While changing log_addr() I noticed that struct bgpd_addr could benefit
from changing the encoding of AID_VPN_IPv4 and AID_VPN_IPv6 addrs.
Instead of having independent route distinguishers and labelstacks use
common fields for those and use the v4 and v6 addresses for the prefix.
This is a bit more compact but also simplifies some code since the
handling of AID_VPN_IPv4 and AID_VPN_IPv6 can be handled in the same
switch case.
I reduced the labelstack size from 21 to 18 (6 instead of 7 labels). Now
in theory you could pack 7 labels into an IPv4 VPN NLRI (8bit prefixlen +
64bit RD + 16bit prefix + 21 * 8bit label = 256) but that is quite silly.
Even 6 labels is more than enough. bgpd itself only allows a single MPLS
label when announcing such networks.
--
:wq Claudio
PS: diff is based of /usr/src/usr.sbin
Index: bgpctl/mrtparser.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/mrtparser.c,v
retrieving revision 1.13
diff -u -p -r1.13 mrtparser.c
--- bgpctl/mrtparser.c 3 Jul 2019 06:22:01 -0000 1.13
+++ bgpctl/mrtparser.c 5 Jan 2021 10:05:30 -0000
@@ -833,14 +833,14 @@ mrt_extract_attr(struct mrt_rib_entry *r
re->nexthop.aid = aid;
memcpy(&tmp, a + 1 + sizeof(u_int64_t),
sizeof(tmp));
- re->nexthop.vpn4.addr.s_addr = tmp;
+ re->nexthop.v4.s_addr = tmp;
break;
case AID_VPN_IPv6:
if (attr_len < sizeof(u_int64_t) +
sizeof(struct in6_addr))
return (-1);
re->nexthop.aid = aid;
- memcpy(&re->nexthop.vpn6.addr,
+ memcpy(&re->nexthop.v6,
a + 1 + sizeof(u_int64_t),
sizeof(struct in6_addr));
break;
@@ -979,7 +979,7 @@ mrt_extract_addr(void *msg, u_int len, s
return (-1);
addr->aid = aid;
/* XXX labelstack and rd missing */
- memcpy(&addr->vpn4.addr, b + sizeof(u_int64_t),
+ memcpy(&addr->v4, b + sizeof(u_int64_t),
sizeof(struct in_addr));
return (sizeof(u_int64_t) + sizeof(struct in_addr));
case AID_VPN_IPv6:
@@ -987,7 +987,7 @@ mrt_extract_addr(void *msg, u_int len, s
return (-1);
addr->aid = aid;
/* XXX labelstack and rd missing */
- memcpy(&addr->vpn6.addr, b + sizeof(u_int64_t),
+ memcpy(&addr->v6, b + sizeof(u_int64_t),
sizeof(struct in6_addr));
return (sizeof(u_int64_t) + sizeof(struct in6_addr));
default:
Index: bgpd/bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.409
diff -u -p -r1.409 bgpd.h
--- bgpd/bgpd.h 4 Jan 2021 13:40:32 -0000 1.409
+++ bgpd/bgpd.h 5 Jan 2021 10:05:30 -0000
@@ -176,23 +176,6 @@ extern const struct aid aid_vals[];
sizeof(struct pt_entry_vpn6) \
}
-struct vpn4_addr {
- u_int64_t rd;
- struct in_addr addr;
- u_int8_t labelstack[21]; /* max that makes sense */
- u_int8_t labellen;
- u_int8_t pad1;
- u_int8_t pad2;
-};
-
-struct vpn6_addr {
- u_int64_t rd;
- struct in6_addr addr;
- u_int8_t labelstack[21]; /* max that makes sense */
- u_int8_t labellen;
- u_int8_t pad1;
- u_int8_t pad2;
-};
#define BGP_MPLS_BOS 0x01
@@ -200,22 +183,15 @@ struct bgpd_addr {
union {
struct in_addr v4;
struct in6_addr v6;
- struct vpn4_addr vpn4;
- struct vpn6_addr vpn6;
/* maximum size for a prefix is 256 bits */
- u_int8_t addr8[32];
- u_int16_t addr16[16];
- u_int32_t addr32[8];
} ba; /* 128-bit address */
+ u_int64_t rd; /* route distinguisher for VPN addrs */
u_int32_t scope_id; /* iface scope id for v6 */
u_int8_t aid;
+ u_int8_t labellen; /* size of the labelstack */
+ u_int8_t labelstack[18]; /* max that makes sense */
#define v4 ba.v4
#define v6 ba.v6
-#define vpn4 ba.vpn4
-#define vpn6 ba.vpn6
-#define addr8 ba.addr8
-#define addr16 ba.addr16
-#define addr32 ba.addr32
};
#define DEFAULT_LISTENER 0x01
Index: bgpd/kroute.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v
retrieving revision 1.240
diff -u -p -r1.240 kroute.c
--- bgpd/kroute.c 29 Dec 2020 09:20:25 -0000 1.240
+++ bgpd/kroute.c 5 Jan 2021 10:05:30 -0000
@@ -601,14 +601,14 @@ krVPN4_change(struct ktable *kt, struct
return (0);
/* only single MPLS label are supported for now */
- if (kl->prefix.vpn4.labellen != 3) {
+ if (kl->prefix.labellen != 3) {
log_warnx("%s: %s/%u has not a single label", __func__,
log_addr(&kl->prefix), kl->prefixlen);
return (0);
}
- mplslabel = (kl->prefix.vpn4.labelstack[0] << 24) |
- (kl->prefix.vpn4.labelstack[1] << 16) |
- (kl->prefix.vpn4.labelstack[2] << 8);
+ mplslabel = (kl->prefix.labelstack[0] << 24) |
+ (kl->prefix.labelstack[1] << 16) |
+ (kl->prefix.labelstack[2] << 8);
mplslabel = htonl(mplslabel);
labelid = rtlabel_name2id(kl->label);
@@ -617,7 +617,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.vpn4.addr.s_addr, kl->prefixlen,
+ if ((kr = kroute_find(kt, kl->prefix.v4.s_addr, kl->prefixlen,
fib_prio)) != NULL)
action = RTM_CHANGE;
@@ -626,7 +626,7 @@ krVPN4_change(struct ktable *kt, struct
log_warn("%s", __func__);
return (-1);
}
- kr->r.prefix.s_addr = kl->prefix.vpn4.addr.s_addr;
+ kr->r.prefix.s_addr = kl->prefix.v4.s_addr;
kr->r.prefixlen = kl->prefixlen;
kr->r.nexthop.s_addr = kl->nexthop.v4.s_addr;
kr->r.flags = kl->flags | F_BGPD_INSERTED | F_MPLS;
@@ -675,14 +675,14 @@ krVPN6_change(struct ktable *kt, struct
return (0);
/* only single MPLS label are supported for now */
- if (kl->prefix.vpn6.labellen != 3) {
+ if (kl->prefix.labellen != 3) {
log_warnx("%s: %s/%u has not a single label", __func__,
log_addr(&kl->prefix), kl->prefixlen);
return (0);
}
- mplslabel = (kl->prefix.vpn6.labelstack[0] << 24) |
- (kl->prefix.vpn6.labelstack[1] << 16) |
- (kl->prefix.vpn6.labelstack[2] << 8);
+ mplslabel = (kl->prefix.labelstack[0] << 24) |
+ (kl->prefix.labelstack[1] << 16) |
+ (kl->prefix.labelstack[2] << 8);
mplslabel = htonl(mplslabel);
/* for blackhole and reject routes nexthop needs to be ::1 */
@@ -691,7 +691,7 @@ krVPN6_change(struct ktable *kt, struct
labelid = rtlabel_name2id(kl->label);
- if ((kr6 = kroute6_find(kt, &kl->prefix.vpn6.addr, kl->prefixlen,
+ if ((kr6 = kroute6_find(kt, &kl->prefix.v6, kl->prefixlen,
fib_prio)) != NULL)
action = RTM_CHANGE;
@@ -700,8 +700,7 @@ krVPN6_change(struct ktable *kt, struct
log_warn("%s", __func__);
return (-1);
}
- memcpy(&kr6->r.prefix, &kl->prefix.vpn6.addr,
- sizeof(struct in6_addr));
+ memcpy(&kr6->r.prefix, &kl->prefix.v6, sizeof(struct in6_addr));
kr6->r.prefixlen = kl->prefixlen;
memcpy(&kr6->r.nexthop, &kl->nexthop.v6,
sizeof(struct in6_addr));
@@ -848,7 +847,7 @@ krVPN4_delete(struct ktable *kt, struct
{
struct kroute_node *kr;
- if ((kr = kroute_find(kt, kl->prefix.vpn4.addr.s_addr, kl->prefixlen,
+ if ((kr = kroute_find(kt, kl->prefix.v4.s_addr, kl->prefixlen,
fib_prio)) == NULL)
return (0);
@@ -871,7 +870,7 @@ krVPN6_delete(struct ktable *kt, struct
{
struct kroute6_node *kr6;
- if ((kr6 = kroute6_find(kt, &kl->prefix.vpn6.addr, kl->prefixlen,
+ if ((kr6 = kroute6_find(kt, &kl->prefix.v6, kl->prefixlen,
fib_prio)) == NULL)
return (0);
Index: bgpd/rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.510
diff -u -p -r1.510 rde.c
--- bgpd/rde.c 30 Dec 2020 07:29:56 -0000 1.510
+++ bgpd/rde.c 5 Jan 2021 10:05:31 -0000
@@ -3642,7 +3642,7 @@ network_add(struct network_config *nc, s
{
struct l3vpn *vpn;
struct filter_set_head *vpnset = NULL;
- in_addr_t prefix4;
+ struct in_addr prefix4;
struct in6_addr prefix6;
u_int8_t vstate;
u_int16_t i;
@@ -3653,37 +3653,35 @@ network_add(struct network_config *nc, s
continue;
switch (nc->prefix.aid) {
case AID_INET:
- prefix4 = nc->prefix.v4.s_addr;
- bzero(&nc->prefix, sizeof(nc->prefix));
+ prefix4 = nc->prefix.v4;
+ memset(&nc->prefix, 0, sizeof(nc->prefix));
nc->prefix.aid = AID_VPN_IPv4;
- nc->prefix.vpn4.rd = vpn->rd;
- nc->prefix.vpn4.addr.s_addr = prefix4;
- nc->prefix.vpn4.labellen = 3;
- nc->prefix.vpn4.labelstack[0] =
+ nc->prefix.rd = vpn->rd;
+ nc->prefix.v4 = prefix4;
+ nc->prefix.labellen = 3;
+ nc->prefix.labelstack[0] =
(vpn->label >> 12) & 0xff;
- nc->prefix.vpn4.labelstack[1] =
+ nc->prefix.labelstack[1] =
(vpn->label >> 4) & 0xff;
- nc->prefix.vpn4.labelstack[2] =
+ nc->prefix.labelstack[2] =
(vpn->label << 4) & 0xf0;
- nc->prefix.vpn4.labelstack[2] |= BGP_MPLS_BOS;
+ nc->prefix.labelstack[2] |= BGP_MPLS_BOS;
vpnset = &vpn->export;
break;
case AID_INET6:
- memcpy(&prefix6, &nc->prefix.v6.s6_addr,
- sizeof(struct in6_addr));
+ prefix6 = nc->prefix.v6;
memset(&nc->prefix, 0, sizeof(nc->prefix));
nc->prefix.aid = AID_VPN_IPv6;
- nc->prefix.vpn6.rd = vpn->rd;
- memcpy(&nc->prefix.vpn6.addr.s6_addr, &prefix6,
- sizeof(struct in6_addr));
- nc->prefix.vpn6.labellen = 3;
- nc->prefix.vpn6.labelstack[0] =
+ nc->prefix.rd = vpn->rd;
+ nc->prefix.v6 = prefix6;
+ nc->prefix.labellen = 3;
+ nc->prefix.labelstack[0] =
(vpn->label >> 12) & 0xff;
- nc->prefix.vpn6.labelstack[1] =
+ nc->prefix.labelstack[1] =
(vpn->label >> 4) & 0xff;
- nc->prefix.vpn6.labelstack[2] =
+ nc->prefix.labelstack[2] =
(vpn->label << 4) & 0xf0;
- nc->prefix.vpn6.labelstack[2] |= BGP_MPLS_BOS;
+ nc->prefix.labelstack[2] |= BGP_MPLS_BOS;
vpnset = &vpn->export;
break;
default:
@@ -3729,7 +3727,7 @@ void
network_delete(struct network_config *nc)
{
struct l3vpn *vpn;
- in_addr_t prefix4;
+ struct in_addr prefix4;
struct in6_addr prefix6;
u_int32_t i;
@@ -3739,36 +3737,34 @@ network_delete(struct network_config *nc
continue;
switch (nc->prefix.aid) {
case AID_INET:
- prefix4 = nc->prefix.v4.s_addr;
- bzero(&nc->prefix, sizeof(nc->prefix));
+ prefix4 = nc->prefix.v4;
+ memset(&nc->prefix, 0, sizeof(nc->prefix));
nc->prefix.aid = AID_VPN_IPv4;
- nc->prefix.vpn4.rd = vpn->rd;
- nc->prefix.vpn4.addr.s_addr = prefix4;
- nc->prefix.vpn4.labellen = 3;
- nc->prefix.vpn4.labelstack[0] =
+ nc->prefix.rd = vpn->rd;
+ nc->prefix.v4 = prefix4;
+ nc->prefix.labellen = 3;
+ nc->prefix.labelstack[0] =
(vpn->label >> 12) & 0xff;
- nc->prefix.vpn4.labelstack[1] =
+ nc->prefix.labelstack[1] =
(vpn->label >> 4) & 0xff;
- nc->prefix.vpn4.labelstack[2] =
+ nc->prefix.labelstack[2] =
(vpn->label << 4) & 0xf0;
- nc->prefix.vpn4.labelstack[2] |= BGP_MPLS_BOS;
+ nc->prefix.labelstack[2] |= BGP_MPLS_BOS;
break;
case AID_INET6:
- memcpy(&prefix6, &nc->prefix.v6.s6_addr,
- sizeof(struct in6_addr));
+ prefix6 = nc->prefix.v6;
memset(&nc->prefix, 0, sizeof(nc->prefix));
nc->prefix.aid = AID_VPN_IPv6;
- nc->prefix.vpn6.rd = vpn->rd;
- memcpy(&nc->prefix.vpn6.addr.s6_addr, &prefix6,
- sizeof(struct in6_addr));
- nc->prefix.vpn6.labellen = 3;
- nc->prefix.vpn6.labelstack[0] =
+ nc->prefix.rd = vpn->rd;
+ nc->prefix.v6 = prefix6;
+ nc->prefix.labellen = 3;
+ nc->prefix.labelstack[0] =
(vpn->label >> 12) & 0xff;
- nc->prefix.vpn6.labelstack[1] =
+ nc->prefix.labelstack[1] =
(vpn->label >> 4) & 0xff;
- nc->prefix.vpn6.labelstack[2] =
+ nc->prefix.labelstack[2] =
(vpn->label << 4) & 0xf0;
- nc->prefix.vpn6.labelstack[2] |= BGP_MPLS_BOS;
+ nc->prefix.labelstack[2] |= BGP_MPLS_BOS;
break;
default:
log_warnx("unable to VPNize prefix");
Index: bgpd/rde_prefix.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_prefix.c,v
retrieving revision 1.39
diff -u -p -r1.39 rde_prefix.c
--- bgpd/rde_prefix.c 1 Jul 2019 07:07:08 -0000 1.39
+++ bgpd/rde_prefix.c 5 Jan 2021 10:05:31 -0000
@@ -79,27 +79,24 @@ pt_getaddr(struct pt_entry *pte, struct
addr->v4 = ((struct pt_entry4 *)pte)->prefix4;
break;
case AID_INET6:
- memcpy(&addr->v6, &((struct pt_entry6 *)pte)->prefix6,
- sizeof(addr->v6));
+ addr->v6 = ((struct pt_entry6 *)pte)->prefix6;
/* XXX scope_id ??? */
break;
case AID_VPN_IPv4:
- addr->vpn4.addr = ((struct pt_entry_vpn4 *)pte)->prefix4;
- addr->vpn4.rd = ((struct pt_entry_vpn4 *)pte)->rd;
- addr->vpn4.labellen = ((struct pt_entry_vpn4 *)pte)->labellen;
- memcpy(addr->vpn4.labelstack,
+ addr->v4 = ((struct pt_entry_vpn4 *)pte)->prefix4;
+ addr->rd = ((struct pt_entry_vpn4 *)pte)->rd;
+ addr->labellen = ((struct pt_entry_vpn4 *)pte)->labellen;
+ memcpy(addr->labelstack,
((struct pt_entry_vpn4 *)pte)->labelstack,
- addr->vpn4.labellen);
+ addr->labellen);
break;
case AID_VPN_IPv6:
- memcpy(&addr->vpn6.addr,
- &((struct pt_entry_vpn6 *)pte)->prefix6,
- sizeof(addr->vpn6.addr));
- addr->vpn6.rd = ((struct pt_entry_vpn6 *)pte)->rd;
- addr->vpn6.labellen = ((struct pt_entry_vpn6 *)pte)->labellen;
- memcpy(addr->vpn6.labelstack,
+ addr->v6 = ((struct pt_entry_vpn6 *)pte)->prefix6;
+ addr->rd = ((struct pt_entry_vpn6 *)pte)->rd;
+ addr->labellen = ((struct pt_entry_vpn6 *)pte)->labellen;
+ memcpy(addr->labelstack,
((struct pt_entry_vpn6 *)pte)->labelstack,
- addr->vpn6.labellen);
+ addr->labellen);
break;
default:
fatalx("pt_getaddr: unknown af");
@@ -136,26 +133,24 @@ pt_fill(struct bgpd_addr *prefix, int pr
pte_vpn4.aid = prefix->aid;
if (prefixlen > 32)
fatalx("pt_fill: bad IPv4 prefixlen");
- inet4applymask(&pte_vpn4.prefix4, &prefix->vpn4.addr,
- prefixlen);
+ inet4applymask(&pte_vpn4.prefix4, &prefix->v4, prefixlen);
pte_vpn4.prefixlen = prefixlen;
- pte_vpn4.rd = prefix->vpn4.rd;
- pte_vpn4.labellen = prefix->vpn4.labellen;
- memcpy(pte_vpn4.labelstack, prefix->vpn4.labelstack,
- prefix->vpn4.labellen);
+ pte_vpn4.rd = prefix->rd;
+ pte_vpn4.labellen = prefix->labellen;
+ memcpy(pte_vpn4.labelstack, prefix->labelstack,
+ prefix->labellen);
return ((struct pt_entry *)&pte_vpn4);
case AID_VPN_IPv6:
memset(&pte_vpn6, 0, sizeof(pte_vpn6));
pte_vpn6.aid = prefix->aid;
if (prefixlen > 128)
fatalx("pt_get: bad IPv6 prefixlen");
- inet6applymask(&pte_vpn6.prefix6, &prefix->vpn6.addr,
- prefixlen);
+ inet6applymask(&pte_vpn6.prefix6, &prefix->v6, prefixlen);
pte_vpn6.prefixlen = prefixlen;
- pte_vpn6.rd = prefix->vpn6.rd;
- pte_vpn6.labellen = prefix->vpn6.labellen;
- memcpy(pte_vpn6.labelstack, prefix->vpn6.labelstack,
- prefix->vpn6.labellen);
+ pte_vpn6.rd = prefix->rd;
+ pte_vpn6.labellen = prefix->labellen;
+ memcpy(pte_vpn6.labelstack, prefix->labelstack,
+ prefix->labellen);
return ((struct pt_entry *)&pte_vpn6);
default:
fatalx("pt_fill: unknown af");
Index: bgpd/rde_rib.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v
retrieving revision 1.218
diff -u -p -r1.218 rde_rib.c
--- bgpd/rde_rib.c 4 Dec 2020 11:57:13 -0000 1.218
+++ bgpd/rde_rib.c 5 Jan 2021 10:05:31 -0000
@@ -1417,47 +1417,19 @@ prefix_write(u_char *buf, int len, struc
memcpy(buf, &prefix->ba, totlen - 1);
return (totlen);
case AID_VPN_IPv4:
- totlen = PREFIX_SIZE(plen) + sizeof(prefix->vpn4.rd);
- psize = PREFIX_SIZE(plen) - 1;
- plen += sizeof(prefix->vpn4.rd) * 8;
- if (withdraw) {
- /* withdraw have one compat label as placeholder */
- totlen += 3;
- plen += 3 * 8;
- } else {
- totlen += prefix->vpn4.labellen;
- plen += prefix->vpn4.labellen * 8;
- }
-
- if (totlen > len)
- return (-1);
- *buf++ = plen;
- if (withdraw) {
- /* magic compatibility label as per rfc8277 */
- *buf++ = 0x80;
- *buf++ = 0x0;
- *buf++ = 0x0;
- } else {
- memcpy(buf, &prefix->vpn4.labelstack,
- prefix->vpn4.labellen);
- buf += prefix->vpn4.labellen;
- }
- memcpy(buf, &prefix->vpn4.rd, sizeof(prefix->vpn4.rd));
- buf += sizeof(prefix->vpn4.rd);
- memcpy(buf, &prefix->vpn4.addr, psize);
- return (totlen);
case AID_VPN_IPv6:
- totlen = PREFIX_SIZE(plen) + sizeof(prefix->vpn6.rd);
+ totlen = PREFIX_SIZE(plen) + sizeof(prefix->rd);
psize = PREFIX_SIZE(plen) - 1;
- plen += sizeof(prefix->vpn6.rd) * 8;
+ plen += sizeof(prefix->rd) * 8;
if (withdraw) {
/* withdraw have one compat label as placeholder */
totlen += 3;
plen += 3 * 8;
} else {
- totlen += prefix->vpn6.labellen;
- plen += prefix->vpn6.labellen * 8;
+ totlen += prefix->labellen;
+ plen += prefix->labellen * 8;
}
+
if (totlen > len)
return (-1);
*buf++ = plen;
@@ -1467,13 +1439,13 @@ prefix_write(u_char *buf, int len, struc
*buf++ = 0x0;
*buf++ = 0x0;
} else {
- memcpy(buf, &prefix->vpn6.labelstack,
- prefix->vpn6.labellen);
- buf += prefix->vpn6.labellen;
+ memcpy(buf, &prefix->labelstack,
+ prefix->labellen);
+ buf += prefix->labellen;
}
- memcpy(buf, &prefix->vpn6.rd, sizeof(prefix->vpn6.rd));
- buf += sizeof(prefix->vpn6.rd);
- memcpy(buf, &prefix->vpn6.addr, psize);
+ memcpy(buf, &prefix->rd, sizeof(prefix->rd));
+ buf += sizeof(prefix->rd);
+ memcpy(buf, &prefix->ba, psize);
return (totlen);
default:
return (-1);
@@ -1492,12 +1464,9 @@ prefix_writebuf(struct ibuf *buf, struct
totlen = PREFIX_SIZE(plen);
break;
case AID_VPN_IPv4:
- totlen = PREFIX_SIZE(plen) + sizeof(prefix->vpn4.rd) +
- prefix->vpn4.labellen;
- break;
case AID_VPN_IPv6:
- totlen = PREFIX_SIZE(plen) + sizeof(prefix->vpn6.rd) +
- prefix->vpn6.labellen;
+ totlen = PREFIX_SIZE(plen) + sizeof(prefix->rd) +
+ prefix->labellen;
break;
default:
return (-1);
Index: bgpd/util.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/util.c,v
retrieving revision 1.58
diff -u -p -r1.58 util.c
--- bgpd/util.c 5 Jan 2021 10:00:28 -0000 1.58
+++ bgpd/util.c 5 Jan 2021 10:05:31 -0000
@@ -47,11 +47,8 @@ log_addr(const struct bgpd_addr *addr)
case AID_INET6:
return log_sockaddr(sa, len);
case AID_VPN_IPv4:
- snprintf(buf, sizeof(buf), "%s %s", log_rd(addr->vpn4.rd),
- log_sockaddr(sa, len));
- return (buf);
case AID_VPN_IPv6:
- snprintf(buf, sizeof(buf), "%s %s", log_rd(addr->vpn6.rd),
+ snprintf(buf, sizeof(buf), "%s %s", log_rd(addr->rd),
log_sockaddr(sa, len));
return (buf);
}
@@ -532,8 +529,8 @@ nlri_get_vpn4(u_char *p, u_int16_t len,
do {
if (len - plen < 3 || pfxlen < 3 * 8)
return (-1);
- if (prefix->vpn4.labellen + 3U >
- sizeof(prefix->vpn4.labelstack))
+ if (prefix->labellen + 3U >
+ sizeof(prefix->labelstack))
return (-1);
if (withdraw) {
/* on withdraw ignore the labelstack all together */
@@ -541,13 +538,13 @@ nlri_get_vpn4(u_char *p, u_int16_t len,
pfxlen -= 3 * 8;
break;
}
- prefix->vpn4.labelstack[prefix->vpn4.labellen++] = *p++;
- prefix->vpn4.labelstack[prefix->vpn4.labellen++] = *p++;
- prefix->vpn4.labelstack[prefix->vpn4.labellen] = *p++;
- if (prefix->vpn4.labelstack[prefix->vpn4.labellen] &
+ prefix->labelstack[prefix->labellen++] = *p++;
+ prefix->labelstack[prefix->labellen++] = *p++;
+ prefix->labelstack[prefix->labellen] = *p++;
+ if (prefix->labelstack[prefix->labellen] &
BGP_MPLS_BOS)
done = 1;
- prefix->vpn4.labellen++;
+ prefix->labellen++;
plen += 3;
pfxlen -= 3 * 8;
} while (!done);
@@ -556,7 +553,7 @@ nlri_get_vpn4(u_char *p, u_int16_t len,
if (len - plen < (int)sizeof(u_int64_t) ||
pfxlen < sizeof(u_int64_t) * 8)
return (-1);
- memcpy(&prefix->vpn4.rd, p, sizeof(u_int64_t));
+ memcpy(&prefix->rd, p, sizeof(u_int64_t));
pfxlen -= sizeof(u_int64_t) * 8;
p += sizeof(u_int64_t);
plen += sizeof(u_int64_t);
@@ -567,8 +564,8 @@ nlri_get_vpn4(u_char *p, u_int16_t len,
if (pfxlen > 32)
return (-1);
- if ((rv = extract_prefix(p, len, &prefix->vpn4.addr,
- pfxlen, sizeof(prefix->vpn4.addr))) == -1)
+ if ((rv = extract_prefix(p, len, &prefix->v4,
+ pfxlen, sizeof(prefix->v4))) == -1)
return (-1);
return (plen + rv);
@@ -595,8 +592,8 @@ nlri_get_vpn6(u_char *p, u_int16_t len,
do {
if (len - plen < 3 || pfxlen < 3 * 8)
return (-1);
- if (prefix->vpn6.labellen + 3U >
- sizeof(prefix->vpn6.labelstack))
+ if (prefix->labellen + 3U >
+ sizeof(prefix->labelstack))
return (-1);
if (withdraw) {
/* on withdraw ignore the labelstack all together */
@@ -605,13 +602,13 @@ nlri_get_vpn6(u_char *p, u_int16_t len,
break;
}
- prefix->vpn6.labelstack[prefix->vpn6.labellen++] = *p++;
- prefix->vpn6.labelstack[prefix->vpn6.labellen++] = *p++;
- prefix->vpn6.labelstack[prefix->vpn6.labellen] = *p++;
- if (prefix->vpn6.labelstack[prefix->vpn6.labellen] &
+ prefix->labelstack[prefix->labellen++] = *p++;
+ prefix->labelstack[prefix->labellen++] = *p++;
+ prefix->labelstack[prefix->labellen] = *p++;
+ if (prefix->labelstack[prefix->labellen] &
BGP_MPLS_BOS)
done = 1;
- prefix->vpn6.labellen++;
+ prefix->labellen++;
plen += 3;
pfxlen -= 3 * 8;
} while (!done);
@@ -621,7 +618,7 @@ nlri_get_vpn6(u_char *p, u_int16_t len,
pfxlen < sizeof(u_int64_t) * 8)
return (-1);
- memcpy(&prefix->vpn6.rd, p, sizeof(u_int64_t));
+ memcpy(&prefix->rd, p, sizeof(u_int64_t));
pfxlen -= sizeof(u_int64_t) * 8;
p += sizeof(u_int64_t);
plen += sizeof(u_int64_t);
@@ -633,8 +630,8 @@ nlri_get_vpn6(u_char *p, u_int16_t len,
if (pfxlen > 128)
return (-1);
- if ((rv = extract_prefix(p, len, &prefix->vpn6.addr,
- pfxlen, sizeof(prefix->vpn6.addr))) == -1)
+ if ((rv = extract_prefix(p, len, &prefix->v6,
+ pfxlen, sizeof(prefix->v6))) == -1)
return (-1);
return (plen + rv);
@@ -658,6 +655,12 @@ prefix_compare(const struct bgpd_addr *a
return (a->aid - b->aid);
switch (a->aid) {
+ case AID_VPN_IPv4:
+ if (be64toh(a->rd) > be64toh(b->rd))
+ return (1);
+ if (be64toh(a->rd) < be64toh(b->rd))
+ return (-1);
+ /* FALLTHROUGH */
case AID_INET:
if (prefixlen == 0)
return (0);
@@ -666,9 +669,17 @@ prefix_compare(const struct bgpd_addr *a
mask = htonl(prefixlen2mask(prefixlen));
aa = ntohl(a->v4.s_addr & mask);
ba = ntohl(b->v4.s_addr & mask);
- if (aa != ba)
- return (aa - ba);
- return (0);
+ if (aa > ba)
+ return (1);
+ if (aa < ba)
+ return (1);
+ break;
+ case AID_VPN_IPv6:
+ if (be64toh(a->rd) > be64toh(b->rd))
+ return (1);
+ if (be64toh(a->rd) < be64toh(b->rd))
+ return (-1);
+ /* FALLTHROUGH */
case AID_INET6:
if (prefixlen == 0)
return (0);
@@ -685,53 +696,20 @@ prefix_compare(const struct bgpd_addr *a
return ((a->v6.s6_addr[prefixlen / 8] & m) -
(b->v6.s6_addr[prefixlen / 8] & m));
}
- return (0);
- case AID_VPN_IPv4:
- if (prefixlen > 32)
- return (-1);
- if (be64toh(a->vpn4.rd) > be64toh(b->vpn4.rd))
- return (1);
- if (be64toh(a->vpn4.rd) < be64toh(b->vpn4.rd))
- return (-1);
- mask = htonl(prefixlen2mask(prefixlen));
- aa = ntohl(a->vpn4.addr.s_addr & mask);
- ba = ntohl(b->vpn4.addr.s_addr & mask);
- if (aa != ba)
- return (aa - ba);
- if (a->vpn4.labellen > b->vpn4.labellen)
- return (1);
- if (a->vpn4.labellen < b->vpn4.labellen)
- return (-1);
- return (memcmp(a->vpn4.labelstack, b->vpn4.labelstack,
- a->vpn4.labellen));
- case AID_VPN_IPv6:
- if (prefixlen > 128)
- return (-1);
- if (be64toh(a->vpn6.rd) > be64toh(b->vpn6.rd))
- return (1);
- if (be64toh(a->vpn6.rd) < be64toh(b->vpn6.rd))
- return (-1);
- for (i = 0; i < prefixlen / 8; i++)
- if (a->vpn6.addr.s6_addr[i] != b->vpn6.addr.s6_addr[i])
- return (a->vpn6.addr.s6_addr[i] -
- b->vpn6.addr.s6_addr[i]);
- i = prefixlen % 8;
- if (i) {
- m = 0xff00 >> i;
- if ((a->vpn6.addr.s6_addr[prefixlen / 8] & m) !=
- (b->vpn6.addr.s6_addr[prefixlen / 8] & m))
- return ((a->vpn6.addr.s6_addr[prefixlen / 8] &
- m) - (b->vpn6.addr.s6_addr[prefixlen / 8] &
- m));
- }
- if (a->vpn6.labellen > b->vpn6.labellen)
+ break;
+ default:
+ return (-1);
+ }
+
+ if (a->aid == AID_VPN_IPv4 || a->aid == AID_VPN_IPv6) {
+ if (a->labellen > b->labellen)
return (1);
- if (a->vpn6.labellen < b->vpn6.labellen)
+ if (a->labellen < b->labellen)
return (-1);
- return (memcmp(a->vpn6.labelstack, b->vpn6.labelstack,
- a->vpn6.labellen));
+ return (memcmp(a->labelstack, b->labelstack, a->labellen));
}
- return (-1);
+ return (0);
+
}
in_addr_t
@@ -847,28 +825,16 @@ addr2sa(const struct bgpd_addr *addr, u_
bzero(&ss, sizeof(ss));
switch (addr->aid) {
case AID_INET:
+ case AID_VPN_IPv4:
sa_in->sin_family = AF_INET;
sa_in->sin_addr.s_addr = addr->v4.s_addr;
sa_in->sin_port = htons(port);
*len = sizeof(struct sockaddr_in);
break;
case AID_INET6:
- sa_in6->sin6_family = AF_INET6;
- memcpy(&sa_in6->sin6_addr, &addr->v6,
- sizeof(sa_in6->sin6_addr));
- sa_in6->sin6_port = htons(port);
- sa_in6->sin6_scope_id = addr->scope_id;
- *len = sizeof(struct sockaddr_in6);
- break;
- case AID_VPN_IPv4:
- sa_in->sin_family = AF_INET;
- sa_in->sin_addr.s_addr = addr->vpn4.addr.s_addr;
- sa_in->sin_port = htons(port);
- *len = sizeof(struct sockaddr_in);
- break;
case AID_VPN_IPv6:
sa_in6->sin6_family = AF_INET6;
- memcpy(&sa_in6->sin6_addr, &addr->vpn6.addr,
+ memcpy(&sa_in6->sin6_addr, &addr->v6,
sizeof(sa_in6->sin6_addr));
sa_in6->sin6_port = htons(port);
sa_in6->sin6_scope_id = addr->scope_id;