1101 lines · 26.1 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0+/* * Author: Justin Iurman (justin.iurman@uliege.be) * * IOAM tester for IPv6, see ioam6.sh for details on each test case. */#include <arpa/inet.h>#include <errno.h>#include <limits.h>#include <linux/const.h>#include <linux/if_ether.h>#include <linux/ioam6.h>#include <linux/ipv6.h>#include <stdbool.h>#include <stdlib.h>#include <string.h>#include <unistd.h> struct ioam_config {	__u32 id;	__u64 wide;	__u16 ingr_id;	__u16 egr_id;	__u32 ingr_wide;	__u32 egr_wide;	__u32 ns_data;	__u64 ns_wide;	__u32 sc_id;	__u8 hlim;	char *sc_data;}; /* * Be careful if you modify structs below - everything MUST be kept synchronized * with configurations inside ioam6.sh and always reflect the same. */ static struct ioam_config node1 = {	.id = 1,	.wide = 11111111,	.ingr_id = 0xffff, /* default value */	.egr_id = 101,	.ingr_wide = 0xffffffff, /* default value */	.egr_wide = 101101,	.ns_data = 0xdeadbeef,	.ns_wide = 0xcafec0caf00dc0de,	.sc_id = 777,	.sc_data = "something that will be 4n-aligned",	.hlim = 64,}; static struct ioam_config node2 = {	.id = 2,	.wide = 22222222,	.ingr_id = 201,	.egr_id = 202,	.ingr_wide = 201201,	.egr_wide = 202202,	.ns_data = 0xffffffff, /* default value */	.ns_wide = 0xffffffffffffffff, /* default value */	.sc_id = 0xffffff, /* default value */	.sc_data = NULL,	.hlim = 63,}; enum {	/**********	 * OUTPUT *	 **********/	__TEST_OUT_MIN, 	TEST_OUT_UNDEF_NS,	TEST_OUT_NO_ROOM,	TEST_OUT_NO_ROOM_OSS,	TEST_OUT_BIT0,	TEST_OUT_BIT1,	TEST_OUT_BIT2,	TEST_OUT_BIT3,	TEST_OUT_BIT4,	TEST_OUT_BIT5,	TEST_OUT_BIT6,	TEST_OUT_BIT7,	TEST_OUT_BIT8,	TEST_OUT_BIT9,	TEST_OUT_BIT10,	TEST_OUT_BIT11,	TEST_OUT_BIT22,	TEST_OUT_SIZE4,	TEST_OUT_SIZE8,	TEST_OUT_SIZE12,	TEST_OUT_SIZE16,	TEST_OUT_SIZE20,	TEST_OUT_SIZE24,	TEST_OUT_SIZE28,	TEST_OUT_SIZE32,	TEST_OUT_SIZE36,	TEST_OUT_SIZE40,	TEST_OUT_SIZE44,	TEST_OUT_SIZE48,	TEST_OUT_SIZE52,	TEST_OUT_SIZE56,	TEST_OUT_SIZE60,	TEST_OUT_SIZE64,	TEST_OUT_SIZE68,	TEST_OUT_SIZE72,	TEST_OUT_SIZE76,	TEST_OUT_SIZE80,	TEST_OUT_SIZE84,	TEST_OUT_SIZE88,	TEST_OUT_SIZE92,	TEST_OUT_SIZE96,	TEST_OUT_SIZE100,	TEST_OUT_SIZE104,	TEST_OUT_SIZE108,	TEST_OUT_SIZE112,	TEST_OUT_SIZE116,	TEST_OUT_SIZE120,	TEST_OUT_SIZE124,	TEST_OUT_SIZE128,	TEST_OUT_SIZE132,	TEST_OUT_SIZE136,	TEST_OUT_SIZE140,	TEST_OUT_SIZE144,	TEST_OUT_SIZE148,	TEST_OUT_SIZE152,	TEST_OUT_SIZE156,	TEST_OUT_SIZE160,	TEST_OUT_SIZE164,	TEST_OUT_SIZE168,	TEST_OUT_SIZE172,	TEST_OUT_SIZE176,	TEST_OUT_SIZE180,	TEST_OUT_SIZE184,	TEST_OUT_SIZE188,	TEST_OUT_SIZE192,	TEST_OUT_SIZE196,	TEST_OUT_SIZE200,	TEST_OUT_SIZE204,	TEST_OUT_SIZE208,	TEST_OUT_SIZE212,	TEST_OUT_SIZE216,	TEST_OUT_SIZE220,	TEST_OUT_SIZE224,	TEST_OUT_SIZE228,	TEST_OUT_SIZE232,	TEST_OUT_SIZE236,	TEST_OUT_SIZE240,	TEST_OUT_SIZE244,	TEST_OUT_FULL_SUPP_TRACE, 	__TEST_OUT_MAX, 	/*********	 * INPUT *	 *********/	__TEST_IN_MIN, 	TEST_IN_UNDEF_NS,	TEST_IN_NO_ROOM,	TEST_IN_NO_ROOM_OSS,	TEST_IN_DISABLED,	TEST_IN_OFLAG,	TEST_IN_BIT0,	TEST_IN_BIT1,	TEST_IN_BIT2,	TEST_IN_BIT3,	TEST_IN_BIT4,	TEST_IN_BIT5,	TEST_IN_BIT6,	TEST_IN_BIT7,	TEST_IN_BIT8,	TEST_IN_BIT9,	TEST_IN_BIT10,	TEST_IN_BIT11,	TEST_IN_BIT22,	TEST_IN_SIZE4,	TEST_IN_SIZE8,	TEST_IN_SIZE12,	TEST_IN_SIZE16,	TEST_IN_SIZE20,	TEST_IN_SIZE24,	TEST_IN_SIZE28,	TEST_IN_SIZE32,	TEST_IN_SIZE36,	TEST_IN_SIZE40,	TEST_IN_SIZE44,	TEST_IN_SIZE48,	TEST_IN_SIZE52,	TEST_IN_SIZE56,	TEST_IN_SIZE60,	TEST_IN_SIZE64,	TEST_IN_SIZE68,	TEST_IN_SIZE72,	TEST_IN_SIZE76,	TEST_IN_SIZE80,	TEST_IN_SIZE84,	TEST_IN_SIZE88,	TEST_IN_SIZE92,	TEST_IN_SIZE96,	TEST_IN_SIZE100,	TEST_IN_SIZE104,	TEST_IN_SIZE108,	TEST_IN_SIZE112,	TEST_IN_SIZE116,	TEST_IN_SIZE120,	TEST_IN_SIZE124,	TEST_IN_SIZE128,	TEST_IN_SIZE132,	TEST_IN_SIZE136,	TEST_IN_SIZE140,	TEST_IN_SIZE144,	TEST_IN_SIZE148,	TEST_IN_SIZE152,	TEST_IN_SIZE156,	TEST_IN_SIZE160,	TEST_IN_SIZE164,	TEST_IN_SIZE168,	TEST_IN_SIZE172,	TEST_IN_SIZE176,	TEST_IN_SIZE180,	TEST_IN_SIZE184,	TEST_IN_SIZE188,	TEST_IN_SIZE192,	TEST_IN_SIZE196,	TEST_IN_SIZE200,	TEST_IN_SIZE204,	TEST_IN_SIZE208,	TEST_IN_SIZE212,	TEST_IN_SIZE216,	TEST_IN_SIZE220,	TEST_IN_SIZE224,	TEST_IN_SIZE228,	TEST_IN_SIZE232,	TEST_IN_SIZE236,	TEST_IN_SIZE240,	TEST_IN_SIZE244,	TEST_IN_FULL_SUPP_TRACE, 	__TEST_IN_MAX, 	__TEST_MAX,}; static int check_header(int tid, struct ioam6_trace_hdr *trace,			__u32 trace_type, __u8 trace_size, __u16 ioam_ns){	if (__be16_to_cpu(trace->namespace_id) != ioam_ns ||	    __be32_to_cpu(trace->type_be32) != (trace_type << 8))		return 1; 	switch (tid) {	case TEST_OUT_UNDEF_NS:	case TEST_IN_UNDEF_NS:	case TEST_IN_DISABLED:		return trace->overflow == 1 ||		       trace->nodelen != 1 ||		       trace->remlen != 1; 	case TEST_OUT_NO_ROOM:	case TEST_IN_NO_ROOM:	case TEST_IN_OFLAG:		return trace->overflow == 0 ||		       trace->nodelen != 2 ||		       trace->remlen != 1; 	case TEST_OUT_NO_ROOM_OSS:		return trace->overflow == 0 ||		       trace->nodelen != 0 ||		       trace->remlen != 1; 	case TEST_IN_NO_ROOM_OSS:	case TEST_OUT_BIT22:	case TEST_IN_BIT22:		return trace->overflow == 1 ||		       trace->nodelen != 0 ||		       trace->remlen != 0; 	case TEST_OUT_BIT0:	case TEST_IN_BIT0:	case TEST_OUT_BIT1:	case TEST_IN_BIT1:	case TEST_OUT_BIT2:	case TEST_IN_BIT2:	case TEST_OUT_BIT3:	case TEST_IN_BIT3:	case TEST_OUT_BIT4:	case TEST_IN_BIT4:	case TEST_OUT_BIT5:	case TEST_IN_BIT5:	case TEST_OUT_BIT6:	case TEST_IN_BIT6:	case TEST_OUT_BIT7:	case TEST_IN_BIT7:	case TEST_OUT_BIT11:	case TEST_IN_BIT11:		return trace->overflow == 1 ||		       trace->nodelen != 1 ||		       trace->remlen != 0; 	case TEST_OUT_BIT8:	case TEST_IN_BIT8:	case TEST_OUT_BIT9:	case TEST_IN_BIT9:	case TEST_OUT_BIT10:	case TEST_IN_BIT10:		return trace->overflow == 1 ||		       trace->nodelen != 2 ||		       trace->remlen != 0; 	case TEST_OUT_SIZE4:	case TEST_OUT_SIZE8:	case TEST_OUT_SIZE12:	case TEST_OUT_SIZE16:	case TEST_OUT_SIZE20:	case TEST_OUT_SIZE24:	case TEST_OUT_SIZE28:	case TEST_OUT_SIZE32:	case TEST_OUT_SIZE36:	case TEST_OUT_SIZE40:	case TEST_OUT_SIZE44:	case TEST_OUT_SIZE48:	case TEST_OUT_SIZE52:	case TEST_OUT_SIZE56:	case TEST_OUT_SIZE60:	case TEST_OUT_SIZE64:	case TEST_OUT_SIZE68:	case TEST_OUT_SIZE72:	case TEST_OUT_SIZE76:	case TEST_OUT_SIZE80:	case TEST_OUT_SIZE84:	case TEST_OUT_SIZE88:	case TEST_OUT_SIZE92:	case TEST_OUT_SIZE96:	case TEST_OUT_SIZE100:	case TEST_OUT_SIZE104:	case TEST_OUT_SIZE108:	case TEST_OUT_SIZE112:	case TEST_OUT_SIZE116:	case TEST_OUT_SIZE120:	case TEST_OUT_SIZE124:	case TEST_OUT_SIZE128:	case TEST_OUT_SIZE132:	case TEST_OUT_SIZE136:	case TEST_OUT_SIZE140:	case TEST_OUT_SIZE144:	case TEST_OUT_SIZE148:	case TEST_OUT_SIZE152:	case TEST_OUT_SIZE156:	case TEST_OUT_SIZE160:	case TEST_OUT_SIZE164:	case TEST_OUT_SIZE168:	case TEST_OUT_SIZE172:	case TEST_OUT_SIZE176:	case TEST_OUT_SIZE180:	case TEST_OUT_SIZE184:	case TEST_OUT_SIZE188:	case TEST_OUT_SIZE192:	case TEST_OUT_SIZE196:	case TEST_OUT_SIZE200:	case TEST_OUT_SIZE204:	case TEST_OUT_SIZE208:	case TEST_OUT_SIZE212:	case TEST_OUT_SIZE216:	case TEST_OUT_SIZE220:	case TEST_OUT_SIZE224:	case TEST_OUT_SIZE228:	case TEST_OUT_SIZE232:	case TEST_OUT_SIZE236:	case TEST_OUT_SIZE240:	case TEST_OUT_SIZE244:		return trace->overflow == 1 ||		       trace->nodelen != 1 ||		       trace->remlen != trace_size / 4; 	case TEST_IN_SIZE4:	case TEST_IN_SIZE8:	case TEST_IN_SIZE12:	case TEST_IN_SIZE16:	case TEST_IN_SIZE20:	case TEST_IN_SIZE24:	case TEST_IN_SIZE28:	case TEST_IN_SIZE32:	case TEST_IN_SIZE36:	case TEST_IN_SIZE40:	case TEST_IN_SIZE44:	case TEST_IN_SIZE48:	case TEST_IN_SIZE52:	case TEST_IN_SIZE56:	case TEST_IN_SIZE60:	case TEST_IN_SIZE64:	case TEST_IN_SIZE68:	case TEST_IN_SIZE72:	case TEST_IN_SIZE76:	case TEST_IN_SIZE80:	case TEST_IN_SIZE84:	case TEST_IN_SIZE88:	case TEST_IN_SIZE92:	case TEST_IN_SIZE96:	case TEST_IN_SIZE100:	case TEST_IN_SIZE104:	case TEST_IN_SIZE108:	case TEST_IN_SIZE112:	case TEST_IN_SIZE116:	case TEST_IN_SIZE120:	case TEST_IN_SIZE124:	case TEST_IN_SIZE128:	case TEST_IN_SIZE132:	case TEST_IN_SIZE136:	case TEST_IN_SIZE140:	case TEST_IN_SIZE144:	case TEST_IN_SIZE148:	case TEST_IN_SIZE152:	case TEST_IN_SIZE156:	case TEST_IN_SIZE160:	case TEST_IN_SIZE164:	case TEST_IN_SIZE168:	case TEST_IN_SIZE172:	case TEST_IN_SIZE176:	case TEST_IN_SIZE180:	case TEST_IN_SIZE184:	case TEST_IN_SIZE188:	case TEST_IN_SIZE192:	case TEST_IN_SIZE196:	case TEST_IN_SIZE200:	case TEST_IN_SIZE204:	case TEST_IN_SIZE208:	case TEST_IN_SIZE212:	case TEST_IN_SIZE216:	case TEST_IN_SIZE220:	case TEST_IN_SIZE224:	case TEST_IN_SIZE228:	case TEST_IN_SIZE232:	case TEST_IN_SIZE236:	case TEST_IN_SIZE240:	case TEST_IN_SIZE244:		return trace->overflow == 1 ||		       trace->nodelen != 1 ||		       trace->remlen != (trace_size / 4) - trace->nodelen; 	case TEST_OUT_FULL_SUPP_TRACE:	case TEST_IN_FULL_SUPP_TRACE:		return trace->overflow == 1 ||		       trace->nodelen != 15 ||		       trace->remlen != 0; 	default:		break;	} 	return 1;} static int check_data(struct ioam6_trace_hdr *trace, __u8 trace_size,		      const struct ioam_config cnf, bool is_output){	unsigned int len, i;	__u8 aligned;	__u64 raw64;	__u32 raw32;	__u8 *p; 	if (trace->type.bit12 | trace->type.bit13 | trace->type.bit14 |	    trace->type.bit15 | trace->type.bit16 | trace->type.bit17 |	    trace->type.bit18 | trace->type.bit19 | trace->type.bit20 |	    trace->type.bit21 | trace->type.bit23)		return 1; 	for (i = 0; i < trace->remlen * 4; i++) {		if (trace->data[i] != 0)			return 1;	} 	if (trace->remlen * 4 == trace_size)		return 0; 	p = trace->data + trace->remlen * 4; 	if (trace->type.bit0) {		raw32 = __be32_to_cpu(*((__u32 *)p));		if (cnf.hlim != (raw32 >> 24) || cnf.id != (raw32 & 0xffffff))			return 1;		p += sizeof(__u32);	} 	if (trace->type.bit1) {		raw32 = __be32_to_cpu(*((__u32 *)p));		if (cnf.ingr_id != (raw32 >> 16) ||		    cnf.egr_id != (raw32 & 0xffff))			return 1;		p += sizeof(__u32);	} 	if (trace->type.bit2) {		raw32 = __be32_to_cpu(*((__u32 *)p));		if ((is_output && raw32 != 0xffffffff) ||		    (!is_output && (raw32 == 0 || raw32 == 0xffffffff)))			return 1;		p += sizeof(__u32);	} 

Lines 1–500 of 1101.