14c074b47SAaron LI /*-
24c074b47SAaron LI * SPDX-License-Identifier: MIT
382c705f0SAaron LI *
482c705f0SAaron LI * Copyright (C) 2015-2021 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
54c074b47SAaron LI * Copyright (c) 2024 Aaron LI <aly@aaronly.me>
64c074b47SAaron LI *
74c074b47SAaron LI * Permission is hereby granted, free of charge, to any person obtaining
84c074b47SAaron LI * a copy of this software and associated documentation files (the
94c074b47SAaron LI * "Software"), to deal in the Software without restriction, including
104c074b47SAaron LI * without limitation the rights to use, copy, modify, merge, publish,
114c074b47SAaron LI * distribute, sublicense, and/or sell copies of the Software, and to
124c074b47SAaron LI * permit persons to whom the Software is furnished to do so, subject
134c074b47SAaron LI * to the following conditions:
144c074b47SAaron LI *
154c074b47SAaron LI * The above copyright notice and this permission notice shall be
164c074b47SAaron LI * included in all copies or substantial portions of the Software.
174c074b47SAaron LI *
184c074b47SAaron LI * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
194c074b47SAaron LI * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
204c074b47SAaron LI * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
214c074b47SAaron LI * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
224c074b47SAaron LI * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
234c074b47SAaron LI * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
244c074b47SAaron LI * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2582c705f0SAaron LI */
2682c705f0SAaron LI
274c074b47SAaron LI static bool
test_aip_init(struct wg_softc * sc)284c074b47SAaron LI test_aip_init(struct wg_softc *sc)
2982c705f0SAaron LI {
304c074b47SAaron LI memset(sc, 0, sizeof(*sc));
314c074b47SAaron LI
324c074b47SAaron LI lockinit(&sc->sc_aip_lock, "aip_lock (test)", 0, 0);
334c074b47SAaron LI
34cf257a5cSAaron LI if (!rn_inithead(&sc->sc_aip4, wg_maskhead,
35cf257a5cSAaron LI offsetof(struct aip_addr, in)))
364c074b47SAaron LI return (false);
37cf257a5cSAaron LI if (!rn_inithead(&sc->sc_aip6, wg_maskhead,
38cf257a5cSAaron LI offsetof(struct aip_addr, in6)))
394c074b47SAaron LI return (false);
404c074b47SAaron LI
414c074b47SAaron LI return (true);
4282c705f0SAaron LI }
4382c705f0SAaron LI
444c074b47SAaron LI static void
test_aip_deinit(struct wg_softc * sc)454c074b47SAaron LI test_aip_deinit(struct wg_softc *sc)
4682c705f0SAaron LI {
474c074b47SAaron LI if (sc->sc_aip4 != NULL) {
48cf257a5cSAaron LI rn_freehead(sc->sc_aip4);
49cf257a5cSAaron LI sc->sc_aip4 = NULL;
5082c705f0SAaron LI }
514c074b47SAaron LI if (sc->sc_aip6 != NULL) {
52cf257a5cSAaron LI rn_freehead(sc->sc_aip6);
53cf257a5cSAaron LI sc->sc_aip6 = NULL;
5482c705f0SAaron LI }
554c074b47SAaron LI
564c074b47SAaron LI lockuninit(&sc->sc_aip_lock);
574c074b47SAaron LI }
584c074b47SAaron LI
594c074b47SAaron LI static struct wg_peer *
test_aip_peer_new(struct wg_softc * sc)604c074b47SAaron LI test_aip_peer_new(struct wg_softc *sc)
614c074b47SAaron LI {
624c074b47SAaron LI struct wg_peer *peer;
634c074b47SAaron LI
644c074b47SAaron LI peer = kmalloc(sizeof(*peer), M_WG, M_NOWAIT | M_ZERO);
654c074b47SAaron LI if (peer == NULL)
664c074b47SAaron LI return (NULL);
674c074b47SAaron LI
684c074b47SAaron LI peer->p_sc = sc;
694c074b47SAaron LI LIST_INIT(&peer->p_aips);
704c074b47SAaron LI peer->p_aips_num = 0;
714c074b47SAaron LI /*
724c074b47SAaron LI * WARNING:
734c074b47SAaron LI * wg_aip_lookup() will reference 'peer->p_remote', so this member
744c074b47SAaron LI * cannot be NULL. Do a hack and just assign itself to it, so as
754c074b47SAaron LI * no need to bother with creating noise_local and noise_remote.
764c074b47SAaron LI * This is kind of dangerous, but probably fine.
774c074b47SAaron LI */
784c074b47SAaron LI peer->p_remote = (struct noise_remote *)peer;
794c074b47SAaron LI
804c074b47SAaron LI return (peer);
8182c705f0SAaron LI }
8282c705f0SAaron LI
8382c705f0SAaron LI #ifdef WG_ALLOWEDIPS_RANDOMIZED_TEST
8482c705f0SAaron LI
8582c705f0SAaron LI struct horrible_allowedips {
8682c705f0SAaron LI LIST_HEAD(, horrible_allowedips_node) head;
8782c705f0SAaron LI };
8882c705f0SAaron LI
8982c705f0SAaron LI struct horrible_allowedips_node {
904c074b47SAaron LI LIST_ENTRY(horrible_allowedips_node) entry;
9182c705f0SAaron LI struct aip_addr ip;
9282c705f0SAaron LI struct aip_addr mask;
9382c705f0SAaron LI uint8_t ip_version;
9482c705f0SAaron LI void *value;
9582c705f0SAaron LI };
9682c705f0SAaron LI
974c074b47SAaron LI static void
horrible_allowedips_init(struct horrible_allowedips * table)984c074b47SAaron LI horrible_allowedips_init(struct horrible_allowedips *table)
9982c705f0SAaron LI {
10082c705f0SAaron LI LIST_INIT(&table->head);
10182c705f0SAaron LI }
10282c705f0SAaron LI
1034c074b47SAaron LI static void
horrible_allowedips_flush(struct horrible_allowedips * table)104*350efd1cSAaron LI horrible_allowedips_flush(struct horrible_allowedips *table)
10582c705f0SAaron LI {
1064c074b47SAaron LI struct horrible_allowedips_node *node, *node_;
10782c705f0SAaron LI
1084c074b47SAaron LI LIST_FOREACH_MUTABLE(node, &table->head, entry, node_) {
1094c074b47SAaron LI LIST_REMOVE(node, entry);
110cf257a5cSAaron LI kfree(node, M_WG);
11182c705f0SAaron LI }
11282c705f0SAaron LI }
11382c705f0SAaron LI
1144c074b47SAaron LI static inline void
horrible_cidr_to_mask(uint8_t cidr,struct aip_addr * mask)1154c074b47SAaron LI horrible_cidr_to_mask(uint8_t cidr, struct aip_addr *mask)
11682c705f0SAaron LI {
1174c074b47SAaron LI uint8_t n;
11882c705f0SAaron LI
1194c074b47SAaron LI memset(&mask->in6, 0x00, sizeof(mask->in6));
1204c074b47SAaron LI memset(&mask->in6, 0xff, cidr / 8);
1214c074b47SAaron LI if ((n = cidr % 32) != 0)
1224c074b47SAaron LI mask->ip6[cidr / 32] =
1234c074b47SAaron LI (uint32_t)htonl((0xFFFFFFFFUL << (32 - n)) & 0xFFFFFFFFUL);
12482c705f0SAaron LI }
12582c705f0SAaron LI
1264c074b47SAaron LI static inline uint8_t
horrible_mask_to_cidr(const struct aip_addr * mask)1274c074b47SAaron LI horrible_mask_to_cidr(const struct aip_addr *mask)
12882c705f0SAaron LI {
1294c074b47SAaron LI return (bitcount32(mask->ip6[0]) +
1304c074b47SAaron LI bitcount32(mask->ip6[1]) +
1314c074b47SAaron LI bitcount32(mask->ip6[2]) +
1324c074b47SAaron LI bitcount32(mask->ip6[3]));
13382c705f0SAaron LI }
13482c705f0SAaron LI
13582c705f0SAaron LI static inline void
horrible_mask_self(struct horrible_allowedips_node * node)13682c705f0SAaron LI horrible_mask_self(struct horrible_allowedips_node *node)
13782c705f0SAaron LI {
1384c074b47SAaron LI KKASSERT(node->ip_version == 4 || node->ip_version == 6);
1394c074b47SAaron LI
14082c705f0SAaron LI if (node->ip_version == 4) {
14182c705f0SAaron LI node->ip.ip &= node->mask.ip;
1424c074b47SAaron LI } else {
14382c705f0SAaron LI node->ip.ip6[0] &= node->mask.ip6[0];
14482c705f0SAaron LI node->ip.ip6[1] &= node->mask.ip6[1];
14582c705f0SAaron LI node->ip.ip6[2] &= node->mask.ip6[2];
14682c705f0SAaron LI node->ip.ip6[3] &= node->mask.ip6[3];
14782c705f0SAaron LI }
14882c705f0SAaron LI }
14982c705f0SAaron LI
15082c705f0SAaron LI static inline bool
horrible_match_v4(const struct horrible_allowedips_node * node,const struct in_addr * ip)15182c705f0SAaron LI horrible_match_v4(const struct horrible_allowedips_node *node,
1524c074b47SAaron LI const struct in_addr *ip)
15382c705f0SAaron LI {
1544c074b47SAaron LI return ((ip->s_addr & node->mask.ip) == node->ip.ip);
15582c705f0SAaron LI }
15682c705f0SAaron LI
15782c705f0SAaron LI static inline bool
horrible_match_v6(const struct horrible_allowedips_node * node,const struct in6_addr * ip)15882c705f0SAaron LI horrible_match_v6(const struct horrible_allowedips_node *node,
1594c074b47SAaron LI const struct in6_addr *ip)
16082c705f0SAaron LI {
1614c074b47SAaron LI #define IP6MATCH_SEG(ip, node, n) \
1624c074b47SAaron LI ((ip->__u6_addr.__u6_addr32[n] & node->mask.ip6[n]) \
1634c074b47SAaron LI == node->ip.ip6[n])
1644c074b47SAaron LI
1654c074b47SAaron LI return (IP6MATCH_SEG(ip, node, 0) &&
1664c074b47SAaron LI IP6MATCH_SEG(ip, node, 1) &&
1674c074b47SAaron LI IP6MATCH_SEG(ip, node, 2) &&
1684c074b47SAaron LI IP6MATCH_SEG(ip, node, 3));
1694c074b47SAaron LI
1704c074b47SAaron LI #undef IP6MATCH_SEG
17182c705f0SAaron LI }
17282c705f0SAaron LI
17382c705f0SAaron LI static void
horrible_insert_ordered(struct horrible_allowedips * table,struct horrible_allowedips_node * node)17482c705f0SAaron LI horrible_insert_ordered(struct horrible_allowedips *table,
17582c705f0SAaron LI struct horrible_allowedips_node *node)
17682c705f0SAaron LI {
1774c074b47SAaron LI struct horrible_allowedips_node *other, *where;
1784c074b47SAaron LI uint8_t my_cidr;
17982c705f0SAaron LI
1804c074b47SAaron LI other = where = NULL;
1814c074b47SAaron LI my_cidr = horrible_mask_to_cidr(&node->mask);
1824c074b47SAaron LI
1834c074b47SAaron LI LIST_FOREACH(other, &table->head, entry) {
18482c705f0SAaron LI if (!memcmp(&other->mask, &node->mask,
18582c705f0SAaron LI sizeof(struct aip_addr)) &&
18682c705f0SAaron LI !memcmp(&other->ip, &node->ip,
18782c705f0SAaron LI sizeof(struct aip_addr)) &&
1884c074b47SAaron LI other->ip_version == node->ip_version)
1894c074b47SAaron LI {
19082c705f0SAaron LI other->value = node->value;
191cf257a5cSAaron LI kfree(node, M_WG);
19282c705f0SAaron LI return;
19382c705f0SAaron LI }
19482c705f0SAaron LI where = other;
1954c074b47SAaron LI if (horrible_mask_to_cidr(&other->mask) <= my_cidr)
19682c705f0SAaron LI break;
19782c705f0SAaron LI }
1984c074b47SAaron LI
1994c074b47SAaron LI if (other == NULL && where == NULL)
2004c074b47SAaron LI LIST_INSERT_HEAD(&table->head, node, entry);
2014c074b47SAaron LI else if (other == NULL)
2024c074b47SAaron LI LIST_INSERT_AFTER(where, node, entry);
20382c705f0SAaron LI else
2044c074b47SAaron LI LIST_INSERT_BEFORE(where, node, entry);
20582c705f0SAaron LI }
20682c705f0SAaron LI
20782c705f0SAaron LI static int
horrible_allowedips_insert_v4(struct horrible_allowedips * table,const void * ip,uint8_t cidr,void * value)20882c705f0SAaron LI horrible_allowedips_insert_v4(struct horrible_allowedips *table,
2094c074b47SAaron LI const void *ip, uint8_t cidr, void *value)
21082c705f0SAaron LI {
2114c074b47SAaron LI struct horrible_allowedips_node *node;
21282c705f0SAaron LI
2134c074b47SAaron LI node = kmalloc(sizeof(*node), M_WG, M_NOWAIT | M_ZERO);
2144c074b47SAaron LI if (node == NULL)
2154c074b47SAaron LI return (ENOMEM);
2164c074b47SAaron LI
2174c074b47SAaron LI node->ip.in = *(const struct in_addr *)ip;
2184c074b47SAaron LI horrible_cidr_to_mask(cidr, &node->mask);
21982c705f0SAaron LI node->ip_version = 4;
22082c705f0SAaron LI node->value = value;
2214c074b47SAaron LI
22282c705f0SAaron LI horrible_mask_self(node);
22382c705f0SAaron LI horrible_insert_ordered(table, node);
2244c074b47SAaron LI
2254c074b47SAaron LI return (0);
22682c705f0SAaron LI }
22782c705f0SAaron LI
22882c705f0SAaron LI static int
horrible_allowedips_insert_v6(struct horrible_allowedips * table,const void * ip,uint8_t cidr,void * value)22982c705f0SAaron LI horrible_allowedips_insert_v6(struct horrible_allowedips *table,
2304c074b47SAaron LI const void *ip, uint8_t cidr, void *value)
23182c705f0SAaron LI {
2324c074b47SAaron LI struct horrible_allowedips_node *node;
23382c705f0SAaron LI
2344c074b47SAaron LI node = kmalloc(sizeof(*node), M_WG, M_NOWAIT | M_ZERO);
2354c074b47SAaron LI if (node == NULL)
2364c074b47SAaron LI return (ENOMEM);
2374c074b47SAaron LI
2384c074b47SAaron LI node->ip.in6 = *(const struct in6_addr *)ip;
2394c074b47SAaron LI horrible_cidr_to_mask(cidr, &node->mask);
24082c705f0SAaron LI node->ip_version = 6;
24182c705f0SAaron LI node->value = value;
2424c074b47SAaron LI
24382c705f0SAaron LI horrible_mask_self(node);
24482c705f0SAaron LI horrible_insert_ordered(table, node);
2454c074b47SAaron LI
2464c074b47SAaron LI return (0);
24782c705f0SAaron LI }
24882c705f0SAaron LI
24982c705f0SAaron LI static void *
horrible_allowedips_lookup_v4(const struct horrible_allowedips * table,const void * ip)2504c074b47SAaron LI horrible_allowedips_lookup_v4(const struct horrible_allowedips *table,
2514c074b47SAaron LI const void *ip)
25282c705f0SAaron LI {
25382c705f0SAaron LI struct horrible_allowedips_node *node;
25482c705f0SAaron LI void *ret = NULL;
25582c705f0SAaron LI
2564c074b47SAaron LI LIST_FOREACH(node, &table->head, entry) {
25782c705f0SAaron LI if (node->ip_version != 4)
25882c705f0SAaron LI continue;
2594c074b47SAaron LI if (horrible_match_v4(node, (const struct in_addr *)ip)) {
26082c705f0SAaron LI ret = node->value;
26182c705f0SAaron LI break;
26282c705f0SAaron LI }
26382c705f0SAaron LI }
2644c074b47SAaron LI
2654c074b47SAaron LI return (ret);
26682c705f0SAaron LI }
26782c705f0SAaron LI
26882c705f0SAaron LI static void *
horrible_allowedips_lookup_v6(const struct horrible_allowedips * table,const void * ip)2694c074b47SAaron LI horrible_allowedips_lookup_v6(const struct horrible_allowedips *table,
2704c074b47SAaron LI const void *ip)
27182c705f0SAaron LI {
27282c705f0SAaron LI struct horrible_allowedips_node *node;
27382c705f0SAaron LI void *ret = NULL;
27482c705f0SAaron LI
2754c074b47SAaron LI LIST_FOREACH(node, &table->head, entry) {
27682c705f0SAaron LI if (node->ip_version != 6)
27782c705f0SAaron LI continue;
2784c074b47SAaron LI if (horrible_match_v6(node, (const struct in6_addr *)ip)) {
27982c705f0SAaron LI ret = node->value;
28082c705f0SAaron LI break;
28182c705f0SAaron LI }
28282c705f0SAaron LI }
2834c074b47SAaron LI
2844c074b47SAaron LI return (ret);
28582c705f0SAaron LI }
28682c705f0SAaron LI
2874c074b47SAaron LI #define T_NUM_PEERS 2000
2884c074b47SAaron LI #define T_NUM_RAND_ROUTES 400
2894c074b47SAaron LI #define T_NUM_MUTATED_ROUTES 100
2904c074b47SAaron LI #define T_NUM_QUERIES (T_NUM_RAND_ROUTES * T_NUM_MUTATED_ROUTES * 30)
2914c074b47SAaron LI
2924c074b47SAaron LI static bool
wg_allowedips_randomized_test(void)2934c074b47SAaron LI wg_allowedips_randomized_test(void)
29482c705f0SAaron LI {
29582c705f0SAaron LI struct horrible_allowedips h;
2964c074b47SAaron LI struct wg_softc sc;
2974c074b47SAaron LI struct wg_peer **peers, *peer;
2984c074b47SAaron LI unsigned int i, j, k, p, nextp, mutate_amount;
2994c074b47SAaron LI uint8_t ip[16], mutated[16], mutate_mask[16], cidr;
30082c705f0SAaron LI bool ret = false;
30182c705f0SAaron LI
3024c074b47SAaron LI peers = NULL;
3034c074b47SAaron LI
30482c705f0SAaron LI horrible_allowedips_init(&h);
3054c074b47SAaron LI if (!test_aip_init(&sc)) {
3064c074b47SAaron LI kprintf("%s: FAIL: test_aip_init\n", __func__);
3074c074b47SAaron LI goto error;
3084c074b47SAaron LI }
3094c074b47SAaron LI peers = kmalloc(T_NUM_PEERS * sizeof(*peers), M_WG, M_NOWAIT | M_ZERO);
3104c074b47SAaron LI if (peers == NULL) {
3114c074b47SAaron LI kprintf("%s: FAIL: peers malloc\n", __func__);
3124c074b47SAaron LI goto error;
3134c074b47SAaron LI }
3144c074b47SAaron LI for (i = 0; i < T_NUM_PEERS; ++i) {
3154c074b47SAaron LI peers[i] = test_aip_peer_new(&sc);
3164c074b47SAaron LI if (peers[i] == NULL) {
3174c074b47SAaron LI kprintf("%s: FAIL: peer_new\n", __func__);
3184c074b47SAaron LI goto error;
3194c074b47SAaron LI }
3204c074b47SAaron LI }
32182c705f0SAaron LI
3224c074b47SAaron LI kprintf("%s: inserting v4 routes: ", __func__);
3234c074b47SAaron LI for (i = 0, nextp = 0; i < T_NUM_RAND_ROUTES; ++i) {
3244c074b47SAaron LI if ((p = i * 100 / T_NUM_RAND_ROUTES) == nextp) {
3254c074b47SAaron LI kprintf("%d%%...", p);
3264c074b47SAaron LI nextp += 10;
3274c074b47SAaron LI }
328cf257a5cSAaron LI karc4random_buf(ip, 4);
329cf257a5cSAaron LI cidr = karc4random_uniform(32) + 1;
3304c074b47SAaron LI peer = peers[karc4random_uniform(T_NUM_PEERS)];
33182c705f0SAaron LI if (wg_aip_add(&sc, peer, AF_INET, ip, cidr)) {
3324c074b47SAaron LI kprintf("%s: FAIL: wg_aip_add(v4)\n", __func__);
3334c074b47SAaron LI goto error;
33482c705f0SAaron LI }
3354c074b47SAaron LI if (horrible_allowedips_insert_v4(&h, ip, cidr, peer)) {
3364c074b47SAaron LI kprintf("%s: FAIL: insert_v4\n", __func__);
3374c074b47SAaron LI goto error;
33882c705f0SAaron LI }
3394c074b47SAaron LI for (j = 0; j < T_NUM_MUTATED_ROUTES; ++j) {
34082c705f0SAaron LI memcpy(mutated, ip, 4);
341cf257a5cSAaron LI karc4random_buf(mutate_mask, 4);
342cf257a5cSAaron LI mutate_amount = karc4random_uniform(32);
34382c705f0SAaron LI for (k = 0; k < mutate_amount / 8; ++k)
34482c705f0SAaron LI mutate_mask[k] = 0xff;
3454c074b47SAaron LI mutate_mask[k] =
3464c074b47SAaron LI 0xff << ((8 - (mutate_amount % 8)) % 8);
34782c705f0SAaron LI for (; k < 4; ++k)
34882c705f0SAaron LI mutate_mask[k] = 0;
3494c074b47SAaron LI for (k = 0; k < 4; ++k) {
35082c705f0SAaron LI mutated[k] = (mutated[k] & mutate_mask[k]) |
35182c705f0SAaron LI (~mutate_mask[k] &
352cf257a5cSAaron LI karc4random_uniform(256));
3534c074b47SAaron LI }
354cf257a5cSAaron LI cidr = karc4random_uniform(32) + 1;
3554c074b47SAaron LI peer = peers[karc4random_uniform(T_NUM_PEERS)];
35682c705f0SAaron LI if (wg_aip_add(&sc, peer, AF_INET, mutated, cidr)) {
3574c074b47SAaron LI kprintf("%s: FAIL: wg_aip_add(v4)\n", __func__);
3584c074b47SAaron LI goto error;
35982c705f0SAaron LI }
3604c074b47SAaron LI if (horrible_allowedips_insert_v4(&h, mutated, cidr,
3614c074b47SAaron LI peer)) {
3624c074b47SAaron LI kprintf("%s: FAIL: insert_v4\n", __func__);
3634c074b47SAaron LI goto error;
36482c705f0SAaron LI }
36582c705f0SAaron LI }
36682c705f0SAaron LI }
3674c074b47SAaron LI kprintf("done\n");
36882c705f0SAaron LI
369*350efd1cSAaron LI kprintf("%s: v4 looking up: ", __func__);
370*350efd1cSAaron LI for (i = 0, nextp = 0; i < T_NUM_QUERIES; ++i) {
371*350efd1cSAaron LI if ((p = i * 100 / T_NUM_QUERIES) == nextp) {
372*350efd1cSAaron LI kprintf("%d%%...", p);
373*350efd1cSAaron LI nextp += 5;
374*350efd1cSAaron LI }
375*350efd1cSAaron LI karc4random_buf(ip, 4);
376*350efd1cSAaron LI if (wg_aip_lookup(&sc, AF_INET, ip) !=
377*350efd1cSAaron LI horrible_allowedips_lookup_v4(&h, ip)) {
378*350efd1cSAaron LI kprintf("%s: FAIL: lookup_v4\n", __func__);
379*350efd1cSAaron LI goto error;
380*350efd1cSAaron LI }
381*350efd1cSAaron LI }
382*350efd1cSAaron LI kprintf("pass\n");
383*350efd1cSAaron LI
384*350efd1cSAaron LI /*
385*350efd1cSAaron LI * Flush existing v4 routes for the following v6 test so as to
386*350efd1cSAaron LI * significantly reduce the test time.
387*350efd1cSAaron LI */
388*350efd1cSAaron LI horrible_allowedips_flush(&h);
389*350efd1cSAaron LI
3904c074b47SAaron LI kprintf("%s: inserting v6 routes: ", __func__);
3914c074b47SAaron LI for (i = 0, nextp = 0; i < T_NUM_RAND_ROUTES; ++i) {
3924c074b47SAaron LI if ((p = i * 100 / T_NUM_RAND_ROUTES) == nextp) {
3934c074b47SAaron LI kprintf("%d%%...", p);
3944c074b47SAaron LI nextp += 10;
3954c074b47SAaron LI }
396cf257a5cSAaron LI karc4random_buf(ip, 16);
397cf257a5cSAaron LI cidr = karc4random_uniform(128) + 1;
3984c074b47SAaron LI peer = peers[karc4random_uniform(T_NUM_PEERS)];
39982c705f0SAaron LI if (wg_aip_add(&sc, peer, AF_INET6, ip, cidr)) {
4004c074b47SAaron LI kprintf("%s: FAIL: wg_aip_add(v6)\n", __func__);
4014c074b47SAaron LI goto error;
40282c705f0SAaron LI }
4034c074b47SAaron LI if (horrible_allowedips_insert_v6(&h, ip, cidr, peer)) {
4044c074b47SAaron LI kprintf("%s: FAIL: insert_v6\n", __func__);
4054c074b47SAaron LI goto error;
40682c705f0SAaron LI }
4074c074b47SAaron LI for (j = 0; j < T_NUM_MUTATED_ROUTES; ++j) {
40882c705f0SAaron LI memcpy(mutated, ip, 16);
409cf257a5cSAaron LI karc4random_buf(mutate_mask, 16);
410cf257a5cSAaron LI mutate_amount = karc4random_uniform(128);
41182c705f0SAaron LI for (k = 0; k < mutate_amount / 8; ++k)
41282c705f0SAaron LI mutate_mask[k] = 0xff;
4134c074b47SAaron LI mutate_mask[k] =
4144c074b47SAaron LI 0xff << ((8 - (mutate_amount % 8)) % 8);
41582c705f0SAaron LI for (; k < 4; ++k)
41682c705f0SAaron LI mutate_mask[k] = 0;
4174c074b47SAaron LI for (k = 0; k < 4; ++k) {
41882c705f0SAaron LI mutated[k] = (mutated[k] & mutate_mask[k]) |
41982c705f0SAaron LI (~mutate_mask[k] &
420cf257a5cSAaron LI karc4random_uniform(256));
4214c074b47SAaron LI }
422cf257a5cSAaron LI cidr = karc4random_uniform(128) + 1;
4234c074b47SAaron LI peer = peers[karc4random_uniform(T_NUM_PEERS)];
42482c705f0SAaron LI if (wg_aip_add(&sc, peer, AF_INET6, mutated, cidr)) {
4254c074b47SAaron LI kprintf("%s: FAIL: wg_aip_add(v6)\n", __func__);
4264c074b47SAaron LI goto error;
42782c705f0SAaron LI }
4284c074b47SAaron LI if (horrible_allowedips_insert_v6(&h, mutated, cidr,
42982c705f0SAaron LI peer)) {
4304c074b47SAaron LI kprintf("%s: FAIL: insert_v6\n", __func__);
4314c074b47SAaron LI goto error;
43282c705f0SAaron LI }
43382c705f0SAaron LI }
43482c705f0SAaron LI }
4354c074b47SAaron LI kprintf("done\n");
43682c705f0SAaron LI
4374c074b47SAaron LI kprintf("%s: v6 looking up: ", __func__);
4384c074b47SAaron LI for (i = 0, nextp = 0; i < T_NUM_QUERIES; ++i) {
4394c074b47SAaron LI if ((p = i * 100 / T_NUM_QUERIES) == nextp) {
4404c074b47SAaron LI kprintf("%d%%...", p);
4414c074b47SAaron LI nextp += 5;
4424c074b47SAaron LI }
443cf257a5cSAaron LI karc4random_buf(ip, 16);
44482c705f0SAaron LI if (wg_aip_lookup(&sc, AF_INET6, ip) !=
4454c074b47SAaron LI horrible_allowedips_lookup_v6(&h, ip)) {
4464c074b47SAaron LI kprintf("%s: FAIL: lookup_v6\n", __func__);
4474c074b47SAaron LI goto error;
44882c705f0SAaron LI }
44982c705f0SAaron LI }
4504c074b47SAaron LI kprintf("pass\n");
45182c705f0SAaron LI
4524c074b47SAaron LI ret = true;
4534c074b47SAaron LI kprintf("%s: pass\n", __func__);
4544c074b47SAaron LI
4554c074b47SAaron LI error:
456*350efd1cSAaron LI horrible_allowedips_flush(&h);
4574c074b47SAaron LI if (peers != NULL) {
4584c074b47SAaron LI for (i = 0; i < T_NUM_PEERS; ++i) {
4594c074b47SAaron LI if (peers[i] != NULL) {
46082c705f0SAaron LI wg_aip_remove_all(&sc, peers[i]);
461cf257a5cSAaron LI kfree(peers[i], M_WG);
46282c705f0SAaron LI }
46382c705f0SAaron LI }
4644c074b47SAaron LI kfree(peers, M_WG);
4654c074b47SAaron LI }
4664c074b47SAaron LI test_aip_deinit(&sc);
46782c705f0SAaron LI
4684c074b47SAaron LI return (ret);
4694c074b47SAaron LI }
4704c074b47SAaron LI
4714c074b47SAaron LI #else /* !WG_ALLOWEDIPS_RANDOMIZED_TEST */
4724c074b47SAaron LI
4734c074b47SAaron LI static inline bool
wg_allowedips_randomized_test(void)4744c074b47SAaron LI wg_allowedips_randomized_test(void)
4754c074b47SAaron LI {
4764c074b47SAaron LI return (true);
4774c074b47SAaron LI }
4784c074b47SAaron LI
4794c074b47SAaron LI #endif /* WG_ALLOWEDIPS_RANDOMIZED_TEST */
4804c074b47SAaron LI
4814c074b47SAaron LI static inline void *
ip_make_v4(uint8_t a,uint8_t b,uint8_t c,uint8_t d)4824c074b47SAaron LI ip_make_v4(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
48382c705f0SAaron LI {
48482c705f0SAaron LI static struct in_addr ip;
48582c705f0SAaron LI uint8_t *split = (uint8_t *)&ip;
48682c705f0SAaron LI
48782c705f0SAaron LI split[0] = a;
48882c705f0SAaron LI split[1] = b;
48982c705f0SAaron LI split[2] = c;
49082c705f0SAaron LI split[3] = d;
4914c074b47SAaron LI
4924c074b47SAaron LI return (void *)&ip;
49382c705f0SAaron LI }
49482c705f0SAaron LI
4954c074b47SAaron LI static inline void *
ip_make_v6(uint32_t a,uint32_t b,uint32_t c,uint32_t d)4964c074b47SAaron LI ip_make_v6(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
49782c705f0SAaron LI {
49882c705f0SAaron LI static struct in6_addr ip;
49982c705f0SAaron LI uint32_t *split = ip.__u6_addr.__u6_addr32;
50082c705f0SAaron LI
50182c705f0SAaron LI split[0] = htobe32(a);
50282c705f0SAaron LI split[1] = htobe32(b);
50382c705f0SAaron LI split[2] = htobe32(c);
50482c705f0SAaron LI split[3] = htobe32(d);
5054c074b47SAaron LI
5064c074b47SAaron LI return (void *)&ip;
50782c705f0SAaron LI }
50882c705f0SAaron LI
5094c074b47SAaron LI static inline bool
ip_equal_v4(const void * ip,uint8_t a,uint8_t b,uint8_t c,uint8_t d)5104c074b47SAaron LI ip_equal_v4(const void *ip, uint8_t a, uint8_t b, uint8_t c, uint8_t d)
51182c705f0SAaron LI {
5124c074b47SAaron LI return (memcmp(ip, ip_make_v4(a, b, c, d), 4) == 0);
51382c705f0SAaron LI }
51482c705f0SAaron LI
5154c074b47SAaron LI static inline bool
ip_equal_v6(const void * ip,uint32_t a,uint32_t b,uint32_t c,uint32_t d)5164c074b47SAaron LI ip_equal_v6(const void *ip, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
5174c074b47SAaron LI {
5184c074b47SAaron LI return (memcmp(ip, ip_make_v6(a, b, c, d), 16) == 0);
5194c074b47SAaron LI }
5204c074b47SAaron LI
5214c074b47SAaron LI #define T_INSERT(n, peer, af, ipa, ipb, ipc, ipd, cidr) do { \
5224c074b47SAaron LI const void *_ip = (af == AF_INET) ? \
5234c074b47SAaron LI ip_make_v4(ipa, ipb, ipc, ipd) : \
5244c074b47SAaron LI ip_make_v6(ipa, ipb, ipc, ipd); \
5254c074b47SAaron LI if (wg_aip_add(&sc, peer, af, _ip, cidr)) { \
5264c074b47SAaron LI kprintf("%s: insert #%d: FAIL\n", __func__, n); \
52782c705f0SAaron LI success = false; \
52882c705f0SAaron LI } \
52982c705f0SAaron LI } while (0)
53082c705f0SAaron LI
5314c074b47SAaron LI #define T_LOOKUP(n, op, peer, af, ipa, ipb, ipc, ipd) do { \
5324c074b47SAaron LI const void *_ip = (af == AF_INET) ? \
5334c074b47SAaron LI ip_make_v4(ipa, ipb, ipc, ipd) : \
5344c074b47SAaron LI ip_make_v6(ipa, ipb, ipc, ipd); \
5354c074b47SAaron LI if (!(wg_aip_lookup(&sc, af, _ip) op peer)) { \
5364c074b47SAaron LI kprintf("%s: lookup #%d: FAIL\n", __func__, n); \
53782c705f0SAaron LI success = false; \
53882c705f0SAaron LI } \
53982c705f0SAaron LI } while (0)
54082c705f0SAaron LI
5414c074b47SAaron LI #define T_NEW_PEER(p) do { \
5424c074b47SAaron LI if ((p = test_aip_peer_new(&sc)) == NULL) { \
5434c074b47SAaron LI kprintf("%s: FAIL: peer_new(%s)\n", __func__, #p); \
5444c074b47SAaron LI goto error; \
5454c074b47SAaron LI } \
54682c705f0SAaron LI } while (0)
54782c705f0SAaron LI
5484c074b47SAaron LI #define T_NEW_PEERS() do { \
5494c074b47SAaron LI T_NEW_PEER(a); \
5504c074b47SAaron LI T_NEW_PEER(b); \
5514c074b47SAaron LI T_NEW_PEER(c); \
5524c074b47SAaron LI T_NEW_PEER(d); \
5534c074b47SAaron LI T_NEW_PEER(e); \
5544c074b47SAaron LI T_NEW_PEER(f); \
5554c074b47SAaron LI T_NEW_PEER(g); \
5564c074b47SAaron LI T_NEW_PEER(h); \
55782c705f0SAaron LI } while (0)
55882c705f0SAaron LI
5594c074b47SAaron LI #define T_CLEAR_PEERS() do { \
5604c074b47SAaron LI if (a != NULL) \
5614c074b47SAaron LI wg_aip_remove_all(&sc, a); \
5624c074b47SAaron LI if (b != NULL) \
5634c074b47SAaron LI wg_aip_remove_all(&sc, b); \
5644c074b47SAaron LI if (c != NULL) \
5654c074b47SAaron LI wg_aip_remove_all(&sc, c); \
5664c074b47SAaron LI if (d != NULL) \
5674c074b47SAaron LI wg_aip_remove_all(&sc, d); \
5684c074b47SAaron LI if (e != NULL) \
5694c074b47SAaron LI wg_aip_remove_all(&sc, e); \
5704c074b47SAaron LI if (f != NULL) \
5714c074b47SAaron LI wg_aip_remove_all(&sc, f); \
5724c074b47SAaron LI if (g != NULL) \
5734c074b47SAaron LI wg_aip_remove_all(&sc, g); \
5744c074b47SAaron LI if (h != NULL) \
5754c074b47SAaron LI wg_aip_remove_all(&sc, h); \
57682c705f0SAaron LI } while (0)
57782c705f0SAaron LI
5784c074b47SAaron LI #define T_FREE_PEERS() do { \
5794c074b47SAaron LI T_CLEAR_PEERS(); \
5804c074b47SAaron LI if (a != NULL) \
5814c074b47SAaron LI kfree(a, M_WG); \
5824c074b47SAaron LI if (b != NULL) \
5834c074b47SAaron LI kfree(b, M_WG); \
5844c074b47SAaron LI if (c != NULL) \
5854c074b47SAaron LI kfree(c, M_WG); \
5864c074b47SAaron LI if (d != NULL) \
5874c074b47SAaron LI kfree(d, M_WG); \
5884c074b47SAaron LI if (e != NULL) \
5894c074b47SAaron LI kfree(e, M_WG); \
5904c074b47SAaron LI if (f != NULL) \
5914c074b47SAaron LI kfree(f, M_WG); \
5924c074b47SAaron LI if (g != NULL) \
5934c074b47SAaron LI kfree(g, M_WG); \
5944c074b47SAaron LI if (h != NULL) \
5954c074b47SAaron LI kfree(h, M_WG); \
59682c705f0SAaron LI } while (0)
59782c705f0SAaron LI
5984c074b47SAaron LI static bool
wg_allowedips_lookup_test(void)5994c074b47SAaron LI wg_allowedips_lookup_test(void)
60082c705f0SAaron LI {
6014c074b47SAaron LI struct wg_softc sc;
6024c074b47SAaron LI struct wg_peer *a = NULL, *b = NULL, *c = NULL, *d = NULL;
6034c074b47SAaron LI struct wg_peer *e = NULL, *f = NULL, *g = NULL, *h = NULL;
6044c074b47SAaron LI struct wg_aip *aip;
6054c074b47SAaron LI size_t i, count;
6064c074b47SAaron LI bool found_a, found_b, found_c, found_d, found_e, found_other;
60782c705f0SAaron LI bool success = false;
60882c705f0SAaron LI
60982c705f0SAaron LI if (!test_aip_init(&sc)) {
6104c074b47SAaron LI kprintf("%s: FAIL: test_aip_init\n", __func__);
6114c074b47SAaron LI goto error;
61282c705f0SAaron LI }
61382c705f0SAaron LI
6144c074b47SAaron LI T_NEW_PEERS();
61582c705f0SAaron LI
6164c074b47SAaron LI T_INSERT( 1, a, AF_INET, 192, 168, 4, 0, 24);
6174c074b47SAaron LI T_INSERT( 2, b, AF_INET, 192, 168, 4, 4, 32);
6184c074b47SAaron LI T_INSERT( 3, c, AF_INET, 192, 168, 0, 0, 16);
6194c074b47SAaron LI T_INSERT( 4, d, AF_INET, 192, 95, 5, 64, 27);
62082c705f0SAaron LI /* replaces previous entry, and maskself is required */
6214c074b47SAaron LI T_INSERT( 5, c, AF_INET, 192, 95, 5, 65, 27);
6224c074b47SAaron LI T_INSERT( 6, d, AF_INET6,
6234c074b47SAaron LI 0x26075300, 0x60006b00, 0, 0xc05f0543, 128);
6244c074b47SAaron LI T_INSERT( 7, c, AF_INET6,
6254c074b47SAaron LI 0x26075300, 0x60006b00, 0, 0, 64);
6264c074b47SAaron LI T_INSERT( 8, e, AF_INET, 0, 0, 0, 0, 0);
6274c074b47SAaron LI T_INSERT( 9, e, AF_INET6, 0, 0, 0, 0, 0);
62882c705f0SAaron LI /* replaces previous entry */
6294c074b47SAaron LI T_INSERT(10, f, AF_INET6, 0, 0, 0, 0, 0);
6304c074b47SAaron LI T_INSERT(11, g, AF_INET6, 0x24046800, 0, 0, 0, 32);
63182c705f0SAaron LI /* maskself is required */
6324c074b47SAaron LI T_INSERT(12, h, AF_INET6,
6334c074b47SAaron LI 0x24046800, 0x40040800, 0xdeadbeef, 0xdeadbeef, 64);
6344c074b47SAaron LI T_INSERT(13, a, AF_INET6,
6354c074b47SAaron LI 0x24046800, 0x40040800, 0xdeadbeef, 0xdeadbeef, 128);
6364c074b47SAaron LI T_INSERT(14, c, AF_INET6,
6374c074b47SAaron LI 0x24446800, 0x40e40800, 0xdeaebeef, 0xdefbeef, 128);
6384c074b47SAaron LI T_INSERT(15, b, AF_INET6,
6394c074b47SAaron LI 0x24446800, 0xf0e40800, 0xeeaebeef, 0, 98);
6404c074b47SAaron LI T_INSERT(16, g, AF_INET, 64, 15, 112, 0, 20);
64182c705f0SAaron LI /* maskself is required */
6424c074b47SAaron LI T_INSERT(17, h, AF_INET, 64, 15, 123, 211, 25);
6434c074b47SAaron LI T_INSERT(18, a, AF_INET, 10, 0, 0, 0, 25);
6444c074b47SAaron LI T_INSERT(19, b, AF_INET, 10, 0, 0, 128, 25);
6454c074b47SAaron LI T_INSERT(20, a, AF_INET, 10, 1, 0, 0, 30);
6464c074b47SAaron LI T_INSERT(21, b, AF_INET, 10, 1, 0, 4, 30);
6474c074b47SAaron LI T_INSERT(22, c, AF_INET, 10, 1, 0, 8, 29);
6484c074b47SAaron LI T_INSERT(23, d, AF_INET, 10, 1, 0, 16, 29);
64982c705f0SAaron LI
65082c705f0SAaron LI success = true;
65182c705f0SAaron LI
6524c074b47SAaron LI T_LOOKUP( 1, ==, a, AF_INET, 192, 168, 4, 20);
6534c074b47SAaron LI T_LOOKUP( 2, ==, a, AF_INET, 192, 168, 4, 0);
6544c074b47SAaron LI T_LOOKUP( 3, ==, b, AF_INET, 192, 168, 4, 4);
6554c074b47SAaron LI T_LOOKUP( 4, ==, c, AF_INET, 192, 168, 200, 182);
6564c074b47SAaron LI T_LOOKUP( 5, ==, c, AF_INET, 192, 95, 5, 68);
6574c074b47SAaron LI T_LOOKUP( 6, ==, e, AF_INET, 192, 95, 5, 96);
6584c074b47SAaron LI T_LOOKUP( 7, ==, d, AF_INET6,
6594c074b47SAaron LI 0x26075300, 0x60006b00, 0, 0xc05f0543);
6604c074b47SAaron LI T_LOOKUP( 8, ==, c, AF_INET6,
6614c074b47SAaron LI 0x26075300, 0x60006b00, 0, 0xc02e01ee);
6624c074b47SAaron LI T_LOOKUP( 9, ==, f, AF_INET6,
6634c074b47SAaron LI 0x26075300, 0x60006b01, 0, 0);
6644c074b47SAaron LI T_LOOKUP(10, ==, g, AF_INET6,
6654c074b47SAaron LI 0x24046800, 0x40040806, 0, 0x1006);
6664c074b47SAaron LI T_LOOKUP(11, ==, g, AF_INET6,
6674c074b47SAaron LI 0x24046800, 0x40040806, 0x1234, 0x5678);
6684c074b47SAaron LI T_LOOKUP(12, ==, f, AF_INET6,
6694c074b47SAaron LI 0x240467ff, 0x40040806, 0x1234, 0x5678);
6704c074b47SAaron LI T_LOOKUP(13, ==, f, AF_INET6,
6714c074b47SAaron LI 0x24046801, 0x40040806, 0x1234, 0x5678);
6724c074b47SAaron LI T_LOOKUP(14, ==, h, AF_INET6,
6734c074b47SAaron LI 0x24046800, 0x40040800, 0x1234, 0x5678);
6744c074b47SAaron LI T_LOOKUP(15, ==, h, AF_INET6,
6754c074b47SAaron LI 0x24046800, 0x40040800, 0, 0);
6764c074b47SAaron LI T_LOOKUP(16, ==, h, AF_INET6,
6774c074b47SAaron LI 0x24046800, 0x40040800, 0x10101010, 0x10101010);
6784c074b47SAaron LI T_LOOKUP(17, ==, a, AF_INET6,
6794c074b47SAaron LI 0x24046800, 0x40040800, 0xdeadbeef, 0xdeadbeef);
6804c074b47SAaron LI T_LOOKUP(18, ==, g, AF_INET, 64, 15, 116, 26);
6814c074b47SAaron LI T_LOOKUP(19, ==, g, AF_INET, 64, 15, 127, 3);
6824c074b47SAaron LI T_LOOKUP(20, ==, g, AF_INET, 64, 15, 123, 1);
6834c074b47SAaron LI T_LOOKUP(21, ==, h, AF_INET, 64, 15, 123, 128);
6844c074b47SAaron LI T_LOOKUP(22, ==, h, AF_INET, 64, 15, 123, 129);
6854c074b47SAaron LI T_LOOKUP(23, ==, a, AF_INET, 10, 0, 0, 52);
6864c074b47SAaron LI T_LOOKUP(24, ==, b, AF_INET, 10, 0, 0, 220);
6874c074b47SAaron LI T_LOOKUP(25, ==, a, AF_INET, 10, 1, 0, 2);
6884c074b47SAaron LI T_LOOKUP(26, ==, b, AF_INET, 10, 1, 0, 6);
6894c074b47SAaron LI T_LOOKUP(27, ==, c, AF_INET, 10, 1, 0, 10);
6904c074b47SAaron LI T_LOOKUP(28, ==, d, AF_INET, 10, 1, 0, 20);
69182c705f0SAaron LI
6924c074b47SAaron LI T_INSERT(24, a, AF_INET, 1, 0, 0, 0, 32);
6934c074b47SAaron LI T_INSERT(25, a, AF_INET, 64, 0, 0, 0, 32);
6944c074b47SAaron LI T_INSERT(26, a, AF_INET, 128, 0, 0, 0, 32);
6954c074b47SAaron LI T_INSERT(27, a, AF_INET, 192, 0, 0, 0, 32);
6964c074b47SAaron LI T_INSERT(28, a, AF_INET, 255, 0, 0, 0, 32);
69782c705f0SAaron LI wg_aip_remove_all(&sc, a);
6984c074b47SAaron LI T_LOOKUP(29, !=, a, AF_INET, 1, 0, 0, 0);
6994c074b47SAaron LI T_LOOKUP(30, !=, a, AF_INET, 64, 0, 0, 0);
7004c074b47SAaron LI T_LOOKUP(31, !=, a, AF_INET, 128, 0, 0, 0);
7014c074b47SAaron LI T_LOOKUP(32, !=, a, AF_INET, 192, 0, 0, 0);
7024c074b47SAaron LI T_LOOKUP(33, !=, a, AF_INET, 255, 0, 0, 0);
70382c705f0SAaron LI
7044c074b47SAaron LI T_CLEAR_PEERS();
7054c074b47SAaron LI T_INSERT(29, a, AF_INET, 192, 168, 0, 0, 16);
7064c074b47SAaron LI T_INSERT(30, a, AF_INET, 192, 168, 0, 0, 24);
70782c705f0SAaron LI wg_aip_remove_all(&sc, a);
7084c074b47SAaron LI T_LOOKUP(34, !=, a, AF_INET, 192, 168, 0, 1);
70982c705f0SAaron LI
71082c705f0SAaron LI for (i = 0; i < 128; ++i) {
7114c074b47SAaron LI uint64_t part = htobe64(~(1LLU << (i % 64)));
7124c074b47SAaron LI struct in6_addr addr;
7134c074b47SAaron LI memset(&addr, 0xff, 16);
7144c074b47SAaron LI memcpy((uint8_t *)&addr + (i < 64) * 8, &part, 8);
7154c074b47SAaron LI wg_aip_add(&sc, a, AF_INET6, &addr, 128);
71682c705f0SAaron LI }
71782c705f0SAaron LI
7184c074b47SAaron LI T_CLEAR_PEERS();
7194c074b47SAaron LI T_INSERT(31, a, AF_INET, 192, 95, 5, 93, 27);
7204c074b47SAaron LI T_INSERT(32, a, AF_INET6,
7214c074b47SAaron LI 0x26075300, 0x60006b00, 0, 0xc05f0543, 128);
7224c074b47SAaron LI T_INSERT(33, a, AF_INET, 10, 1, 0, 20, 29);
7234c074b47SAaron LI T_INSERT(34, a, AF_INET6,
7244c074b47SAaron LI 0x26075300, 0x6d8a6bf8, 0xdab1f1df, 0xc05f1523, 83);
7254c074b47SAaron LI T_INSERT(35, a, AF_INET6,
7264c074b47SAaron LI 0x26075300, 0x6d8a6bf8, 0xdab1f1df, 0xc05f1523, 21);
7274c074b47SAaron LI count = 0;
7284c074b47SAaron LI found_a = found_b = found_c = found_d = found_e = found_other = false;
7294c074b47SAaron LI LIST_FOREACH(aip, &a->p_aips, a_entry) {
7304c074b47SAaron LI sa_family_t family = aip->a_af;
7314c074b47SAaron LI uint8_t *ip = aip->a_addr.bytes;
7324c074b47SAaron LI uint8_t cidr;
7334c074b47SAaron LI
73482c705f0SAaron LI if (family == AF_INET)
7354c074b47SAaron LI cidr = bitcount32(aip->a_mask.ip);
73682c705f0SAaron LI else if (family == AF_INET6)
7374c074b47SAaron LI cidr = in6_mask2len(&aip->a_mask.in6, NULL);
73882c705f0SAaron LI else
73982c705f0SAaron LI continue;
74082c705f0SAaron LI
74182c705f0SAaron LI count++;
74282c705f0SAaron LI
74382c705f0SAaron LI if (cidr == 27 && family == AF_INET &&
7444c074b47SAaron LI ip_equal_v4(ip, 192, 95, 5, 64))
74582c705f0SAaron LI found_a = true;
74682c705f0SAaron LI else if (cidr == 128 && family == AF_INET6 &&
7474c074b47SAaron LI ip_equal_v6(ip, 0x26075300, 0x60006b00, 0, 0xc05f0543))
74882c705f0SAaron LI found_b = true;
74982c705f0SAaron LI else if (cidr == 29 && family == AF_INET &&
7504c074b47SAaron LI ip_equal_v4(ip, 10, 1, 0, 16))
75182c705f0SAaron LI found_c = true;
75282c705f0SAaron LI else if (cidr == 83 && family == AF_INET6 &&
7534c074b47SAaron LI ip_equal_v6(ip, 0x26075300, 0x6d8a6bf8, 0xdab1e000, 0))
75482c705f0SAaron LI found_d = true;
75582c705f0SAaron LI else if (cidr == 21 && family == AF_INET6 &&
7564c074b47SAaron LI ip_equal_v6(ip, 0x26075000, 0, 0, 0))
75782c705f0SAaron LI found_e = true;
75882c705f0SAaron LI else
75982c705f0SAaron LI found_other = true;
76082c705f0SAaron LI }
7614c074b47SAaron LI if (!(count == 5 &&
7624c074b47SAaron LI found_a && found_b && found_c && found_d && found_e &&
7634c074b47SAaron LI !found_other)) {
7644c074b47SAaron LI kprintf("%s: aips lookup: FAIL\n", __func__);
7654c074b47SAaron LI success = false;
76682c705f0SAaron LI }
76782c705f0SAaron LI
7684c074b47SAaron LI kprintf("%s: %s\n", __func__, success ? "pass" : "FAIL");
7694c074b47SAaron LI
7704c074b47SAaron LI error:
7714c074b47SAaron LI T_FREE_PEERS();
7724c074b47SAaron LI test_aip_deinit(&sc);
7734c074b47SAaron LI return (success);
7744c074b47SAaron LI }
7754c074b47SAaron LI
7764c074b47SAaron LI #undef T_INSERT
7774c074b47SAaron LI #undef T_LOOKUP
7784c074b47SAaron LI #undef T_NEW_PEER
7794c074b47SAaron LI #undef T_NEW_PEERS
7804c074b47SAaron LI #undef T_CLEAR_PEERS
7814c074b47SAaron LI #undef T_FREE_PEERS
7824c074b47SAaron LI
7834c074b47SAaron LI static bool
wg_allowedips_selftest(void)7844c074b47SAaron LI wg_allowedips_selftest(void)
7854c074b47SAaron LI {
7864c074b47SAaron LI bool ret = true;
7874c074b47SAaron LI
7884c074b47SAaron LI ret &= wg_allowedips_lookup_test();
7894c074b47SAaron LI ret &= wg_allowedips_randomized_test();
7904c074b47SAaron LI
7914c074b47SAaron LI kprintf("%s: %s\n", __func__, ret ? "pass" : "FAIL");
7924c074b47SAaron LI return (ret);
7934c074b47SAaron LI }
794