This diff kills external use of prefixlen2mask() and uses inet4applymask()
instead. With this the IPv4 and IPv6 code is more similar.
Also I feel the code is a bit easier to read.
Also kroute{,6}_match() is changed to take a struct bgpd_addr *.
This is another step towards removing lots of copy paste code.
Next step will be to change kroute{,6}_find() to use struct bgpd_addr *.
--
:wq Claudio
Index: usr.sbin/bgpctl/parser.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/parser.c,v
retrieving revision 1.109
diff -u -p -r1.109 parser.c
--- usr.sbin/bgpctl/parser.c 21 Mar 2022 10:16:23 -0000 1.109
+++ usr.sbin/bgpctl/parser.c 16 Jun 2022 12:28:59 -0000
@@ -968,7 +968,7 @@ parse_prefix(const char *word, size_t wo
mask = 32;
if (mask > 32)
errx(1, "invalid netmask: too large");
- addr->v4.s_addr = addr->v4.s_addr & htonl(prefixlen2mask(mask));
+ inet4applymask(&addr->v4, &addr->v4, mask);
break;
case AID_INET6:
if (mask == -1)
Index: usr.sbin/bgpd/bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.428
diff -u -p -r1.428 bgpd.h
--- usr.sbin/bgpd/bgpd.h 9 Jun 2022 16:45:19 -0000 1.428
+++ usr.sbin/bgpd/bgpd.h 16 Jun 2022 12:28:59 -0000
@@ -1304,7 +1304,6 @@ void kr_show_route(struct imsg *);
void kr_ifinfo(char *);
void kr_net_reload(u_int, uint64_t, struct network_head *);
int kr_reload(void);
-struct in6_addr *prefixlen2mask6(uint8_t prefixlen);
int get_mpe_config(const char *, u_int *, u_int *);
/* log.c */
@@ -1422,7 +1421,6 @@ int nlri_get_vpn6(u_char *, uint16_t,
uint8_t *, int);
int prefix_compare(const struct bgpd_addr *,
const struct bgpd_addr *, int);
-in_addr_t prefixlen2mask(uint8_t);
void inet4applymask(struct in_addr *, const struct in_addr *, int);
void inet6applymask(struct in6_addr *, const struct in6_addr *,
int);
Index: usr.sbin/bgpd/kroute.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v
retrieving revision 1.255
diff -u -p -r1.255 kroute.c
--- usr.sbin/bgpd/kroute.c 14 Jun 2022 14:06:48 -0000 1.255
+++ usr.sbin/bgpd/kroute.c 16 Jun 2022 12:28:59 -0000
@@ -167,8 +167,9 @@ void knexthop_validate(struct
ktable
struct knexthop_node *);
void knexthop_track(struct ktable *, void *);
void knexthop_send_update(struct knexthop_node *);
-struct kroute_node *kroute_match(struct ktable *, in_addr_t, int);
-struct kroute6_node *kroute6_match(struct ktable *, struct in6_addr *, int);
+struct kroute_node *kroute_match(struct ktable *, struct bgpd_addr *, int);
+struct kroute6_node *kroute6_match(struct ktable *, struct bgpd_addr *,
+ int);
void kroute_detach_nexthop(struct ktable *,
struct knexthop_node *);
@@ -210,6 +211,12 @@ RB_GENERATE(kif_tree, kif_node, entry, k
#define KT2KNT(x) (&(ktable_get((x)->nhtableid)->knt))
+const struct in_addr inet4allone = { INADDR_BROADCAST };
+const struct in6_addr inet6allone = {{{ 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff }}};
+
+
/*
* exported functions
*/
@@ -1112,14 +1119,14 @@ kr_show_route(struct imsg *imsg)
kr = NULL;
switch (addr->aid) {
case AID_INET:
- kr = kroute_match(kt, addr->v4.s_addr, 1);
+ kr = kroute_match(kt, addr, 1);
if (kr != NULL)
send_imsg_session(IMSG_CTL_KROUTE,
imsg->hdr.pid, kr_tofull(&kr->r),
sizeof(struct kroute_full));
break;
case AID_INET6:
- kr6 = kroute6_match(kt, &addr->v6, 1);
+ kr6 = kroute6_match(kt, addr, 1);
if (kr6 != NULL)
send_imsg_session(IMSG_CTL_KROUTE,
imsg->hdr.pid, kr6_tofull(&kr6->r),
@@ -1800,7 +1807,7 @@ kroute_insert(struct ktable *kt, struct
{
struct kroute_node *krm;
struct knexthop_node *h;
- in_addr_t mask, ina;
+ struct in_addr ina, inb;
if ((krm = RB_INSERT(kroute_tree, &kt->krt, kr)) != NULL) {
/* multipath route, add at end of list */
@@ -1812,12 +1819,14 @@ kroute_insert(struct ktable *kt, struct
/* XXX this is wrong for nexthop validated via BGP */
if (kr->r.flags & F_KERNEL) {
- mask = prefixlen2mask(kr->r.prefixlen);
- ina = ntohl(kr->r.prefix.s_addr);
+ inet4applymask(&ina, &kr->r.prefix, kr->r.prefixlen);
RB_FOREACH(h, knexthop_tree, KT2KNT(kt))
- if (h->nexthop.aid == AID_INET &&
- (ntohl(h->nexthop.v4.s_addr) & mask) == ina)
- knexthop_validate(kt, h);
+ if (h->nexthop.aid == AID_INET) {
+ inet4applymask(&inb, &h->nexthop.v4,
+ kr->r.prefixlen);
+ if (memcmp(&ina, &inb, sizeof(ina)) == 0)
+ knexthop_validate(kt, h);
+ }
if (kr->r.flags & F_CONNECTED)
if (kif_kr_insert(kr) == -1)
@@ -2392,7 +2401,7 @@ knexthop_validate(struct ktable *kt, str
switch (kn->nexthop.aid) {
case AID_INET:
- kr = kroute_match(kt, kn->nexthop.v4.s_addr, 0);
+ kr = kroute_match(kt, &kn->nexthop, 0);
if (kr) {
kn->kroute = kr;
@@ -2408,7 +2417,7 @@ knexthop_validate(struct ktable *kt, str
knexthop_send_update(kn);
break;
case AID_INET6:
- kr6 = kroute6_match(kt, &kn->nexthop.v6, 0);
+ kr6 = kroute6_match(kt, &kn->nexthop, 0);
if (kr6) {
kn->kroute = kr6;
@@ -2484,20 +2493,19 @@ knexthop_send_update(struct knexthop_nod
}
struct kroute_node *
-kroute_match(struct ktable *kt, in_addr_t key, int matchall)
+kroute_match(struct ktable *kt, struct bgpd_addr *key, int matchall)
{
int i;
struct kroute_node *kr;
- in_addr_t ina;
-
- ina = ntohl(key);
+ struct in_addr ina;
/* this will never match the default route */
- for (i = 32; i > 0; i--)
- if ((kr = kroute_find(kt, htonl(ina & prefixlen2mask(i)), i,
- RTP_ANY)) != NULL)
+ for (i = 32; i > 0; i--) {
+ inet4applymask(&ina, &key->v4, i);
+ if ((kr = kroute_find(kt, ina.s_addr, 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)
@@ -2508,7 +2516,7 @@ kroute_match(struct ktable *kt, in_addr_
}
struct kroute6_node *
-kroute6_match(struct ktable *kt, struct in6_addr *key, int matchall)
+kroute6_match(struct ktable *kt, struct bgpd_addr *key, int matchall)
{
int i;
struct kroute6_node *kr6;
@@ -2516,7 +2524,7 @@ kroute6_match(struct ktable *kt, struct
/* this will never match the default route */
for (i = 128; i > 0; i--) {
- inet6applymask(&ina, key, i);
+ inet6applymask(&ina, &key->v6, i);
if ((kr6 = kroute6_find(kt, &ina, i, RTP_ANY)) != NULL)
if (matchall || bgpd_filternexthop(NULL, &kr6->r) == 0)
return (kr6);
@@ -2679,22 +2687,6 @@ mask2prefixlen6(struct sockaddr_in6 *sa_
return (l);
}
-struct in6_addr *
-prefixlen2mask6(uint8_t prefixlen)
-{
- static struct in6_addr mask;
- int i;
-
- bzero(&mask, sizeof(mask));
- for (i = 0; i < prefixlen / 8; i++)
- mask.s6_addr[i] = 0xff;
- i = prefixlen % 8;
- if (i)
- mask.s6_addr[prefixlen / 8] = 0xff00 >> i;
-
- return (&mask);
-}
-
const struct if_status_description
if_status_descriptions[] = LINK_STATE_DESCRIPTIONS;
const struct ifmedia_description
@@ -2956,7 +2948,7 @@ send_rtmsg(int fd, int action, struct kt
bzero(&mask, sizeof(mask));
mask.sin_len = sizeof(mask);
mask.sin_family = AF_INET;
- mask.sin_addr.s_addr = htonl(prefixlen2mask(kroute->prefixlen));
+ inet4applymask(&mask.sin_addr, &inet4allone, kroute->prefixlen);
/* adjust header */
hdr.rtm_addrs |= RTA_NETMASK;
hdr.rtm_msglen += sizeof(mask);
@@ -3096,8 +3088,7 @@ send_rt6msg(int fd, int action, struct k
bzero(&mask, sizeof(mask));
mask.addr.sin6_len = sizeof(struct sockaddr_in6);
mask.addr.sin6_family = AF_INET6;
- memcpy(&mask.addr.sin6_addr, prefixlen2mask6(kroute->prefixlen),
- sizeof(struct in6_addr));
+ inet6applymask(&mask.addr.sin6_addr, &inet6allone, kroute->prefixlen);
/* adjust header */
hdr.rtm_addrs |= RTA_NETMASK;
hdr.rtm_msglen += ROUNDUP(sizeof(struct sockaddr_in6));
Index: usr.sbin/bgpd/util.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/util.c,v
retrieving revision 1.63
diff -u -p -r1.63 util.c
--- usr.sbin/bgpd/util.c 25 May 2022 16:03:34 -0000 1.63
+++ usr.sbin/bgpd/util.c 16 Jun 2022 12:29:21 -0000
@@ -675,7 +675,14 @@ nlri_get_vpn6(u_char *p, uint16_t len, s
return (plen + rv);
}
+static in_addr_t
+prefixlen2mask(uint8_t prefixlen)
+{
+ if (prefixlen == 0)
+ return (0);
+ return (0xffffffff << (32 - prefixlen));
+}
/*
* This function will have undefined behaviour if the passed in prefixlen is
@@ -748,15 +755,6 @@ prefix_compare(const struct bgpd_addr *a
}
return (0);
-}
-
-in_addr_t
-prefixlen2mask(uint8_t prefixlen)
-{
- if (prefixlen == 0)
- return (0);
-
- return (0xffffffff << (32 - prefixlen));
}
void