From: claudio Date: Fri, 20 Jul 2018 14:58:20 +0000 (+0000) Subject: Move the nlri_get_prefix functions to util.c so that bgpctl can use them too. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=6d3e8673a3238e02bf13d4fcff28d9c6adcec880;p=openbsd Move the nlri_get_prefix functions to util.c so that bgpctl can use them too. --- diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index 92ade0493e7..71f6272a66c 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -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 @@ -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); diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index e4a3e66cc1a..3afe468ed9c 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -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 @@ -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) diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h index 9b3ceab29d1..fbcdb944d27 100644 --- a/usr.sbin/bgpd/rde.h +++ b/usr.sbin/bgpd/rde.h @@ -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 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 *); diff --git a/usr.sbin/bgpd/util.c b/usr.sbin/bgpd/util.c index 19a9ee887f7..e7c40df5c8d 100644 --- a/usr.sbin/bgpd/util.c +++ b/usr.sbin/bgpd/util.c @@ -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 @@ -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.