-/* $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>
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);
-/* $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>
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,
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)
-/* $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
#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 *);
-/* $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>
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.