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;