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