Move the nlri_get_prefix functions to util.c so that bgpctl can use them too.
authorclaudio <claudio@openbsd.org>
Fri, 20 Jul 2018 14:58:20 +0000 (14:58 +0000)
committerclaudio <claudio@openbsd.org>
Fri, 20 Jul 2018 14:58:20 +0000 (14:58 +0000)
usr.sbin/bgpd/bgpd.h
usr.sbin/bgpd/rde.c
usr.sbin/bgpd/rde.h
usr.sbin/bgpd/util.c

index 92ade04..71f6272 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bgpd.h,v 1.326 2018/07/14 12:32:35 benno Exp $ */
+/*     $OpenBSD: bgpd.h,v 1.327 2018/07/20 14:58:20 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -1165,6 +1165,18 @@ int               aspath_match(void *, u_int16_t, struct filter_as *, u_int32_t);
 int             as_compare(u_int8_t, u_int32_t, u_int32_t, u_int32_t,
                    u_int32_t);
 u_int32_t       aspath_extract(const void *, int);
+int             aspath_verify(void *, u_int16_t, int);
+#define                 AS_ERR_LEN     -1
+#define                 AS_ERR_TYPE    -2
+#define                 AS_ERR_BAD     -3
+#define                 AS_ERR_SOFT    -4
+u_char         *aspath_inflate(void *, u_int16_t, u_int16_t *);
+int             nlri_get_prefix(u_char *, u_int16_t, struct bgpd_addr *,
+                    u_int8_t *);
+int             nlri_get_prefix6(u_char *, u_int16_t, struct bgpd_addr *,
+                    u_int8_t *);
+int             nlri_get_vpn4(u_char *, u_int16_t, struct bgpd_addr *,
+                    u_int8_t *, int);
 int             prefix_compare(const struct bgpd_addr *,
                    const struct bgpd_addr *, int);
 in_addr_t       prefixlen2mask(u_int8_t);
index e4a3e66..3afe468 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde.c,v 1.396 2018/07/20 14:49:15 claudio Exp $ */
+/*     $OpenBSD: rde.c,v 1.397 2018/07/20 14:58:20 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -61,12 +61,6 @@ int           rde_attr_add(struct rde_aspath *, u_char *, u_int16_t);
 u_int8_t        rde_attr_missing(struct rde_aspath *, int, u_int16_t);
 int             rde_get_mp_nexthop(u_char *, u_int16_t, u_int8_t,
                     struct filterstate *);
-int             nlri_get_prefix(u_char *, u_int16_t, struct bgpd_addr *,
-                    u_int8_t *);
-int             nlri_get_prefix6(u_char *, u_int16_t, struct bgpd_addr *,
-                    u_int8_t *);
-int             nlri_get_vpn4(u_char *, u_int16_t, struct bgpd_addr *,
-                    u_int8_t *, int);
 void            rde_update_err(struct rde_peer *, u_int8_t , u_int8_t,
                     void *, u_int16_t);
 void            rde_update_log(const char *, u_int16_t,
@@ -1839,147 +1833,6 @@ rde_get_mp_nexthop(u_char *data, u_int16_t len, u_int8_t aid,
        return (totlen);
 }
 
-static int
-extract_prefix(u_char *p, u_int16_t len, void *va,
-    u_int8_t pfxlen, u_int8_t max)
-{
-       static u_char addrmask[] = {
-           0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
-       u_char          *a = va;
-       int              i;
-       u_int16_t        plen = 0;
-
-       for (i = 0; pfxlen && i < max; i++) {
-               if (len <= plen)
-                       return (-1);
-               if (pfxlen < 8) {
-                       a[i] = *p++ & addrmask[pfxlen];
-                       plen++;
-                       break;
-               } else {
-                       a[i] = *p++;
-                       plen++;
-                       pfxlen -= 8;
-               }
-       }
-       return (plen);
-}
-
-int
-nlri_get_prefix(u_char *p, u_int16_t len, struct bgpd_addr *prefix,
-    u_int8_t *prefixlen)
-{
-       u_int8_t         pfxlen;
-       int              plen;
-
-       if (len < 1)
-               return (-1);
-
-       pfxlen = *p++;
-       len--;
-
-       bzero(prefix, sizeof(struct bgpd_addr));
-       prefix->aid = AID_INET;
-       *prefixlen = pfxlen;
-
-       if (pfxlen > 32)
-               return (-1);
-       if ((plen = extract_prefix(p, len, &prefix->v4, pfxlen,
-           sizeof(prefix->v4))) == -1)
-               return (-1);
-
-       return (plen + 1);      /* pfxlen needs to be added */
-}
-
-int
-nlri_get_prefix6(u_char *p, u_int16_t len, struct bgpd_addr *prefix,
-    u_int8_t *prefixlen)
-{
-       int             plen;
-       u_int8_t        pfxlen;
-
-       if (len < 1)
-               return (-1);
-
-       pfxlen = *p++;
-       len--;
-
-       bzero(prefix, sizeof(struct bgpd_addr));
-       prefix->aid = AID_INET6;
-       *prefixlen = pfxlen;
-
-       if (pfxlen > 128)
-               return (-1);
-       if ((plen = extract_prefix(p, len, &prefix->v6, pfxlen,
-           sizeof(prefix->v6))) == -1)
-               return (-1);
-
-       return (plen + 1);      /* pfxlen needs to be added */
-}
-
-int
-nlri_get_vpn4(u_char *p, u_int16_t len, struct bgpd_addr *prefix,
-    u_int8_t *prefixlen, int withdraw)
-{
-       int              rv, done = 0;
-       u_int8_t         pfxlen;
-       u_int16_t        plen;
-
-       if (len < 1)
-               return (-1);
-
-       memcpy(&pfxlen, p, 1);
-       p += 1;
-       plen = 1;
-
-       bzero(prefix, sizeof(struct bgpd_addr));
-
-       /* label stack */
-       do {
-               if (len - plen < 3 || pfxlen < 3 * 8)
-                       return (-1);
-               if (prefix->vpn4.labellen + 3U >
-                   sizeof(prefix->vpn4.labelstack))
-                       return (-1);
-               if (withdraw) {
-                       /* on withdraw ignore the labelstack all together */
-                       plen += 3;
-                       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] &
-                   BGP_MPLS_BOS)
-                       done = 1;
-               prefix->vpn4.labellen++;
-               plen += 3;
-               pfxlen -= 3 * 8;
-       } while (!done);
-
-       /* RD */
-       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));
-       pfxlen -= sizeof(u_int64_t) * 8;
-       p += sizeof(u_int64_t);
-       plen += sizeof(u_int64_t);
-
-       /* prefix */
-       prefix->aid = AID_VPN_IPv4;
-       *prefixlen = pfxlen;
-
-       if (pfxlen > 32)
-               return (-1);
-       if ((rv = extract_prefix(p, len, &prefix->vpn4.addr,
-           pfxlen, sizeof(prefix->vpn4.addr))) == -1)
-               return (-1);
-
-       return (plen + rv);
-}
-
 void
 rde_update_err(struct rde_peer *peer, u_int8_t error, u_int8_t suberr,
     void *data, u_int16_t size)
