Home | History | Annotate | Line # | Download | only in libnpftest
npf_l2rule_test.c revision 1.1
      1  1.1  joe /*
      2  1.1  joe  * NPF layer 2 ruleset tests.
      3  1.1  joe  *
      4  1.1  joe  * Public Domain.
      5  1.1  joe  */
      6  1.1  joe 
      7  1.1  joe #ifdef _KERNEL
      8  1.1  joe #include <sys/types.h>
      9  1.1  joe #endif
     10  1.1  joe 
     11  1.1  joe #include "npf_impl.h"
     12  1.1  joe #include "npf_test.h"
     13  1.1  joe 
     14  1.1  joe #define	RESULT_PASS	0
     15  1.1  joe #define	RESULT_BLOCK	ENETUNREACH
     16  1.1  joe 
     17  1.1  joe static const struct test_case {
     18  1.1  joe 	const char *	src;
     19  1.1  joe 	const char *	dst;
     20  1.1  joe 	uint16_t		etype;
     21  1.1  joe 	const char *	ifname;
     22  1.1  joe 	int		di;
     23  1.1  joe 	int		ret;
     24  1.1  joe } test_cases[] = {
     25  1.1  joe 	{
     26  1.1  joe 		/* pass ether in final from $mac1 to $mac2 type $E_IPv6 */
     27  1.1  joe 		.src = "00:00:5E:00:53:00",	.dst = "00:00:5E:00:53:01",
     28  1.1  joe 		.ifname = IFNAME_INT,		.etype = htons(ETHERTYPE_IPV6),
     29  1.1  joe 		.di = PFIL_IN,			.ret = RESULT_PASS
     30  1.1  joe 	},
     31  1.1  joe 	{
     32  1.1  joe 		/* block ether in final from $mac2 */
     33  1.1  joe 		.src = "00:00:5E:00:53:01",	.dst = "00:00:5E:00:53:02",
     34  1.1  joe 		.ifname = IFNAME_INT,		.etype = htons(ETHERTYPE_IP),
     35  1.1  joe 		.di = PFIL_IN,			.ret = RESULT_BLOCK
     36  1.1  joe 	},
     37  1.1  joe 
     38  1.1  joe 		/* pass ether out final to $mac3 $Apple talk */
     39  1.1  joe 	{
     40  1.1  joe 		.src = "00:00:5E:00:53:00",	.dst = "00:00:5E:00:53:02",
     41  1.1  joe 		.ifname = IFNAME_INT,		.etype = htons(ETHERTYPE_ATALK),
     42  1.1  joe 		.di = PFIL_OUT,			.ret = RESULT_PASS
     43  1.1  joe 	},
     44  1.1  joe 	{
     45  1.1  joe 		/* goto default: block all (since direction is not matching ) */
     46  1.1  joe 		.src = "00:00:5E:00:53:00",	.dst = "00:00:5E:00:53:02",
     47  1.1  joe 		.ifname = IFNAME_INT,		.etype = htons(ETHERTYPE_IP),
     48  1.1  joe 		.di = PFIL_IN,			.ret = RESULT_BLOCK
     49  1.1  joe 	},
     50  1.1  joe };
     51  1.1  joe 
     52  1.1  joe static int
     53  1.1  joe run_raw_testcase(unsigned i)
     54  1.1  joe {
     55  1.1  joe 	const struct test_case *t = &test_cases[i];
     56  1.1  joe 	npf_t *npf = npf_getkernctx();
     57  1.1  joe 	npf_cache_t *npc;
     58  1.1  joe 	struct mbuf *m;
     59  1.1  joe 	npf_rule_t *rl;
     60  1.1  joe 	int slock, error;
     61  1.1  joe 
     62  1.1  joe 	m = mbuf_get_frame(t->src, t->dst, t->etype);
     63  1.1  joe 	npc = get_cached_pkt(m, t->ifname, NPF_RULE_LAYER_2);
     64  1.1  joe 
     65  1.1  joe 	slock = npf_config_read_enter(npf);
     66  1.1  joe 	rl = npf_ruleset_inspect(npc, npf_config_ruleset(npf), t->di, NPF_RULE_LAYER_2);
     67  1.1  joe 	if (rl) {
     68  1.1  joe 		npf_match_info_t mi;
     69  1.1  joe 		error = npf_rule_conclude(rl, &mi);
     70  1.1  joe 	} else {
     71  1.1  joe 		error = ENOENT;
     72  1.1  joe 	}
     73  1.1  joe 	npf_config_read_exit(npf, slock);
     74  1.1  joe 
     75  1.1  joe 	put_cached_pkt(npc);
     76  1.1  joe 	return error;
     77  1.1  joe }
     78  1.1  joe 
     79  1.1  joe /* for dynamic testing */
     80  1.1  joe static int
     81  1.1  joe run_handler_testcase(unsigned i)
     82  1.1  joe {
     83  1.1  joe 	const struct test_case *t = &test_cases[i];
     84  1.1  joe 	ifnet_t *ifp = npf_test_getif(t->ifname);
     85  1.1  joe 	npf_t *npf = npf_getkernctx();
     86  1.1  joe 	struct mbuf *m;
     87  1.1  joe 	int error;
     88  1.1  joe 
     89  1.1  joe 	m = mbuf_get_frame(t->src, t->dst, t->etype);
     90  1.1  joe 	error = npfk_layer2_handler(npf, &m, ifp, t->di);
     91  1.1  joe 	if (m) {
     92  1.1  joe 		m_freem(m);
     93  1.1  joe 	}
     94  1.1  joe 	return error;
     95  1.1  joe }
     96  1.1  joe 
     97  1.1  joe static npf_rule_t *
     98  1.1  joe npf_blockall_rule(void)
     99  1.1  joe {
    100  1.1  joe 	npf_t *npf = npf_getkernctx();
    101  1.1  joe 	nvlist_t *rule = nvlist_create(0);
    102  1.1  joe 	npf_rule_t *rl;
    103  1.1  joe 
    104  1.1  joe 	nvlist_add_number(rule, "attr",
    105  1.1  joe 		NPF_RULE_IN | NPF_RULE_OUT | NPF_RULE_DYNAMIC | NPF_RULE_LAYER_2);
    106  1.1  joe 	rl = npf_rule_alloc(npf, rule);
    107  1.1  joe 	nvlist_destroy(rule);
    108  1.1  joe 	return rl;
    109  1.1  joe }
    110  1.1  joe 
    111  1.1  joe static bool
    112  1.1  joe test_static(bool verbose)
    113  1.1  joe {
    114  1.1  joe 	for (unsigned i = 0; i < __arraycount(test_cases); i++) {
    115  1.1  joe 		const struct test_case *t = &test_cases[i];
    116  1.1  joe 		int error;
    117  1.1  joe 
    118  1.1  joe 		if (npf_test_getif(t->ifname) == NULL) {
    119  1.1  joe 			printf("Interface %s is not configured.\n", t->ifname);
    120  1.1  joe 			return false;
    121  1.1  joe 		}
    122  1.1  joe 
    123  1.1  joe 		error = run_handler_testcase(i);
    124  1.1  joe 
    125  1.1  joe 		if (verbose) {
    126  1.1  joe 			printf("rule test %d:\texpected %d\n"
    127  1.1  joe 				"\t\t-> returned %d\n",
    128  1.1  joe 				i + 1, t->ret, error);
    129  1.1  joe 		}
    130  1.1  joe 		CHECK_TRUE(error == t->ret);
    131  1.1  joe 	}
    132  1.1  joe 	return true;
    133  1.1  joe }
    134  1.1  joe 
    135  1.1  joe static bool
    136  1.1  joe test_dynamic(void)
    137  1.1  joe {
    138  1.1  joe 	npf_t *npf = npf_getkernctx();
    139  1.1  joe 	npf_ruleset_t *rlset;
    140  1.1  joe 	npf_rule_t *rl;
    141  1.1  joe 	uint64_t id;
    142  1.1  joe 	int error;
    143  1.1  joe 
    144  1.1  joe 	/*
    145  1.1  joe 	* Test dynamic NPF rules.
    146  1.1  joe 	*/
    147  1.1  joe 
    148  1.1  joe 	error = run_raw_testcase(0);
    149  1.1  joe 	CHECK_TRUE(error == RESULT_PASS);
    150  1.1  joe 
    151  1.1  joe 	npf_config_enter(npf);
    152  1.1  joe 	rlset = npf_config_ruleset(npf);
    153  1.1  joe 
    154  1.1  joe 	rl = npf_blockall_rule();
    155  1.1  joe 	error = npf_ruleset_add(rlset, "l2-ruleset", rl);
    156  1.1  joe 	CHECK_TRUE(error == 0);
    157  1.1  joe 
    158  1.1  joe 	error = run_raw_testcase(0);
    159  1.1  joe 	CHECK_TRUE(error == RESULT_BLOCK);
    160  1.1  joe 
    161  1.1  joe 	id = npf_rule_getid(rl);
    162  1.1  joe 	error = npf_ruleset_remove(rlset, "l2-ruleset", id);
    163  1.1  joe 	CHECK_TRUE(error == 0);
    164  1.1  joe 
    165  1.1  joe 	npf_config_exit(npf);
    166  1.1  joe 
    167  1.1  joe 	error = run_raw_testcase(0);
    168  1.1  joe 	CHECK_TRUE(error == RESULT_PASS);
    169  1.1  joe 
    170  1.1  joe 	return true;
    171  1.1  joe }
    172  1.1  joe 
    173  1.1  joe bool
    174  1.1  joe npf_layer2_rule_test(bool verbose)
    175  1.1  joe {
    176  1.1  joe 	bool ok;
    177  1.1  joe 
    178  1.1  joe 	ok = test_static(verbose);
    179  1.1  joe 	CHECK_TRUE(ok);
    180  1.1  joe 
    181  1.1  joe 	ok = test_dynamic();
    182  1.1  joe 	CHECK_TRUE(ok);
    183  1.1  joe 
    184  1.1  joe 	return true;
    185  1.1  joe }
    186