diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-09-08 15:40:26 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-09-08 15:40:26 +0000 |
commit | d2863a322ab754c0b6f3239c0504024a525a789d (patch) | |
tree | 218c39b2b470111b32c2a68693288f7938f1528d | |
parent | 6e8fc9a1adf30acd4571d405b622b07cb8842abb (diff) |
Update irrfilter to support IPv6 and 4-byte AS numbers. IPv6 support based
on work by Tonnerre Lombard I just cleaned it up. OK henning, sthen
-rw-r--r-- | usr.sbin/bgpctl/irr_parser.c | 8 | ||||
-rw-r--r-- | usr.sbin/bgpctl/irr_prefix.c | 86 | ||||
-rw-r--r-- | usr.sbin/bgpctl/irrfilter.h | 8 | ||||
-rw-r--r-- | usr.sbin/bgpctl/whois.c | 5 |
4 files changed, 78 insertions, 29 deletions
diff --git a/usr.sbin/bgpctl/irr_parser.c b/usr.sbin/bgpctl/irr_parser.c index 063faba1753..33e51e823c5 100644 --- a/usr.sbin/bgpctl/irr_parser.c +++ b/usr.sbin/bgpctl/irr_parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: irr_parser.c,v 1.8 2007/03/05 22:34:08 henning Exp $ */ +/* $OpenBSD: irr_parser.c,v 1.9 2009/09/08 15:40:25 claudio Exp $ */ /* * Copyright (c) 2007 Henning Brauer <henning@openbsd.org> @@ -81,6 +81,7 @@ parse_response(FILE *f, enum qtype qtype) return (-1); break; case QTYPE_ROUTE: + case QTYPE_ROUTE6: if ((n = parse_route(key, val)) == -1) return (-1); break; @@ -281,7 +282,7 @@ parse_policy(char *key, char *val) !isdigit(tok[2])) errx(1, "peering spec \"%s\": format " "error, AS expected", tok); - pi->peer_as = strtonum(tok + 2, 1, USHRT_MAX, + pi->peer_as = strtonum(tok + 2, 1, UINT_MAX, &errstr); if (errstr) errx(1, "peering spec \"%s\": format " @@ -407,7 +408,8 @@ parse_asset(char *key, char *val) int parse_route(char *key, char *val) { - if (strcmp(key, "route")) /* ignore everything else */ + if (strcmp(key, "route") && strcmp(key, "route6")) + /* ignore everything else */ return (0); /* route is single-value, but seen trailing , in the wild */ diff --git a/usr.sbin/bgpctl/irr_prefix.c b/usr.sbin/bgpctl/irr_prefix.c index 8bc0d7470d5..d8f5a708bdd 100644 --- a/usr.sbin/bgpctl/irr_prefix.c +++ b/usr.sbin/bgpctl/irr_prefix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: irr_prefix.c,v 1.15 2007/05/27 18:54:25 henning Exp $ */ +/* $OpenBSD: irr_prefix.c,v 1.16 2009/09/08 15:40:25 claudio Exp $ */ /* * Copyright (c) 2007 Henning Brauer <henning@openbsd.org> @@ -29,6 +29,7 @@ #include <arpa/inet.h> #include "irrfilter.h" +#include "bgpd.h" void prefixset_aggregate(struct prefix_set *); int prefix_aggregate(struct irr_prefix *, const struct irr_prefix *); @@ -65,6 +66,8 @@ prefixset_get(char *as) curpfxs = pfxs; if (whois(as, QTYPE_ROUTE) == -1) errx(1, "whois error, prefixset_get %s", as); + if (whois(as, QTYPE_ROUTE6) == -1) + errx(1, "whois error, prefixset_get %s", as); curpfxs = NULL; if (irrverbose >= 3) fprintf(stdout, "done\n"); @@ -80,9 +83,11 @@ prefixset_addmember(char *s) void *p; u_int i; struct irr_prefix *pfx; - int len; + int len, ret; + char *slash; + const char *errstr; - if (strchr(s, '/') == NULL) { + if ((slash = strchr(s, '/')) == NULL) { fprintf(stderr, "%s: prefix %s does not have the len " "specified, ignoring\n", curpfxs->as, s); return (0); @@ -92,17 +97,26 @@ prefixset_addmember(char *s) err(1, "prefixset_addmember calloc"); if ((len = inet_net_pton(AF_INET, s, &pfx->addr.in, - sizeof(pfx->addr.in))) == -1) { - if (errno == ENOENT) { - fprintf(stderr, "%s: prefix \"%s\": parse error\n", + sizeof(pfx->addr.in))) != -1) { + pfx->af = AF_INET; + } else { + len = strtonum(slash + 1, 0, 128, &errstr); + if (errstr) + errx(1, "prefixset_addmember %s prefix %s: prefixlen " + "is %s", curpfxs->as, s, errstr); + *slash = '\0'; + + if ((ret = inet_pton(AF_INET6, s, &pfx->addr.in6)) == -1) + err(1, "prefixset_addmember %s prefix \"%s\"", curpfxs->as, s); + else if (ret == 0) { + fprintf(stderr, "prefixset_addmember %s prefix \"%s\": " + "No matching address family found", curpfxs->as, s); + free(pfx); return (0); - } else - err(1, "prefixset_addmember %s inet_net_pton \"%s\"", - curpfxs->as, s); + } + pfx->af = AF_INET6; } - - pfx->af = AF_INET; pfx->len = pfx->maxlen = len; /* yes, there are dupes... e. g. from multiple sources */ @@ -175,24 +189,47 @@ prefixset_aggregate(struct prefix_set *pfxs) int prefix_aggregate(struct irr_prefix *a, const struct irr_prefix *b) { - in_addr_t mask; + in_addr_t mask; + struct in6_addr ma; + struct in6_addr mb; if (a->len == 0) return (1); - mask = htonl(0xffffffff << (32 - a->len)); + if (a->af != b->af) + /* We cannot aggregate addresses of different families. */ + return (0); - if ((a->addr.in.s_addr & mask) == (b->addr.in.s_addr & mask)) - return (1); + if (a->af == AF_INET) { + mask = htonl(prefixlen2mask(a->len)); + if ((a->addr.in.s_addr & mask) == (b->addr.in.s_addr & mask)) + return (1); + } else if (a->af == AF_INET6) { + inet6applymask(&ma, &a->addr.in6, a->len); + inet6applymask(&mb, &b->addr.in6, a->len); + if (IN6_ARE_ADDR_EQUAL(&ma, &mb)) + return (1); + } /* see wether we can fold them in one */ if (a->len == b->len && a->len > 1) { - mask = htonl(0xffffffff << (32 - (a->len - 1))); - if ((a->addr.in.s_addr & mask) == - (b->addr.in.s_addr & mask)) { - a->len--; - a->addr.in.s_addr &= mask; - return (1); + if (a->af == AF_INET) { + mask = htonl(prefixlen2mask(a->len - 1)); + if ((a->addr.in.s_addr & mask) == + (b->addr.in.s_addr & mask)) { + a->len--; + a->addr.in.s_addr &= mask; + return (1); + } + } else if (a->af == AF_INET6) { + inet6applymask(&ma, &a->addr.in6, a->len - 1); + inet6applymask(&mb, &b->addr.in6, a->len - 1); + + if (IN6_ARE_ADDR_EQUAL(&ma, &mb)) { + a->len--; + memcpy(&a->addr.in6, &ma, sizeof(ma)); + return (1); + } } } @@ -219,6 +256,13 @@ irr_prefix_cmp(const void *a, const void *b) if (ntohl(pa->addr.in.s_addr) > ntohl(pb->addr.in.s_addr)) return (1); + } else if (pa->af == AF_INET6) { + for (r = 0; r < 16; r++) { + if (pa->addr.in6.s6_addr[r] < pb->addr.in6.s6_addr[r]) + return (-1); + if (pa->addr.in6.s6_addr[r] > pb->addr.in6.s6_addr[r]) + return (1); + } } else errx(1, "irr_prefix_cmp unknown af %u", pa->af); diff --git a/usr.sbin/bgpctl/irrfilter.h b/usr.sbin/bgpctl/irrfilter.h index 5059240b52e..88370b47045 100644 --- a/usr.sbin/bgpctl/irrfilter.h +++ b/usr.sbin/bgpctl/irrfilter.h @@ -1,4 +1,4 @@ -/* $OpenBSD: irrfilter.h,v 1.7 2007/03/06 16:45:34 henning Exp $ */ +/* $OpenBSD: irrfilter.h,v 1.8 2009/09/08 15:40:25 claudio Exp $ */ /* * Copyright (c) 2007 Henning Brauer <henning@openbsd.org> @@ -37,7 +37,7 @@ struct policy_item { char *action; char *filter; enum pdir dir; - u_int16_t peer_as; + u_int32_t peer_as; }; TAILQ_HEAD(policy_head, policy_item); @@ -55,7 +55,8 @@ enum qtype { QTYPE_NONE, QTYPE_OWNAS, QTYPE_ASSET, - QTYPE_ROUTE + QTYPE_ROUTE, + QTYPE_ROUTE6 }; struct as_set { @@ -72,6 +73,7 @@ struct as_set { struct irr_prefix { union { struct in_addr in; + struct in6_addr in6; } addr; sa_family_t af; u_int8_t len; diff --git a/usr.sbin/bgpctl/whois.c b/usr.sbin/bgpctl/whois.c index 839dcbba13a..f14d07d8ed7 100644 --- a/usr.sbin/bgpctl/whois.c +++ b/usr.sbin/bgpctl/whois.c @@ -1,4 +1,4 @@ -/* $OpenBSD: whois.c,v 1.3 2007/03/05 16:43:24 henning Exp $ */ +/* $OpenBSD: whois.c,v 1.4 2009/09/08 15:40:25 claudio Exp $ */ /* * Copyright (c) 2007 Henning Brauer <henning@openbsd.org> @@ -68,7 +68,8 @@ char *qtype_opts[] = { "", "-T aut-num", "-K -T as-set", - "-K -T route -i origin" + "-K -T route -i origin", + "-K -T route6 -i origin" }; char *server = "whois.radb.net"; |