diff options
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 6 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.c | 5 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.h | 8 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_attr.c | 63 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_filter.c | 5 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_rib.c | 62 | ||||
-rw-r--r-- | usr.sbin/bgpd/util.c | 123 |
7 files changed, 136 insertions, 136 deletions
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index 1626f0aca12..80e7e407522 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.266 2011/09/19 11:18:11 claudio Exp $ */ +/* $OpenBSD: bgpd.h,v 1.267 2011/09/20 21:19:06 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -986,6 +986,10 @@ const char *log_ext_subtype(u_int8_t); int aspath_snprint(char *, size_t, void *, u_int16_t); int aspath_asprint(char **, void *, u_int16_t); size_t aspath_strlen(void *, u_int16_t); +int aspath_match(void *, u_int16_t, enum as_spec, u_int32_t); +u_int32_t aspath_extract(const void *, int); +int prefix_compare(const struct bgpd_addr *, + const struct bgpd_addr *, int); in_addr_t prefixlen2mask(u_int8_t); void inet6applymask(struct in6_addr *, const struct in6_addr *, int); diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index be5e4f91750..46d140ba97a 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.310 2011/09/19 11:18:11 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.311 2011/09/20 21:19:06 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -2184,7 +2184,8 @@ rde_dump_filter(struct prefix *p, struct ctl_show_rib_request *req) if (req->peerid && req->peerid != p->aspath->peer->conf.id) return; if (req->type == IMSG_CTL_SHOW_RIB_AS && - !aspath_match(p->aspath->aspath, req->as.type, req->as.as)) + !aspath_match(p->aspath->aspath->data, + p->aspath->aspath->len, req->as.type, req->as.as)) return; if (req->type == IMSG_CTL_SHOW_RIB_COMMUNITY && !community_match(p->aspath, req->community.as, diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h index 1e4b3ca378b..38b8363b08e 100644 --- a/usr.sbin/bgpd/rde.h +++ b/usr.sbin/bgpd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.140 2011/09/18 09:31:25 claudio Exp $ */ +/* $OpenBSD: rde.h,v 1.141 2011/09/20 21:19:06 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and @@ -355,7 +355,6 @@ u_int32_t aspath_neighbor(struct aspath *); int aspath_loopfree(struct aspath *, u_int32_t); int aspath_compare(struct aspath *, struct aspath *); u_char *aspath_prepend(struct aspath *, u_int32_t, int, u_int16_t *); -int aspath_match(struct aspath *, enum as_spec, u_int32_t); int aspath_lenmatch(struct aspath *, enum aslen_spec, u_int); int community_match(struct rde_aspath *, int, int); int community_set(struct rde_aspath *, int, int); @@ -434,8 +433,6 @@ struct rde_aspath *path_get(void); void path_put(struct rde_aspath *); #define PREFIX_SIZE(x) (((x) + 7) / 8 + 1) -int prefix_compare(const struct bgpd_addr *, - const struct bgpd_addr *, int); struct prefix *prefix_get(struct rib *, struct rde_peer *, struct bgpd_addr *, int, u_int32_t); int prefix_add(struct rib *, struct rde_aspath *, @@ -482,7 +479,4 @@ u_char *up_dump_mp_unreach(u_char *, u_int16_t *, struct rde_peer *, int up_dump_mp_reach(u_char *, u_int16_t *, struct rde_peer *, u_int8_t); -/* util.c */ -u_int32_t aspath_extract(const void *, int); - #endif /* __RDE_H__ */ diff --git a/usr.sbin/bgpd/rde_attr.c b/usr.sbin/bgpd/rde_attr.c index 097472a877a..1e2b1915b33 100644 --- a/usr.sbin/bgpd/rde_attr.c +++ b/usr.sbin/bgpd/rde_attr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_attr.c,v 1.88 2010/12/31 21:22:42 guenther Exp $ */ +/* $OpenBSD: rde_attr.c,v 1.89 2011/09/20 21:19:06 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org> @@ -923,67 +923,6 @@ aspath_prepend(struct aspath *asp, u_int32_t as, int quantum, u_int16_t *len) return (p); } -/* we need to be able to search more than one as */ -int -aspath_match(struct aspath *a, enum as_spec type, u_int32_t as) -{ - u_int8_t *seg; - int final; - u_int16_t len, seg_size; - u_int8_t i, seg_type, seg_len; - - if (type == AS_EMPTY) { - if (a->len == 0) - return (1); - else - return (0); - } - - final = 0; - seg = a->data; - for (len = a->len; len > 0; len -= seg_size, seg += seg_size) { - seg_type = seg[0]; - seg_len = seg[1]; - seg_size = 2 + sizeof(u_int32_t) * seg_len; - - final = (len == seg_size); - - /* just check the first (leftmost) AS */ - if (type == AS_PEER) { - if (as == aspath_extract(seg, 0)) - return (1); - else - return (0); - } - /* just check the final (rightmost) AS */ - if (type == AS_SOURCE) { - /* not yet in the final segment */ - if (!final) - continue; - - if (as == aspath_extract(seg, seg_len - 1)) - return (1); - else - return (0); - } - - /* AS_TRANSIT or AS_ALL */ - for (i = 0; i < seg_len; i++) { - if (as == aspath_extract(seg, i)) { - /* - * the source (rightmost) AS is excluded from - * AS_TRANSIT matches. - */ - if (final && i == seg_len - 1 && - type == AS_TRANSIT) - return (0); - return (1); - } - } - } - return (0); -} - int aspath_lenmatch(struct aspath *a, enum aslen_spec type, u_int aslen) { diff --git a/usr.sbin/bgpd/rde_filter.c b/usr.sbin/bgpd/rde_filter.c index 24d97cc6946..d2f630155c4 100644 --- a/usr.sbin/bgpd/rde_filter.c +++ b/usr.sbin/bgpd/rde_filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_filter.c,v 1.66 2011/05/01 12:56:04 claudio Exp $ */ +/* $OpenBSD: rde_filter.c,v 1.67 2011/09/20 21:19:06 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org> @@ -277,7 +277,8 @@ rde_filter_match(struct filter_rule *f, struct rde_aspath *asp, pas = peer->conf.remote_as; else pas = f->match.as.as; - if (aspath_match(asp->aspath, f->match.as.type, pas) == 0) + if (aspath_match(asp->aspath->data, asp->aspath->len, + f->match.as.type, pas) == 0) return (0); } diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c index a7297ca6004..bbd472dfd1e 100644 --- a/usr.sbin/bgpd/rde_rib.c +++ b/usr.sbin/bgpd/rde_rib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_rib.c,v 1.129 2011/09/17 16:29:44 claudio Exp $ */ +/* $OpenBSD: rde_rib.c,v 1.130 2011/09/20 21:19:06 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> @@ -627,66 +627,6 @@ static void prefix_link(struct prefix *, struct rib_entry *, struct rde_aspath *); static void prefix_unlink(struct prefix *); -int -prefix_compare(const struct bgpd_addr *a, const struct bgpd_addr *b, - int prefixlen) -{ - in_addr_t mask, aa, ba; - int i; - u_int8_t m; - - if (a->aid != b->aid) - return (a->aid - b->aid); - - switch (a->aid) { - case AID_INET: - if (prefixlen > 32) - fatalx("prefix_cmp: bad IPv4 prefixlen"); - 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); - case AID_INET6: - if (prefixlen > 128) - fatalx("prefix_cmp: bad IPv6 prefixlen"); - for (i = 0; i < prefixlen / 8; i++) - if (a->v6.s6_addr[i] != b->v6.s6_addr[i]) - return (a->v6.s6_addr[i] - b->v6.s6_addr[i]); - i = prefixlen % 8; - if (i) { - m = 0xff00 >> i; - if ((a->v6.s6_addr[prefixlen / 8] & m) != - (b->v6.s6_addr[prefixlen / 8] & m)) - return ((a->v6.s6_addr[prefixlen / 8] & m) - - (b->v6.s6_addr[prefixlen / 8] & m)); - } - return (0); - case AID_VPN_IPv4: - if (prefixlen > 32) - fatalx("prefix_cmp: bad IPv4 VPN prefixlen"); - if (betoh64(a->vpn4.rd) > betoh64(b->vpn4.rd)) - return (1); - if (betoh64(a->vpn4.rd) < betoh64(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)); - default: - fatalx("prefix_cmp: unknown af"); - } - return (-1); -} - /* * search for specified prefix of a peer. Returns NULL if not found. */ diff --git a/usr.sbin/bgpd/util.c b/usr.sbin/bgpd/util.c index 412bf3b3345..0f6a799d2e6 100644 --- a/usr.sbin/bgpd/util.c +++ b/usr.sbin/bgpd/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.13 2010/11/18 12:18:31 claudio Exp $ */ +/* $OpenBSD: util.c,v 1.14 2011/09/20 21:19:07 claudio Exp $ */ /* * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org> @@ -332,6 +332,67 @@ aspath_strlen(void *data, u_int16_t len) return (total_size); } +/* we need to be able to search more than one as */ +int +aspath_match(void *data, u_int16_t len, enum as_spec type, u_int32_t as) +{ + u_int8_t *seg; + int final; + u_int16_t seg_size; + u_int8_t i, seg_type, seg_len; + + if (type == AS_EMPTY) { + if (len == 0) + return (1); + else + return (0); + } + + final = 0; + seg = data; + for (; len > 0; len -= seg_size, seg += seg_size) { + seg_type = seg[0]; + seg_len = seg[1]; + seg_size = 2 + sizeof(u_int32_t) * seg_len; + + final = (len == seg_size); + + /* just check the first (leftmost) AS */ + if (type == AS_PEER) { + if (as == aspath_extract(seg, 0)) + return (1); + else + return (0); + } + /* just check the final (rightmost) AS */ + if (type == AS_SOURCE) { + /* not yet in the final segment */ + if (!final) + continue; + + if (as == aspath_extract(seg, seg_len - 1)) + return (1); + else + return (0); + } + + /* AS_TRANSIT or AS_ALL */ + for (i = 0; i < seg_len; i++) { + if (as == aspath_extract(seg, i)) { + /* + * the source (rightmost) AS is excluded from + * AS_TRANSIT matches. + */ + if (final && i == seg_len - 1 && + type == AS_TRANSIT) + return (0); + return (1); + } + } + } + return (0); +} + /* * Extract the asnum out of the as segment at the specified position. * Direct access is not possible because of non-aligned reads. @@ -348,6 +409,66 @@ aspath_extract(const void *seg, int pos) return (ntohl(as)); } +int +prefix_compare(const struct bgpd_addr *a, const struct bgpd_addr *b, + int prefixlen) +{ + in_addr_t mask, aa, ba; + int i; + u_int8_t m; + + if (a->aid != b->aid) + return (a->aid - b->aid); + + switch (a->aid) { + case AID_INET: + if (prefixlen > 32) + fatalx("prefix_cmp: bad IPv4 prefixlen"); + 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); + case AID_INET6: + if (prefixlen > 128) + fatalx("prefix_cmp: bad IPv6 prefixlen"); + for (i = 0; i < prefixlen / 8; i++) + if (a->v6.s6_addr[i] != b->v6.s6_addr[i]) + return (a->v6.s6_addr[i] - b->v6.s6_addr[i]); + i = prefixlen % 8; + if (i) { + m = 0xff00 >> i; + if ((a->v6.s6_addr[prefixlen / 8] & m) != + (b->v6.s6_addr[prefixlen / 8] & m)) + return ((a->v6.s6_addr[prefixlen / 8] & m) - + (b->v6.s6_addr[prefixlen / 8] & m)); + } + return (0); + case AID_VPN_IPv4: + if (prefixlen > 32) + fatalx("prefix_cmp: bad IPv4 VPN prefixlen"); + if (betoh64(a->vpn4.rd) > betoh64(b->vpn4.rd)) + return (1); + if (betoh64(a->vpn4.rd) < betoh64(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)); + default: + fatalx("prefix_cmp: unknown af"); + } + return (-1); +} + in_addr_t prefixlen2mask(u_int8_t prefixlen) { |