Change struct bgpd_addr VPN encoding. Instead of including two almost
authorclaudio <claudio@openbsd.org>
Mon, 18 Jan 2021 12:15:36 +0000 (12:15 +0000)
committerclaudio <claudio@openbsd.org>
Mon, 18 Jan 2021 12:15:36 +0000 (12:15 +0000)
equal versions put the RD and lable stack right into struct bgpd_addr.
For non-VPN addresses these extra fields are ignored. Since VPN and non-VPN
addresses encode the prefix in the same way now some code can be simplified.
In most cases a fallthrough or reuse of encoding functions is now possible.
It should also reduce the size of struct bgpd_addr a bit.
OK denis@

usr.sbin/bgpd/bgpd.h
usr.sbin/bgpd/kroute.c
usr.sbin/bgpd/rde.c
usr.sbin/bgpd/rde_prefix.c
usr.sbin/bgpd/rde_rib.c
usr.sbin/bgpd/util.c

index e1c2a1d..bedb680 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bgpd.h,v 1.409 2021/01/04 13:40:32 claudio Exp $ */
+/*     $OpenBSD: bgpd.h,v 1.410 2021/01/18 12:15:36 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -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 eab13d9..09aaff5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kroute.c,v 1.240 2020/12/29 09:20:25 claudio Exp $ */
+/*     $OpenBSD: kroute.c,v 1.241 2021/01/18 12:15:36 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -601,14 +601,14 @@ krVPN4_change(struct ktable *kt, struct kroute_full *kl, u_int8_t fib_prio)
                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 kroute_full *kl, u_int8_t fib_prio)
        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 kroute_full *kl, u_int8_t fib_prio)
                        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 kroute_full *kl, u_int8_t fib_prio)
                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 kroute_full *kl, u_int8_t fib_prio)
 
        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 kroute_full *kl, u_int8_t fib_prio)
                        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 kroute_full *kl, u_int8_t fib_prio)
 {
        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 kroute_full *kl, u_int8_t fib_prio)
 {
        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 555eea5..8071a6d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde.c,v 1.512 2021/01/13 11:34:01 claudio Exp $ */
+/*     $OpenBSD: rde.c,v 1.513 2021/01/18 12:15:36 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -3658,7 +3658,7 @@ network_add(struct network_config *nc, struct filterstate *state)
 {
        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;
@@ -3669,37 +3669,35 @@ network_add(struct network_config *nc, struct filterstate *state)
                                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:
@@ -3745,7 +3743,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;
 
@@ -3755,36 +3753,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 6b5b2c4..2883d6b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde_prefix.c,v 1.39 2019/07/01 07:07:08 claudio Exp $ */
+/*     $OpenBSD: rde_prefix.c,v 1.40 2021/01/18 12:15:36 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -79,27 +79,24 @@ pt_getaddr(struct pt_entry *pte, struct bgpd_addr *addr)
                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 prefixlen)
                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 8ec419e..468354b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde_rib.c,v 1.219 2021/01/13 11:34:01 claudio Exp $ */
+/*     $OpenBSD: rde_rib.c,v 1.220 2021/01/18 12:15:36 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -1416,47 +1416,19 @@ prefix_write(u_char *buf, int len, struct bgpd_addr *prefix, u_int8_t plen,
                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;
@@ -1466,13 +1438,13 @@ prefix_write(u_char *buf, int len, struct bgpd_addr *prefix, u_int8_t plen,
                        *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);
@@ -1491,12 +1463,9 @@ prefix_writebuf(struct ibuf *buf, struct bgpd_addr *prefix, u_int8_t plen)
                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 3ec6829..5420b48 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: util.c,v 1.58 2021/01/05 10:00:28 claudio Exp $ */
+/*     $OpenBSD: util.c,v 1.59 2021/01/18 12:15:36 claudio Exp $ */
 
 /*
  * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
@@ -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, struct bgpd_addr *prefix,
        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, struct bgpd_addr *prefix,
                        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, struct bgpd_addr *prefix,
        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, struct bgpd_addr *prefix,
 
        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, struct bgpd_addr *prefix,
        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, struct bgpd_addr *prefix,
                        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, struct bgpd_addr *prefix,
            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, struct bgpd_addr *prefix,
        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, const struct bgpd_addr *b,
                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, const struct bgpd_addr *b,
                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, const struct bgpd_addr *b,
                                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_int16_t port, socklen_t *len)
        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;