Home | History | Annotate | Line # | Download | only in libnpftest
npf_table_test.c revision 1.9.14.1
      1       1.1     rmind /*
      2  1.9.14.1  christos  * NPF tableset tests.
      3       1.1     rmind  *
      4       1.1     rmind  * Public Domain.
      5       1.1     rmind  */
      6       1.1     rmind 
      7       1.9  christos #ifdef _KERNEL
      8       1.1     rmind #include <sys/types.h>
      9  1.9.14.1  christos #include <sys/kmem.h>
     10       1.9  christos #endif
     11       1.9  christos 
     12       1.9  christos #ifdef __linux__
     13       1.9  christos #include <endian.h>
     14       1.9  christos #else
     15       1.9  christos #include <sys/endian.h>
     16       1.9  christos #endif
     17       1.1     rmind 
     18       1.1     rmind #include "npf_impl.h"
     19       1.1     rmind #include "npf_test.h"
     20       1.1     rmind 
     21       1.1     rmind static const char *ip_list[] = {
     22       1.1     rmind 	"192.168.1.1",
     23       1.1     rmind 	"10.0.0.1",
     24       1.1     rmind 	"192.168.2.1",
     25       1.1     rmind 	"10.1.0.1",
     26       1.1     rmind 	"192.168.100.253",
     27       1.1     rmind 	"10.0.5.1",
     28       1.1     rmind 	"192.168.128.127",
     29       1.1     rmind 	"10.0.0.2",
     30       1.1     rmind };
     31       1.1     rmind 
     32  1.9.14.1  christos static const uint8_t ip6_list[][16] = {
     33       1.5     rmind 	{
     34  1.9.14.1  christos 		0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     35  1.9.14.1  christos 		0x02, 0xa0, 0xc0, 0xff, 0xfe, 0x10, 0x12, 0x34
     36       1.5     rmind 	},
     37       1.5     rmind 	{
     38  1.9.14.1  christos 		0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     39  1.9.14.1  christos 		0x02, 0xa0, 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00,
     40       1.5     rmind 	},
     41       1.5     rmind 	{
     42  1.9.14.1  christos 		0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     43  1.9.14.1  christos 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     44       1.5     rmind 	},
     45       1.5     rmind 	{
     46  1.9.14.1  christos 		0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     47  1.9.14.1  christos 		0x02, 0xa0, 0xc0, 0xff, 0xfe, 0x10, 0x12, 0x30
     48       1.5     rmind 	}
     49       1.4     rmind };
     50       1.4     rmind 
     51  1.9.14.1  christos #define	CHECK_TRUE(x)	\
     52  1.9.14.1  christos     if (!(x)) { printf("FAIL: %s line %d\n", __func__, __LINE__); return 0; }
     53  1.9.14.1  christos 
     54  1.9.14.1  christos #define	IPSET_TID		0
     55  1.9.14.1  christos #define	IPSET_NAME		"ipset-table"
     56  1.9.14.1  christos 
     57  1.9.14.1  christos #define	LPM_TID			1
     58  1.9.14.1  christos #define	LPM_NAME		"lpm-table"
     59  1.9.14.1  christos 
     60  1.9.14.1  christos #define	CDB_TID			2
     61  1.9.14.1  christos #define	CDB_NAME		"cdb-table"
     62  1.9.14.1  christos 
     63  1.9.14.1  christos #define	IFADDR_TID		3
     64  1.9.14.1  christos #define	IFADDR_NAME		".ifaddr-eth0"
     65  1.9.14.1  christos 
     66  1.9.14.1  christos ///////////////////////////////////////////////////////////////////////////
     67  1.9.14.1  christos 
     68  1.9.14.1  christos static bool
     69  1.9.14.1  christos check_ip4(const npf_addr_t *addr, const char *ipstr)
     70  1.9.14.1  christos {
     71  1.9.14.1  christos 	npf_addr_t addr_storage, *test_addr = &addr_storage;
     72  1.9.14.1  christos 	const int alen = sizeof(struct in_addr);
     73  1.9.14.1  christos 	test_addr->word32[0] = inet_addr(ipstr);
     74  1.9.14.1  christos 	return memcmp(addr, test_addr, alen) == 0;
     75  1.9.14.1  christos }
     76  1.9.14.1  christos 
     77  1.9.14.1  christos static bool
     78  1.9.14.1  christos ip4list_insert_lookup(npf_table_t *t, unsigned i)
     79  1.9.14.1  christos {
     80  1.9.14.1  christos 	npf_addr_t addr_storage, *addr = &addr_storage;
     81  1.9.14.1  christos 	const int alen = sizeof(struct in_addr);
     82  1.9.14.1  christos 	int error;
     83       1.9  christos 
     84  1.9.14.1  christos 	addr->word32[0] = inet_addr(ip_list[i]);
     85  1.9.14.1  christos 	error = npf_table_insert(t, alen, addr, NPF_NO_NETMASK);
     86  1.9.14.1  christos 	CHECK_TRUE(error == 0);
     87  1.9.14.1  christos 	error = npf_table_lookup(t, alen, addr);
     88  1.9.14.1  christos 	CHECK_TRUE(error == 0);
     89  1.9.14.1  christos 	return true;
     90  1.9.14.1  christos }
     91       1.1     rmind 
     92       1.6     rmind static bool
     93  1.9.14.1  christos fill_with_ip4(npf_tableset_t *tblset)
     94       1.6     rmind {
     95  1.9.14.1  christos 	npf_addr_t addr_storage, *addr = &addr_storage;
     96       1.6     rmind 	const int alen = sizeof(struct in_addr);
     97       1.6     rmind 	const int nm = NPF_NO_NETMASK;
     98       1.6     rmind 
     99       1.6     rmind 	for (unsigned i = 0; i < __arraycount(ip_list); i++) {
    100       1.7     rmind 		npf_table_t *t;
    101       1.6     rmind 		int error;
    102       1.6     rmind 
    103       1.9  christos 		addr->word32[0] = inet_addr(ip_list[i]);
    104       1.6     rmind 
    105  1.9.14.1  christos 		t = npf_tableset_getbyname(tblset, IPSET_NAME);
    106       1.7     rmind 		error = npf_table_insert(t, alen, addr, nm);
    107  1.9.14.1  christos 		CHECK_TRUE(error == 0);
    108       1.7     rmind 		error = npf_table_insert(t, alen, addr, nm);
    109  1.9.14.1  christos 		CHECK_TRUE(error != 0); // duplicate
    110       1.6     rmind 
    111  1.9.14.1  christos 		t = npf_tableset_getbyname(tblset, LPM_NAME);
    112       1.7     rmind 		error = npf_table_insert(t, alen, addr, nm);
    113  1.9.14.1  christos 		CHECK_TRUE(error == 0);
    114       1.7     rmind 		error = npf_table_insert(t, alen, addr, nm);
    115  1.9.14.1  christos 		CHECK_TRUE(error != 0); // duplicate
    116       1.6     rmind 	}
    117  1.9.14.1  christos 	return true;
    118       1.6     rmind }
    119       1.6     rmind 
    120  1.9.14.1  christos static bool
    121  1.9.14.1  christos verify_ip4(npf_tableset_t *tblset)
    122       1.1     rmind {
    123       1.1     rmind 	npf_addr_t addr_storage, *addr = &addr_storage;
    124  1.9.14.1  christos 	const size_t alen = sizeof(struct in_addr);
    125       1.4     rmind 	const int nm = NPF_NO_NETMASK;
    126  1.9.14.1  christos 	npf_table_t *t;
    127  1.9.14.1  christos 	int error;
    128  1.9.14.1  christos 
    129  1.9.14.1  christos 	/* Attempt to add duplicates - should fail. */
    130  1.9.14.1  christos 	addr->word32[0] = inet_addr(ip_list[0]);
    131  1.9.14.1  christos 
    132  1.9.14.1  christos 	t = npf_tableset_getbyname(tblset, IPSET_NAME);
    133  1.9.14.1  christos 	error = npf_table_insert(t, alen, addr, nm);
    134  1.9.14.1  christos 	CHECK_TRUE(error != 0);
    135  1.9.14.1  christos 
    136  1.9.14.1  christos 	t = npf_tableset_getbyname(tblset, LPM_NAME);
    137  1.9.14.1  christos 	error = npf_table_insert(t, alen, addr, nm);
    138  1.9.14.1  christos 	CHECK_TRUE(error != 0);
    139  1.9.14.1  christos 
    140  1.9.14.1  christos 	/* Match (validate) each IP entry. */
    141  1.9.14.1  christos 	for (unsigned i = 0; i < __arraycount(ip_list); i++) {
    142  1.9.14.1  christos 		addr->word32[0] = inet_addr(ip_list[i]);
    143  1.9.14.1  christos 
    144  1.9.14.1  christos 		t = npf_tableset_getbyname(tblset, IPSET_NAME);
    145  1.9.14.1  christos 		error = npf_table_lookup(t, alen, addr);
    146  1.9.14.1  christos 		CHECK_TRUE(error == 0);
    147  1.9.14.1  christos 
    148  1.9.14.1  christos 		t = npf_tableset_getbyname(tblset, LPM_NAME);
    149  1.9.14.1  christos 		error = npf_table_lookup(t, alen, addr);
    150  1.9.14.1  christos 		CHECK_TRUE(error == 0);
    151  1.9.14.1  christos 	}
    152  1.9.14.1  christos 	return true;
    153  1.9.14.1  christos }
    154  1.9.14.1  christos 
    155  1.9.14.1  christos static bool
    156  1.9.14.1  christos clear_ip4(npf_tableset_t *tblset)
    157  1.9.14.1  christos {
    158  1.9.14.1  christos 	npf_addr_t addr_storage, *addr = &addr_storage;
    159  1.9.14.1  christos 	const int alen = sizeof(struct in_addr);
    160  1.9.14.1  christos 	const int nm = NPF_NO_NETMASK;
    161  1.9.14.1  christos 
    162  1.9.14.1  christos 	for (unsigned i = 0; i < __arraycount(ip_list); i++) {
    163  1.9.14.1  christos 		npf_table_t *t;
    164  1.9.14.1  christos 		int error;
    165  1.9.14.1  christos 
    166  1.9.14.1  christos 		addr->word32[0] = inet_addr(ip_list[i]);
    167  1.9.14.1  christos 
    168  1.9.14.1  christos 		t = npf_tableset_getbyname(tblset, IPSET_NAME);
    169  1.9.14.1  christos 		error = npf_table_remove(t, alen, addr, nm);
    170  1.9.14.1  christos 		CHECK_TRUE(error == 0);
    171  1.9.14.1  christos 
    172  1.9.14.1  christos 		error = npf_table_remove(t, alen, addr, nm);
    173  1.9.14.1  christos 		CHECK_TRUE(error != 0);
    174  1.9.14.1  christos 
    175  1.9.14.1  christos 		t = npf_tableset_getbyname(tblset, LPM_NAME);
    176  1.9.14.1  christos 		error = npf_table_remove(t, alen, addr, nm);
    177  1.9.14.1  christos 		CHECK_TRUE(error == 0);
    178  1.9.14.1  christos 
    179  1.9.14.1  christos 		error = npf_table_remove(t, alen, addr, nm);
    180  1.9.14.1  christos 		CHECK_TRUE(error != 0);
    181  1.9.14.1  christos 	}
    182  1.9.14.1  christos 	return true;
    183  1.9.14.1  christos }
    184  1.9.14.1  christos 
    185  1.9.14.1  christos ///////////////////////////////////////////////////////////////////////////
    186  1.9.14.1  christos 
    187  1.9.14.1  christos static bool
    188  1.9.14.1  christos test_basic(npf_tableset_t *tblset)
    189  1.9.14.1  christos {
    190  1.9.14.1  christos 	npf_addr_t addr_storage, *addr = &addr_storage;
    191  1.9.14.1  christos 	const int alen = sizeof(struct in_addr);
    192  1.9.14.1  christos 	npf_table_t *t;
    193  1.9.14.1  christos 	int error;
    194  1.9.14.1  christos 
    195  1.9.14.1  christos 	/* Basic IP set. */
    196  1.9.14.1  christos 	t = npf_table_create(IPSET_NAME, IPSET_TID, NPF_TABLE_IPSET, NULL, 0);
    197  1.9.14.1  christos 	CHECK_TRUE(t != NULL);
    198  1.9.14.1  christos 	error = npf_tableset_insert(tblset, t);
    199  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    200       1.1     rmind 
    201       1.1     rmind 	/* Check for double-insert. */
    202  1.9.14.1  christos 	error = npf_tableset_insert(tblset, t);
    203  1.9.14.1  christos 	CHECK_TRUE(error != 0);
    204       1.1     rmind 
    205  1.9.14.1  christos 	/* Longest-prefix match (LPM). */
    206  1.9.14.1  christos 	t = npf_table_create(LPM_NAME, LPM_TID, NPF_TABLE_LPM, NULL, 0);
    207  1.9.14.1  christos 	CHECK_TRUE(t != NULL);
    208  1.9.14.1  christos 	error = npf_tableset_insert(tblset, t);
    209  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    210  1.9.14.1  christos 
    211  1.9.14.1  christos 	/* Table for interface addresses. */
    212  1.9.14.1  christos 	t = npf_table_create(IFADDR_NAME, IFADDR_TID, NPF_TABLE_IFADDR, NULL, 0);
    213  1.9.14.1  christos 	CHECK_TRUE(t != NULL);
    214  1.9.14.1  christos 	error = npf_tableset_insert(tblset, t);
    215  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    216       1.8     rmind 
    217  1.9.14.1  christos 	/*
    218  1.9.14.1  christos 	 * Attempt to match some non-existing entries - should fail.
    219  1.9.14.1  christos 	 */
    220       1.9  christos 	addr->word32[0] = inet_addr(ip_list[0]);
    221       1.2     rmind 
    222  1.9.14.1  christos 	t = npf_tableset_getbyname(tblset, IPSET_NAME);
    223       1.7     rmind 	error = npf_table_lookup(t, alen, addr);
    224  1.9.14.1  christos 	CHECK_TRUE(error != 0);
    225       1.2     rmind 
    226  1.9.14.1  christos 	t = npf_tableset_getbyname(tblset, LPM_NAME);
    227       1.7     rmind 	error = npf_table_lookup(t, alen, addr);
    228  1.9.14.1  christos 	CHECK_TRUE(error != 0);
    229       1.2     rmind 
    230  1.9.14.1  christos 	return true;
    231  1.9.14.1  christos }
    232       1.1     rmind 
    233  1.9.14.1  christos static bool
    234  1.9.14.1  christos test_nocopy(npf_tableset_t *tblset)
    235  1.9.14.1  christos {
    236  1.9.14.1  christos 	const int alen = sizeof(struct in_addr);
    237  1.9.14.1  christos 	const char *tables[] = { IPSET_NAME, LPM_NAME, IFADDR_NAME };
    238  1.9.14.1  christos 	npf_addr_t *addr, lookup_addr;
    239       1.1     rmind 
    240  1.9.14.1  christos 	for (unsigned i = 0; i < __arraycount(tables); i++) {
    241  1.9.14.1  christos 		npf_table_t *t;
    242  1.9.14.1  christos 		int error;
    243       1.1     rmind 
    244  1.9.14.1  christos 		addr = kmem_zalloc(sizeof(npf_addr_t), KM_SLEEP);
    245  1.9.14.1  christos 		assert(addr != NULL);
    246  1.9.14.1  christos 		addr->word32[0] = inet_addr("172.16.90.10");
    247       1.1     rmind 
    248  1.9.14.1  christos 		t = npf_tableset_getbyname(tblset, tables[i]);
    249  1.9.14.1  christos 		(void)npf_table_flush(t);
    250       1.1     rmind 
    251  1.9.14.1  christos 		error = npf_table_insert(t, alen, addr, NPF_NO_NETMASK);
    252  1.9.14.1  christos 		CHECK_TRUE(error == 0);
    253       1.1     rmind 
    254  1.9.14.1  christos 		memcpy(&lookup_addr, addr, alen);
    255  1.9.14.1  christos 		memset(addr, 0xa5, alen); // explicit memset
    256  1.9.14.1  christos 
    257  1.9.14.1  christos 		error = npf_table_lookup(t, alen, &lookup_addr);
    258  1.9.14.1  christos 		CHECK_TRUE(error == 0);
    259  1.9.14.1  christos 
    260  1.9.14.1  christos 		CHECK_TRUE(*(volatile unsigned char *)addr == 0xa5);
    261  1.9.14.1  christos 		kmem_free(addr, sizeof(npf_addr_t));
    262       1.1     rmind 	}
    263  1.9.14.1  christos 	return true;
    264  1.9.14.1  christos }
    265  1.9.14.1  christos 
    266  1.9.14.1  christos static bool
    267  1.9.14.1  christos test_ip6(npf_tableset_t *tblset)
    268  1.9.14.1  christos {
    269  1.9.14.1  christos 	npf_addr_t addr_storage, *addr = &addr_storage;
    270  1.9.14.1  christos 	const size_t alen = sizeof(struct in6_addr);
    271  1.9.14.1  christos 	const int nm = NPF_NO_NETMASK;
    272  1.9.14.1  christos 	npf_table_t *t;
    273  1.9.14.1  christos 	int error;
    274       1.1     rmind 
    275       1.4     rmind 	/* IPv6 addresses. */
    276       1.4     rmind 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
    277       1.4     rmind 
    278  1.9.14.1  christos 	t = npf_tableset_getbyname(tblset, IPSET_NAME);
    279       1.7     rmind 	error = npf_table_insert(t, alen, addr, nm);
    280  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    281       1.7     rmind 	error = npf_table_lookup(t, alen, addr);
    282  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    283       1.7     rmind 	error = npf_table_remove(t, alen, addr, nm);
    284  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    285       1.4     rmind 
    286  1.9.14.1  christos 	t = npf_tableset_getbyname(tblset, LPM_NAME);
    287       1.7     rmind 	error = npf_table_insert(t, alen, addr, nm);
    288  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    289       1.7     rmind 	error = npf_table_lookup(t, alen, addr);
    290  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    291       1.7     rmind 	error = npf_table_remove(t, alen, addr, nm);
    292  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    293  1.9.14.1  christos 
    294  1.9.14.1  christos 	return true;
    295  1.9.14.1  christos }
    296  1.9.14.1  christos 
    297  1.9.14.1  christos static bool
    298  1.9.14.1  christos test_lpm_masks4(npf_tableset_t *tblset)
    299  1.9.14.1  christos {
    300  1.9.14.1  christos 	npf_table_t *t = npf_tableset_getbyname(tblset, LPM_NAME);
    301  1.9.14.1  christos 	npf_addr_t addr_storage, *addr = &addr_storage;
    302  1.9.14.1  christos 	const size_t alen = sizeof(struct in_addr);
    303  1.9.14.1  christos 	int error;
    304  1.9.14.1  christos 
    305  1.9.14.1  christos 	addr->word32[0] = inet_addr("172.16.90.0");
    306  1.9.14.1  christos 	error = npf_table_insert(t, alen, addr, 25);
    307  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    308  1.9.14.1  christos 
    309  1.9.14.1  christos 	addr->word32[0] = inet_addr("172.16.90.126");
    310  1.9.14.1  christos 	error = npf_table_lookup(t, alen, addr);
    311  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    312  1.9.14.1  christos 
    313  1.9.14.1  christos 	addr->word32[0] = inet_addr("172.16.90.128");
    314  1.9.14.1  christos 	error = npf_table_lookup(t, alen, addr);
    315  1.9.14.1  christos 	CHECK_TRUE(error != 0);
    316  1.9.14.1  christos 
    317  1.9.14.1  christos 	return true;
    318  1.9.14.1  christos }
    319  1.9.14.1  christos 
    320  1.9.14.1  christos static bool
    321  1.9.14.1  christos test_lpm_masks6(npf_tableset_t *tblset)
    322  1.9.14.1  christos {
    323  1.9.14.1  christos 	npf_table_t *t = npf_tableset_getbyname(tblset, LPM_NAME);
    324  1.9.14.1  christos 	npf_addr_t addr_storage, *addr = &addr_storage;
    325  1.9.14.1  christos 	const size_t alen = sizeof(struct in6_addr);
    326  1.9.14.1  christos 	int error;
    327       1.4     rmind 
    328       1.4     rmind 	/*
    329  1.9.14.1  christos 	 * 96
    330       1.4     rmind 	 */
    331       1.4     rmind 	memcpy(addr, ip6_list[1], sizeof(ip6_list[1]));
    332       1.7     rmind 	error = npf_table_insert(t, alen, addr, 96);
    333  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    334       1.4     rmind 
    335       1.4     rmind 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
    336       1.7     rmind 	error = npf_table_lookup(t, alen, addr);
    337  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    338       1.4     rmind 
    339       1.4     rmind 	memcpy(addr, ip6_list[1], sizeof(ip6_list[1]));
    340       1.7     rmind 	error = npf_table_remove(t, alen, addr, 96);
    341  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    342       1.4     rmind 
    343  1.9.14.1  christos 	/*
    344  1.9.14.1  christos 	 * 32
    345  1.9.14.1  christos 	 */
    346       1.4     rmind 	memcpy(addr, ip6_list[2], sizeof(ip6_list[2]));
    347       1.7     rmind 	error = npf_table_insert(t, alen, addr, 32);
    348  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    349       1.4     rmind 
    350       1.4     rmind 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
    351       1.7     rmind 	error = npf_table_lookup(t, alen, addr);
    352  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    353       1.4     rmind 
    354       1.4     rmind 	memcpy(addr, ip6_list[2], sizeof(ip6_list[2]));
    355       1.7     rmind 	error = npf_table_remove(t, alen, addr, 32);
    356  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    357       1.4     rmind 
    358  1.9.14.1  christos 	/*
    359  1.9.14.1  christos 	 * 126
    360  1.9.14.1  christos 	 */
    361       1.4     rmind 	memcpy(addr, ip6_list[3], sizeof(ip6_list[3]));
    362       1.7     rmind 	error = npf_table_insert(t, alen, addr, 126);
    363  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    364       1.4     rmind 
    365       1.4     rmind 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
    366       1.7     rmind 	error = npf_table_lookup(t, alen, addr);
    367  1.9.14.1  christos 	CHECK_TRUE(error != 0);
    368       1.4     rmind 
    369       1.4     rmind 	memcpy(addr, ip6_list[3], sizeof(ip6_list[3]));
    370       1.7     rmind 	error = npf_table_remove(t, alen, addr, 126);
    371  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    372       1.4     rmind 
    373  1.9.14.1  christos 	return true;
    374  1.9.14.1  christos }
    375       1.4     rmind 
    376  1.9.14.1  christos static bool
    377  1.9.14.1  christos test_const_table(npf_tableset_t *tblset, void *blob, size_t size)
    378  1.9.14.1  christos {
    379  1.9.14.1  christos 	npf_addr_t addr_storage, *addr = &addr_storage;
    380  1.9.14.1  christos 	const int alen = sizeof(struct in_addr);
    381  1.9.14.1  christos 	npf_table_t *t;
    382  1.9.14.1  christos 	int error;
    383       1.1     rmind 
    384  1.9.14.1  christos 	t = npf_table_create(CDB_NAME, CDB_TID, NPF_TABLE_CONST, blob, size);
    385  1.9.14.1  christos 	CHECK_TRUE(t != NULL);
    386       1.1     rmind 
    387  1.9.14.1  christos 	error = npf_tableset_insert(tblset, t);
    388  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    389       1.1     rmind 
    390       1.9  christos 	addr->word32[0] = inet_addr(ip_list[0]);
    391  1.9.14.1  christos 	error = npf_table_lookup(t, alen, addr);
    392  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    393       1.8     rmind 
    394  1.9.14.1  christos 	for (unsigned i = 1; i < __arraycount(ip_list) - 1; i++) {
    395       1.9  christos 		addr->word32[0] = inet_addr(ip_list[i]);
    396  1.9.14.1  christos 		error = npf_table_lookup(t, alen, addr);
    397  1.9.14.1  christos 		CHECK_TRUE(error != 0);
    398       1.8     rmind 	}
    399  1.9.14.1  christos 	return true;
    400  1.9.14.1  christos }
    401       1.8     rmind 
    402  1.9.14.1  christos static bool
    403  1.9.14.1  christos test_ifaddr_table(npf_tableset_t *tblset)
    404  1.9.14.1  christos {
    405  1.9.14.1  christos 	npf_addr_t addr_storage, *addr = &addr_storage;
    406  1.9.14.1  christos 	npf_table_t *t = npf_tableset_getbyname(tblset, IFADDR_NAME);
    407  1.9.14.1  christos 	int error;
    408  1.9.14.1  christos 	bool ok;
    409  1.9.14.1  christos 
    410  1.9.14.1  christos 	/* Two IPv4 addresses. */
    411  1.9.14.1  christos 	ok = ip4list_insert_lookup(t, 0);
    412  1.9.14.1  christos 	CHECK_TRUE(ok);
    413  1.9.14.1  christos 
    414  1.9.14.1  christos 	ok = ip4list_insert_lookup(t, 1);
    415  1.9.14.1  christos 	CHECK_TRUE(ok);
    416  1.9.14.1  christos 
    417  1.9.14.1  christos 	/* And one IPv6 address. */
    418  1.9.14.1  christos 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
    419  1.9.14.1  christos 	error = npf_table_insert(t, sizeof(struct in6_addr), addr, NPF_NO_NETMASK);
    420  1.9.14.1  christos 	CHECK_TRUE(error == 0);
    421       1.1     rmind 
    422  1.9.14.1  christos 	/*
    423  1.9.14.1  christos 	 * Get IPv4 addresses.
    424  1.9.14.1  christos 	 */
    425  1.9.14.1  christos 	addr = npf_table_getsome(t, sizeof(struct in_addr), 0);
    426  1.9.14.1  christos 	ok = check_ip4(addr, "192.168.1.1");
    427  1.9.14.1  christos 	CHECK_TRUE(ok);
    428  1.9.14.1  christos 
    429  1.9.14.1  christos 	addr = npf_table_getsome(t, sizeof(struct in_addr), 1);
    430  1.9.14.1  christos 	ok = check_ip4(addr, "10.0.0.1");
    431  1.9.14.1  christos 	CHECK_TRUE(ok);
    432  1.9.14.1  christos 
    433  1.9.14.1  christos 	addr = npf_table_getsome(t, sizeof(struct in_addr), 2);
    434  1.9.14.1  christos 	ok = check_ip4(addr, "192.168.1.1");
    435  1.9.14.1  christos 	CHECK_TRUE(ok);
    436  1.9.14.1  christos 
    437  1.9.14.1  christos 	return true;
    438  1.9.14.1  christos }
    439  1.9.14.1  christos 
    440  1.9.14.1  christos static void
    441  1.9.14.1  christos test_ipset_gc(npf_tableset_t *tblset)
    442  1.9.14.1  christos {
    443  1.9.14.1  christos 	npf_table_t *t = npf_tableset_getbyname(tblset, IPSET_NAME);
    444  1.9.14.1  christos 	npf_t *npf = npf_getkernctx();
    445  1.9.14.1  christos 
    446  1.9.14.1  christos 	npf_config_enter(npf);
    447  1.9.14.1  christos 	npf_table_gc(npf, t);
    448  1.9.14.1  christos 	npf_table_flush(t);
    449  1.9.14.1  christos 	npf_config_exit(npf);
    450  1.9.14.1  christos }
    451  1.9.14.1  christos 
    452  1.9.14.1  christos bool
    453  1.9.14.1  christos npf_table_test(bool verbose, void *blob, size_t size)
    454  1.9.14.1  christos {
    455  1.9.14.1  christos 	npf_tableset_t *tblset;
    456  1.9.14.1  christos 	bool ok;
    457  1.9.14.1  christos 
    458  1.9.14.1  christos 	(void)verbose;
    459  1.9.14.1  christos 
    460  1.9.14.1  christos 	tblset = npf_tableset_create(4);
    461  1.9.14.1  christos 	CHECK_TRUE(tblset != NULL);
    462  1.9.14.1  christos 
    463  1.9.14.1  christos 	ok = test_basic(tblset);
    464  1.9.14.1  christos 	CHECK_TRUE(ok);
    465  1.9.14.1  christos 
    466  1.9.14.1  christos 	/*
    467  1.9.14.1  christos 	 * Fill IPSET and LPM tables with IPv4 addresses.
    468  1.9.14.1  christos 	 * Keep them in the table during the other tests.
    469  1.9.14.1  christos 	 */
    470  1.9.14.1  christos 	ok = fill_with_ip4(tblset);
    471  1.9.14.1  christos 	CHECK_TRUE(ok);
    472  1.9.14.1  christos 
    473  1.9.14.1  christos 	ok = verify_ip4(tblset);
    474  1.9.14.1  christos 	CHECK_TRUE(ok);
    475  1.9.14.1  christos 
    476  1.9.14.1  christos 	ok = test_ip6(tblset);
    477  1.9.14.1  christos 	CHECK_TRUE(ok);
    478  1.9.14.1  christos 
    479  1.9.14.1  christos 	ok = test_lpm_masks4(tblset);
    480  1.9.14.1  christos 	CHECK_TRUE(ok);
    481  1.9.14.1  christos 
    482  1.9.14.1  christos 	ok = test_lpm_masks6(tblset);
    483  1.9.14.1  christos 	CHECK_TRUE(ok);
    484  1.9.14.1  christos 
    485  1.9.14.1  christos 	ok = test_const_table(tblset, blob, size);
    486  1.9.14.1  christos 	CHECK_TRUE(ok);
    487  1.9.14.1  christos 
    488  1.9.14.1  christos 	ok = test_ifaddr_table(tblset);
    489  1.9.14.1  christos 	CHECK_TRUE(ok);
    490  1.9.14.1  christos 
    491  1.9.14.1  christos 	/*
    492  1.9.14.1  christos 	 * Remove the above IPv4 addresses -- they must have been untouched.
    493  1.9.14.1  christos 	 */
    494  1.9.14.1  christos 	ok = clear_ip4(tblset);
    495  1.9.14.1  christos 	CHECK_TRUE(ok);
    496  1.9.14.1  christos 
    497  1.9.14.1  christos 	ok = test_nocopy(tblset);
    498  1.9.14.1  christos 	CHECK_TRUE(ok);
    499  1.9.14.1  christos 
    500  1.9.14.1  christos 	test_ipset_gc(tblset);
    501  1.9.14.1  christos 
    502  1.9.14.1  christos 	npf_tableset_destroy(tblset);
    503  1.9.14.1  christos 	return true;
    504       1.1     rmind }
    505