index 9b3ceab..fbcdb94 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde.h,v 1.179 2018/07/16 09:09:20 claudio Exp $ */
+/*     $OpenBSD: rde.h,v 1.180 2018/07/20 14:58:20 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -360,17 +360,11 @@ void               attr_free(struct rde_aspath *, struct attr *);
 #define                 attr_optlen(x) \
     ((x)->len > 255 ? (x)->len + 4 : (x)->len + 3)
 
-int             aspath_verify(void *, u_int16_t, int);
-#define                 AS_ERR_LEN     -1
-#define                 AS_ERR_TYPE    -2
-#define                 AS_ERR_BAD     -3
-#define                 AS_ERR_SOFT    -4
 void            aspath_init(u_int32_t);
 void            aspath_shutdown(void);
 void            aspath_hash_stats(struct rde_hashstats *);
 struct aspath  *aspath_get(void *, u_int16_t);
 void            aspath_put(struct aspath *);
-u_char         *aspath_inflate(void *, u_int16_t, u_int16_t *);
 u_char         *aspath_deflate(u_char *, u_int16_t *, int *);
 void            aspath_merge(struct rde_aspath *, struct attr *);
 u_char         *aspath_dump(struct aspath *);
index 19a9ee8..e7c40df 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: util.c,v 1.26 2018/07/13 08:18:11 claudio Exp $ */
+/*     $OpenBSD: util.c,v 1.27 2018/07/20 14:58:20 claudio Exp $ */
 
 /*
  * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
@@ -504,6 +504,148 @@ aspath_inflate(void *data, u_int16_t len, u_int16_t *newlen)
        return (ndata);
 }
 
+/* NLRI functions to extract prefixes from the NLRI blobs */
+static int
+extract_prefix(u_char *p, u_int16_t len, void *va,
+    u_int8_t pfxlen, u_int8_t max)
+{
+       static u_char addrmask[] = {
+           0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
+       u_char          *a = va;
+       int              i;
+       u_int16_t        plen = 0;
+
+       for (i = 0; pfxlen && i < max; i++) {
+               if (len <= plen)
+                       return (-1);
+               if (pfxlen < 8) {
+                       a[i] = *p++ & addrmask[pfxlen];
+                       plen++;
+                       break;
+               } else {
+                       a[i] = *p++;
+                       plen++;
+                       pfxlen -= 8;
+               }
+       }
+       return (plen);
+}
+
+int
+nlri_get_prefix(u_char *p, u_int16_t len, struct bgpd_addr *prefix,
+    u_int8_t *prefixlen)
+{
+       u_int8_t         pfxlen;
+       int              plen;
+
+       if (len < 1)
+               return (-1);
+
+       pfxlen = *p++;
+       len--;
+
+       bzero(prefix, sizeof(struct bgpd_addr));
+       prefix->aid = AID_INET;
+       *prefixlen = pfxlen;
+
+       if (pfxlen > 32)
+               return (-1);
+       if ((plen = extract_prefix(p, len, &prefix->v4, pfxlen,
+           sizeof(prefix->v4))) == -1)
+               return (-1);
+
+       return (plen + 1);      /* pfxlen needs to be added */
+}
+
+int
+nlri_get_prefix6(u_char *p, u_int16_t len, struct bgpd_addr *prefix,
+    u_int8_t *prefixlen)
+{
+       int             plen;
+       u_int8_t        pfxlen;
+
+       if (len < 1)
+               return (-1);
+
+       pfxlen = *p++;
+       len--;
+
+       bzero(prefix, sizeof(struct bgpd_addr));
+       prefix->aid = AID_INET6;
+       *prefixlen = pfxlen;
+
+       if (pfxlen > 128)
+               return (-1);
+       if ((plen = extract_prefix(p, len, &prefix->v6, pfxlen,
+           sizeof(prefix->v6))) == -1)
+               return (-1);
+
+       return (plen + 1);      /* pfxlen needs to be added */
+}
+
+int
+nlri_get_vpn4(u_char *p, u_int16_t len, struct bgpd_addr *prefix,
+    u_int8_t *prefixlen, int withdraw)
+{
+       int              rv, done = 0;
+       u_int8_t         pfxlen;
+       u_int16_t        plen;
+
+       if (len < 1)
+               return (-1);
+
+       memcpy(&pfxlen, p, 1);
+       p += 1;
+       plen = 1;
+
+       bzero(prefix, sizeof(struct bgpd_addr));
+
+       /* label stack */
+       do {
+               if (len - plen < 3 || pfxlen < 3 * 8)
+                       return (-1);
+               if (prefix->vpn4.labellen + 3U >
+                   sizeof(prefix->vpn4.labelstack))
+                       return (-1);
+               if (withdraw) {
+                       /* on withdraw ignore the labelstack all together */
+                       plen += 3;
+                       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] &
+                   BGP_MPLS_BOS)
+                       done = 1;
+               prefix->vpn4.labellen++;
+               plen += 3;
+               pfxlen -= 3 * 8;
+       } while (!done);
+
+       /* RD */
+       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));
+       pfxlen -= sizeof(u_int64_t) * 8;
+       p += sizeof(u_int64_t);
+       plen += sizeof(u_int64_t);
+
+       /* prefix */
+       prefix->aid = AID_VPN_IPv4;
+       *prefixlen = pfxlen;
+
+       if (pfxlen > 32)
+               return (-1);
+       if ((rv = extract_prefix(p, len, &prefix->vpn4.addr,
+           pfxlen, sizeof(prefix->vpn4.addr))) == -1)
+               return (-1);
+
+       return (plen + rv);
+}
+
 /*
  * This function will have undefined behaviour if the passed in prefixlen is
  * to large for the respective bgpd_addr address family.