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;

Reply via email to