1
0
mirror of https://github.com/openbsd/src.git synced 2025-01-10 06:47:55 -08:00

Move the nlri_get_prefix functions to util.c so that bgpctl can use them too.

This commit is contained in:
claudio 2018-07-20 14:58:20 +00:00
parent b279bedefa
commit 6d3e8673a3
4 changed files with 158 additions and 157 deletions

View 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);

View 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)

View 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 *);

View 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.