Not much holds us back to switch kroute_find() to use a struct bgpd_addr as prefix argument. Only the match code needs some adoption. I created applymask() for this which works on bgpd_addrs like inet4applymask works on in_addrs.
I also switched a simple case in session.c over to applymask(). There is another one in bgpctl which I will send out once this is in. -- :wq Claudio Index: bgpd.h =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v retrieving revision 1.431 diff -u -p -r1.431 bgpd.h --- bgpd.h 16 Jun 2022 15:33:05 -0000 1.431 +++ bgpd.h 16 Jun 2022 16:30:55 -0000 @@ -1435,6 +1435,7 @@ int prefix_compare(const struct bgpd_a void inet4applymask(struct in_addr *, const struct in_addr *, int); void inet6applymask(struct in6_addr *, const struct in6_addr *, int); +void applymask(struct bgpd_addr *, const struct bgpd_addr *, int); const char *aid2str(uint8_t); int aid2afi(uint8_t, uint16_t *, uint8_t *); int afi2aid(uint16_t, uint8_t, uint8_t *); Index: kroute.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v retrieving revision 1.259 diff -u -p -r1.259 kroute.c --- kroute.c 16 Jun 2022 15:36:36 -0000 1.259 +++ kroute.c 16 Jun 2022 17:02:39 -0000 @@ -127,15 +127,15 @@ int knexthop_compare(struct knexthop_nod int kredist_compare(struct kredist_node *, struct kredist_node *); int kif_compare(struct kif_node *, struct kif_node *); -struct kroute_node *kroute_find(struct ktable *, in_addr_t, uint8_t, - uint8_t); +struct kroute_node *kroute_find(struct ktable *, const struct bgpd_addr *, + uint8_t, uint8_t); struct kroute_node *kroute_matchgw(struct kroute_node *, struct bgpd_addr *); int kroute_insert(struct ktable *, struct kroute_node *); int kroute_remove(struct ktable *, struct kroute_node *); void kroute_clear(struct ktable *); -struct kroute6_node *kroute6_find(struct ktable *, const struct in6_addr *, +struct kroute6_node *kroute6_find(struct ktable *, const struct bgpd_addr *, uint8_t, uint8_t); struct kroute6_node *kroute6_matchgw(struct kroute6_node *, struct bgpd_addr *); @@ -495,7 +495,7 @@ kr4_change(struct ktable *kt, struct kro labelid = rtlabel_name2id(kl->label); - if ((kr = kroute_find(kt, kl->prefix.v4.s_addr, kl->prefixlen, + if ((kr = kroute_find(kt, &kl->prefix, kl->prefixlen, RTP_MINE)) != NULL) action = RTM_CHANGE; @@ -553,7 +553,7 @@ kr6_change(struct ktable *kt, struct kro labelid = rtlabel_name2id(kl->label); - if ((kr6 = kroute6_find(kt, &kl->prefix.v6, kl->prefixlen, + if ((kr6 = kroute6_find(kt, &kl->prefix, kl->prefixlen, RTP_MINE)) != NULL) action = RTM_CHANGE; @@ -626,7 +626,7 @@ krVPN4_change(struct ktable *kt, struct if (kl->flags & (F_BLACKHOLE|F_REJECT)) kl->nexthop.v4.s_addr = htonl(INADDR_LOOPBACK); - if ((kr = kroute_find(kt, kl->prefix.v4.s_addr, kl->prefixlen, + if ((kr = kroute_find(kt, &kl->prefix, kl->prefixlen, RTP_MINE)) != NULL) action = RTM_CHANGE; @@ -700,7 +700,7 @@ krVPN6_change(struct ktable *kt, struct labelid = rtlabel_name2id(kl->label); - if ((kr6 = kroute6_find(kt, &kl->prefix.v6, kl->prefixlen, + if ((kr6 = kroute6_find(kt, &kl->prefix, kl->prefixlen, RTP_MINE)) != NULL) action = RTM_CHANGE; @@ -806,7 +806,7 @@ kr4_delete(struct ktable *kt, struct kro { struct kroute_node *kr; - if ((kr = kroute_find(kt, kl->prefix.v4.s_addr, kl->prefixlen, + if ((kr = kroute_find(kt, &kl->prefix, kl->prefixlen, RTP_MINE)) == NULL) return (0); @@ -826,7 +826,7 @@ kr6_delete(struct ktable *kt, struct kro { struct kroute6_node *kr6; - if ((kr6 = kroute6_find(kt, &kl->prefix.v6, kl->prefixlen, + if ((kr6 = kroute6_find(kt, &kl->prefix, kl->prefixlen, RTP_MINE)) == NULL) return (0); @@ -846,7 +846,7 @@ krVPN4_delete(struct ktable *kt, struct { struct kroute_node *kr; - if ((kr = kroute_find(kt, kl->prefix.v4.s_addr, kl->prefixlen, + if ((kr = kroute_find(kt, &kl->prefix, kl->prefixlen, RTP_MINE)) == NULL) return (0); @@ -866,7 +866,7 @@ krVPN6_delete(struct ktable *kt, struct { struct kroute6_node *kr6; - if ((kr6 = kroute6_find(kt, &kl->prefix.v6, kl->prefixlen, + if ((kr6 = kroute6_find(kt, &kl->prefix, kl->prefixlen, RTP_MINE)) == NULL) return (0); @@ -1749,13 +1749,13 @@ kif_compare(struct kif_node *a, struct k */ struct kroute_node * -kroute_find(struct ktable *kt, in_addr_t prefix, uint8_t prefixlen, - uint8_t prio) +kroute_find(struct ktable *kt, const struct bgpd_addr *prefix, + uint8_t prefixlen, uint8_t prio) { struct kroute_node s; struct kroute_node *kn, *tmp; - s.r.prefix.s_addr = prefix; + s.r.prefix= prefix->v4; s.r.prefixlen = prefixlen; s.r.priority = prio; @@ -1904,13 +1904,13 @@ kroute_clear(struct ktable *kt) } struct kroute6_node * -kroute6_find(struct ktable *kt, const struct in6_addr *prefix, +kroute6_find(struct ktable *kt, const struct bgpd_addr *prefix, uint8_t prefixlen, uint8_t prio) { struct kroute6_node s; struct kroute6_node *kn6, *tmp; - memcpy(&s.r.prefix, prefix, sizeof(struct in6_addr)); + s.r.prefix = prefix->v6; s.r.prefixlen = prefixlen; s.r.priority = prio; @@ -2488,21 +2488,16 @@ kroute_match(struct ktable *kt, struct b { int i; struct kroute_node *kr; - struct in_addr ina; + struct bgpd_addr masked; /* this will never match the default route */ - for (i = 32; i > 0; i--) { - inet4applymask(&ina, &key->v4, i); - if ((kr = kroute_find(kt, ina.s_addr, i, RTP_ANY)) != NULL) + for (i = 32; i >= 0; i--) { + applymask(&masked, key, i); + if ((kr = kroute_find(kt, &masked, i, RTP_ANY)) != NULL) if (matchall || bgpd_filternexthop(&kr->r, NULL) == 0) return (kr); } - /* so if there is no match yet, lookup the default route */ - if ((kr = kroute_find(kt, 0, 0, RTP_ANY)) != NULL) - if (matchall || bgpd_filternexthop(&kr->r, NULL) == 0) - return (kr); - return (NULL); } @@ -2511,21 +2506,16 @@ kroute6_match(struct ktable *kt, struct { int i; struct kroute6_node *kr6; - struct in6_addr ina; + struct bgpd_addr masked; /* this will never match the default route */ - for (i = 128; i > 0; i--) { - inet6applymask(&ina, &key->v6, i); - if ((kr6 = kroute6_find(kt, &ina, i, RTP_ANY)) != NULL) + for (i = 128; i >= 0; i--) { + applymask(&masked, key, i); + if ((kr6 = kroute6_find(kt, &masked, i, RTP_ANY)) != NULL) if (matchall || bgpd_filternexthop(NULL, &kr6->r) == 0) return (kr6); } - /* so if there is no match yet, lookup the default route */ - if ((kr6 = kroute6_find(kt, &in6addr_any, 0, RTP_ANY)) != NULL) - if (matchall || bgpd_filternexthop(NULL, &kr6->r) == 0) - return (kr6); - return (NULL); } @@ -3467,8 +3457,8 @@ kr_fib_delete(struct ktable *kt, struct switch (kl->prefix.aid) { case AID_INET: - if ((kr = kroute_find(kt, kl->prefix.v4.s_addr, - kl->prefixlen, kl->priority)) == NULL) + if ((kr = kroute_find(kt, &kl->prefix, kl->prefixlen, + kl->priority)) == NULL) return (0); if (!(kr->r.flags & F_KERNEL)) return (0); @@ -3485,7 +3475,7 @@ kr_fib_delete(struct ktable *kt, struct return (-1); break; case AID_INET6: - if ((kr6 = kroute6_find(kt, &kl->prefix.v6, kl->prefixlen, + if ((kr6 = kroute6_find(kt, &kl->prefix, kl->prefixlen, kl->priority)) == NULL) return (0); if (!(kr6->r.flags & F_KERNEL)) @@ -3519,7 +3509,7 @@ kr_fib_change(struct ktable *kt, struct flags = kl->flags; switch (kl->prefix.aid) { case AID_INET: - if ((kr = kroute_find(kt, kl->prefix.v4.s_addr, kl->prefixlen, + if ((kr = kroute_find(kt, &kl->prefix, kl->prefixlen, kl->priority)) != NULL) { if (kr->r.flags & F_KERNEL) { /* get the correct route */ @@ -3599,7 +3589,7 @@ add4: } break; case AID_INET6: - if ((kr6 = kroute6_find(kt, &kl->prefix.v6, kl->prefixlen, + if ((kr6 = kroute6_find(kt, &kl->prefix, kl->prefixlen, kl->priority)) != NULL) { if (kr6->r.flags & F_KERNEL) { /* get the correct route */ Index: session.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/session.c,v retrieving revision 1.427 diff -u -p -r1.427 session.c --- session.c 23 Feb 2022 11:20:35 -0000 1.427 +++ session.c 16 Jun 2022 16:55:58 -0000 @@ -3382,23 +3382,11 @@ session_template_clone(struct peer *p, s int session_match_mask(struct peer *p, struct bgpd_addr *a) { - struct in_addr v4masked; - struct in6_addr v6masked; + struct bgpd_addr masked; - switch (p->conf.remote_addr.aid) { - case AID_INET: - inet4applymask(&v4masked, &a->v4, p->conf.remote_masklen); - if (p->conf.remote_addr.v4.s_addr == v4masked.s_addr) - return (1); - return (0); - case AID_INET6: - inet6applymask(&v6masked, &a->v6, p->conf.remote_masklen); - - if (memcmp(&v6masked, &p->conf.remote_addr.v6, - sizeof(v6masked)) == 0) - return (1); - return (0); - } + applymask(&masked, a, p->conf.remote_masklen); + if (memcmp(&masked, &p->conf.remote_addr, sizeof(masked)) == 0) + return (1); return (0); } Index: util.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/util.c,v retrieving revision 1.64 diff -u -p -r1.64 util.c --- util.c 16 Jun 2022 15:33:05 -0000 1.64 +++ util.c 16 Jun 2022 16:50:47 -0000 @@ -783,6 +783,26 @@ inet6applymask(struct in6_addr *dest, co dest->s6_addr[i] = src->s6_addr[i] & mask.s6_addr[i]; } +void +applymask(struct bgpd_addr *dest, const struct bgpd_addr *src, int prefixlen) +{ + struct bgpd_addr tmp; + + /* use temporary storage in case src and dest point to same struct */ + tmp = *src; + switch (src->aid) { + case AID_INET: + case AID_VPN_IPv4: + inet4applymask(&tmp.v4, &src->v4, prefixlen); + break; + case AID_INET6: + case AID_VPN_IPv6: + inet6applymask(&tmp.v6, &src->v6, prefixlen); + break; + } + *dest = tmp; +} + /* address family translation functions */ const struct aid aid_vals[AID_MAX] = AID_VALS;