diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2017-05-31 10:44:01 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2017-05-31 10:44:01 +0000 |
commit | 958954d63c3be5782851b75d730e224de82a6026 (patch) | |
tree | 874ee9c056cea591e059811db7a7c1beb41037df | |
parent | 6f45ba7aa33384883e5f9b009f8820c1b56f58d7 (diff) |
Rework the way we do extended communities (mainly in the parser) and update
the IANA table to a somewhat more complete list. This includes BGP Prefix
Origin Validation State support via the ext-community ovs keyword.
OK henning@ benno@ based on a diff by Job Snijders
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 80 | ||||
-rw-r--r-- | usr.sbin/bgpd/kroute.c | 27 | ||||
-rw-r--r-- | usr.sbin/bgpd/parse.y | 122 | ||||
-rw-r--r-- | usr.sbin/bgpd/printconf.c | 44 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_attr.c | 26 | ||||
-rw-r--r-- | usr.sbin/bgpd/util.c | 34 |
6 files changed, 198 insertions, 135 deletions
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index 69046a17110..db52f858241 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.307 2017/05/28 20:14:15 claudio Exp $ */ +/* $OpenBSD: bgpd.h,v 1.308 2017/05/31 10:44:00 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -760,18 +760,23 @@ struct filter_peers { #define EXT_COMMUNITY_IANA 0x80 #define EXT_COMMUNITY_TRANSITIVE 0x40 #define EXT_COMMUNITY_VALUE 0x3f -/* extended types */ -#define EXT_COMMUNITY_TWO_AS 0 /* 2 octet AS specific */ -#define EXT_COMMUNITY_IPV4 1 /* IPv4 specific */ -#define EXT_COMMUNITY_FOUR_AS 2 /* 4 octet AS specific */ -#define EXT_COMMUNITY_OPAQUE 3 /* opaque ext community */ -/* sub types */ -#define EXT_COMMUNITY_ROUTE_TGT 2 /* RFC 4360 & RFC4364 */ -#define EXT_COMMUNITY_ROUTE_ORIG 3 /* RFC 4360 & RFC4364 */ -#define EXT_COMMUNITY_OSPF_DOM_ID 5 /* RFC 4577 */ -#define EXT_COMMUNITY_OSPF_RTR_TYPE 6 /* RFC 4577 */ -#define EXT_COMMUNITY_OSPF_RTR_ID 7 /* RFC 4577 */ -#define EXT_COMMUNITY_BGP_COLLECT 8 /* RFC 4384 */ +/* extended types transitive */ +#define EXT_COMMUNITY_TRANS_TWO_AS 0x00 /* 2 octet AS specific */ +#define EXT_COMMUNITY_TRANS_IPV4 0x01 /* IPv4 specific */ +#define EXT_COMMUNITY_TRANS_FOUR_AS 0x02 /* 4 octet AS specific */ +#define EXT_COMMUNITY_TRANS_OPAQUE 0x03 /* opaque ext community */ +#define EXT_COMMUNITY_TRANS_EVPN 0x06 /* EVPN RFC7432 */ +/* extended types non-transitive */ +#define EXT_COMMUNITY_NON_TRANS_TWO_AS 0x40 /* 2 octet AS specific */ +#define EXT_COMMUNITY_NON_TRANS_IPV4 0x41 /* IPv4 specific */ +#define EXT_COMMUNITY_NON_TRANS_FOUR_AS 0x42 /* 4 octet AS specific */ +#define EXT_COMMUNITY_NON_TRANS_OPAQUE 0x43 /* opaque ext community */ + +/* BGP Origin Validation State Extended Community RFC8097 */ +#define EXT_COMMUNITY_OVS_VALID 0 +#define EXT_COMMUNITY_OVS_NOTFOUND 1 +#define EXT_COMMUNITY_OVS_INVALID 2 + /* other handy defines */ #define EXT_COMMUNITY_OPAQUE_MAX 0xffffffffffffULL #define EXT_COMMUNITY_FLAG_VALID 0x01 @@ -779,22 +784,41 @@ struct filter_peers { struct ext_comm_pairs { u_int8_t type; u_int8_t subtype; - u_int8_t transitive; /* transitive bit needs to be set */ -}; - -#define IANA_EXT_COMMUNITIES { \ - { EXT_COMMUNITY_TWO_AS, EXT_COMMUNITY_ROUTE_TGT, 0 }, \ - { EXT_COMMUNITY_TWO_AS, EXT_COMMUNITY_ROUTE_ORIG, 0 }, \ - { EXT_COMMUNITY_TWO_AS, EXT_COMMUNITY_OSPF_DOM_ID, 0 }, \ - { EXT_COMMUNITY_TWO_AS, EXT_COMMUNITY_BGP_COLLECT, 0 }, \ - { EXT_COMMUNITY_FOUR_AS, EXT_COMMUNITY_ROUTE_TGT, 0 }, \ - { EXT_COMMUNITY_FOUR_AS, EXT_COMMUNITY_ROUTE_ORIG, 0 }, \ - { EXT_COMMUNITY_IPV4, EXT_COMMUNITY_ROUTE_TGT, 0 }, \ - { EXT_COMMUNITY_IPV4, EXT_COMMUNITY_ROUTE_ORIG, 0 }, \ - { EXT_COMMUNITY_IPV4, EXT_COMMUNITY_OSPF_RTR_ID, 0 }, \ - { EXT_COMMUNITY_OPAQUE, EXT_COMMUNITY_OSPF_RTR_TYPE, 0 } \ + const char *subname; +}; + +#define IANA_EXT_COMMUNITIES { \ + { EXT_COMMUNITY_TRANS_TWO_AS, 0x02, "rt" }, \ + { EXT_COMMUNITY_TRANS_TWO_AS, 0x03, "soo" }, \ + { EXT_COMMUNITY_TRANS_TWO_AS, 0x05, "odi" }, \ + { EXT_COMMUNITY_TRANS_TWO_AS, 0x08, "bdc" }, \ + { EXT_COMMUNITY_TRANS_TWO_AS, 0x09, "srcas" }, \ + { EXT_COMMUNITY_TRANS_TWO_AS, 0x0a, "l2vid" }, \ + \ + { EXT_COMMUNITY_TRANS_FOUR_AS, 0x02, "rt" }, \ + { EXT_COMMUNITY_TRANS_FOUR_AS, 0x03, "soo" }, \ + { EXT_COMMUNITY_TRANS_FOUR_AS, 0x05, "odi" }, \ + { EXT_COMMUNITY_TRANS_FOUR_AS, 0x08, "bdc" }, \ + { EXT_COMMUNITY_TRANS_FOUR_AS, 0x09, "srcas" }, \ + \ + { EXT_COMMUNITY_TRANS_IPV4, 0x02, "rt" }, \ + { EXT_COMMUNITY_TRANS_IPV4, 0x03, "soo" }, \ + { EXT_COMMUNITY_TRANS_IPV4, 0x05, "odi" }, \ + { EXT_COMMUNITY_TRANS_IPV4, 0x07, "ori" }, \ + { EXT_COMMUNITY_TRANS_IPV4, 0x0a, "l2vid" }, \ + { EXT_COMMUNITY_TRANS_IPV4, 0x0b, "vrfri" }, \ + \ + { EXT_COMMUNITY_TRANS_OPAQUE, 0x06, "ort" }, \ + { EXT_COMMUNITY_TRANS_OPAQUE, 0x0d, "defgw" }, \ + \ + { EXT_COMMUNITY_NON_TRANS_OPAQUE, 0x00, "ovs" }, \ + \ + { EXT_COMMUNITY_TRANS_EVPN, 0x00, "mac-mob" }, \ + { EXT_COMMUNITY_TRANS_EVPN, 0x01, "esi-lab" }, \ + { EXT_COMMUNITY_TRANS_EVPN, 0x02, "esi-rt" }, \ } +extern const struct ext_comm_pairs iana_ext_comms[]; struct filter_prefix { struct bgpd_addr addr; @@ -1079,7 +1103,7 @@ const char *log_in6addr(const struct in6_addr *); const char *log_sockaddr(struct sockaddr *); const char *log_as(u_int32_t); const char *log_rd(u_int64_t); -const char *log_ext_subtype(u_int8_t); +const char *log_ext_subtype(u_int8_t, u_int8_t); const char *log_shutcomm(const char *); int aspath_snprint(char *, size_t, void *, u_int16_t); int aspath_asprint(char **, void *, u_int16_t); diff --git a/usr.sbin/bgpd/kroute.c b/usr.sbin/bgpd/kroute.c index 138f7684a2d..8a8a0b04593 100644 --- a/usr.sbin/bgpd/kroute.c +++ b/usr.sbin/bgpd/kroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kroute.c,v 1.213 2017/05/28 15:16:33 henning Exp $ */ +/* $OpenBSD: kroute.c,v 1.214 2017/05/31 10:44:00 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -1281,6 +1281,10 @@ kr_redistribute(int type, struct ktable *kt, struct kroute *kr) kr->flags |= F_REDISTRIBUTED; sendit: + log_debug("kr_redistribute: %s (%s)", inet_ntoa(kr->prefix), + type == IMSG_NETWORK_ADD ? "IMSG_NETWORK_ADD" : + "IMSG_NETWORK_REMOVE"); + bzero(&net, sizeof(net)); net.prefix.aid = AID_INET; net.prefix.v4.s_addr = kr->prefix.s_addr; @@ -1350,6 +1354,11 @@ kr_redistribute6(int type, struct ktable *kt, struct kroute6 *kr6) } else kr6->flags |= F_REDISTRIBUTED; sendit: + log_debug("kr_redistribute6: %s/%u (%s)", + log_in6addr(&kr6->prefix), kr6->prefixlen, + type == IMSG_NETWORK_ADD ? "IMSG_NETWORK_ADD" : + "IMSG_NETWORK_REMOVE"); + bzero(&net, sizeof(net)); net.prefix.aid = AID_INET6; memcpy(&net.prefix.v6, &kr6->prefix, sizeof(struct in6_addr)); @@ -1389,9 +1398,13 @@ kr_reload(void) if (hasdyn) { /* only evaluate the full tree if we need */ RB_FOREACH(kr, kroute_tree, &kt->krt) - kr_redistribute(IMSG_NETWORK_ADD, kt, &kr->r); + if(!(kr->r.flags & F_DOWN)) + kr_redistribute(IMSG_NETWORK_ADD, + kt, &kr->r); RB_FOREACH(kr6, kroute6_tree, &kt->krt6) - kr_redistribute6(IMSG_NETWORK_ADD, kt, &kr6->r); + if(!(kr6->r.flags & F_DOWN)) + kr_redistribute6(IMSG_NETWORK_ADD, + kt, &kr6->r); } } @@ -2502,6 +2515,10 @@ if_change(u_short ifindex, int flags, struct if_data *ifd) if (kt == NULL) continue; + kr_redistribute(reachable ? + IMSG_NETWORK_ADD : IMSG_NETWORK_REMOVE, + kt, &(kkr->kr->r)); + knexthop_track(kt, kkr->kr); } LIST_FOREACH(kkr6, &kif->kroute6_l, entry) { @@ -2513,6 +2530,10 @@ if_change(u_short ifindex, int flags, struct if_data *ifd) if (kt == NULL) continue; + kr_redistribute6(reachable ? + IMSG_NETWORK_ADD : IMSG_NETWORK_REMOVE, + kt, &(kkr6->kr->r)); + knexthop_track(kt, kkr6->kr); } } diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y index 331f04e7931..3359fcd1340 100644 --- a/usr.sbin/bgpd/parse.y +++ b/usr.sbin/bgpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.307 2017/05/29 07:49:27 phessler Exp $ */ +/* $OpenBSD: parse.y,v 1.308 2017/05/31 10:44:00 claudio Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -150,7 +150,7 @@ int getcommunity(char *); int parsecommunity(struct filter_community *, char *); int64_t getlargecommunity(char *); int parselargecommunity(struct filter_largecommunity *, char *); -int parsesubtype(char *); +int parsesubtype(char *, int *, int *); int parseextvalue(char *, u_int32_t *); int parseextcommunity(struct filter_extcommunity *, char *, char *); @@ -871,13 +871,13 @@ rdomainopts : RD STRING { } rd = betoh64(rd) & 0xffffffffffffULL; switch (ext.type) { - case EXT_COMMUNITY_TWO_AS: + case EXT_COMMUNITY_TRANS_TWO_AS: rd |= (0ULL << 48); break; - case EXT_COMMUNITY_IPV4: + case EXT_COMMUNITY_TRANS_IPV4: rd |= (1ULL << 48); break; - case EXT_COMMUNITY_FOUR_AS: + case EXT_COMMUNITY_TRANS_FOUR_AS: rd |= (2ULL << 48); break; default: @@ -3089,26 +3089,23 @@ parselargecommunity(struct filter_largecommunity *c, char *s) } int -parsesubtype(char *type) +parsesubtype(char *name, int *type, int *subtype) { - /* this has to be sorted always */ - static const struct keywords keywords[] = { - { "bdc", EXT_COMMUNITY_BGP_COLLECT }, - { "odi", EXT_COMMUNITY_OSPF_DOM_ID }, - { "ori", EXT_COMMUNITY_OSPF_RTR_ID }, - { "ort", EXT_COMMUNITY_OSPF_RTR_TYPE }, - { "rt", EXT_COMMUNITY_ROUTE_TGT }, - { "soo", EXT_COMMUNITY_ROUTE_ORIG } - }; - const struct keywords *p; - - p = bsearch(type, keywords, sizeof(keywords)/sizeof(keywords[0]), - sizeof(keywords[0]), kw_cmp); + const struct ext_comm_pairs *cp; + int found = 0; - if (p) - return (p->k_val); - else - return (-1); + for (cp = iana_ext_comms; cp->subname != NULL; cp++) { + if (strcmp(name, cp->subname) == 0) { + if (found == 0) { + *type = cp->type; + *subtype = cp->subtype; + } + found++; + } + } + if (found > 1) + *type = -1; + return (found); } int @@ -3127,10 +3124,10 @@ parseextvalue(char *s, u_int32_t *v) return (-1); } *v = uval; - if (uval > USHRT_MAX) - return (EXT_COMMUNITY_FOUR_AS); + if (uval <= USHRT_MAX) + return (EXT_COMMUNITY_TRANS_TWO_AS); else - return (EXT_COMMUNITY_TWO_AS); + return (EXT_COMMUNITY_TRANS_FOUR_AS); } else if (strchr(p + 1, '.') == NULL) { /* AS_DOT number (4-byte) */ *p++ = '\0'; @@ -3145,7 +3142,7 @@ parseextvalue(char *s, u_int32_t *v) return (-1); } *v = uval | (uvalh << 16); - return (EXT_COMMUNITY_FOUR_AS); + return (EXT_COMMUNITY_TRANS_FOUR_AS); } else { /* more than one dot -> IP address */ if (inet_aton(s, &ip) == 0) { @@ -3153,7 +3150,7 @@ parseextvalue(char *s, u_int32_t *v) return (-1); } *v = ip.s_addr; - return (EXT_COMMUNITY_IPV4); + return (EXT_COMMUNITY_TRANS_IPV4); } return (-1); } @@ -3161,75 +3158,90 @@ parseextvalue(char *s, u_int32_t *v) int parseextcommunity(struct filter_extcommunity *c, char *t, char *s) { - const struct ext_comm_pairs iana[] = IANA_EXT_COMMUNITIES; + const struct ext_comm_pairs *cp; const char *errstr; u_int64_t ullval; u_int32_t uval; char *p, *ep; - unsigned int i; int type, subtype; - if ((subtype = parsesubtype(t)) == -1) { + if (parsesubtype(t, &type, &subtype) == 0) { yyerror("Bad ext-community unknown type"); return (-1); } - if ((p = strchr(s, ':')) == NULL) { - type = EXT_COMMUNITY_OPAQUE, - errno = 0; - ullval = strtoull(s, &ep, 0); - if (s[0] == '\0' || *ep != '\0') { - yyerror("Bad ext-community bad value"); - return (-1); - } - if (errno == ERANGE && ullval > EXT_COMMUNITY_OPAQUE_MAX) { - yyerror("Bad ext-community value to big"); + switch (type) { + case -1: + if ((p = strchr(s, ':')) == NULL) { + yyerror("Bad ext-community %s is %s", s, errstr); return (-1); } - c->data.ext_opaq = ullval; - } else { *p++ = '\0'; if ((type = parseextvalue(s, &uval)) == -1) return (-1); switch (type) { - case EXT_COMMUNITY_TWO_AS: + case EXT_COMMUNITY_TRANS_TWO_AS: ullval = strtonum(p, 0, UINT_MAX, &errstr); break; - case EXT_COMMUNITY_IPV4: - case EXT_COMMUNITY_FOUR_AS: + case EXT_COMMUNITY_TRANS_IPV4: + case EXT_COMMUNITY_TRANS_FOUR_AS: ullval = strtonum(p, 0, USHRT_MAX, &errstr); break; default: fatalx("parseextcommunity: unexpected result"); } if (errstr) { - yyerror("Bad ext-community %s is %s", p, - errstr); + yyerror("Bad ext-community %s is %s", p, errstr); return (-1); } switch (type) { - case EXT_COMMUNITY_TWO_AS: + case EXT_COMMUNITY_TRANS_TWO_AS: c->data.ext_as.as = uval; c->data.ext_as.val = ullval; break; - case EXT_COMMUNITY_IPV4: + case EXT_COMMUNITY_TRANS_IPV4: c->data.ext_ip.addr.s_addr = uval; c->data.ext_ip.val = ullval; break; - case EXT_COMMUNITY_FOUR_AS: + case EXT_COMMUNITY_TRANS_FOUR_AS: c->data.ext_as4.as4 = uval; c->data.ext_as4.val = ullval; break; } + break; + case EXT_COMMUNITY_TRANS_OPAQUE: + case EXT_COMMUNITY_TRANS_EVPN: + errno = 0; + ullval = strtoull(s, &ep, 0); + if (s[0] == '\0' || *ep != '\0') { + yyerror("Bad ext-community bad value"); + return (-1); + } + if (errno == ERANGE && ullval > EXT_COMMUNITY_OPAQUE_MAX) { + yyerror("Bad ext-community value to big"); + return (-1); + } + c->data.ext_opaq = ullval; + break; + case EXT_COMMUNITY_NON_TRANS_OPAQUE: + if (strcmp(s, "valid") == 0) + c->data.ext_opaq = EXT_COMMUNITY_OVS_VALID; + else if (strcmp(s, "invalid") == 0) + c->data.ext_opaq = EXT_COMMUNITY_OVS_INVALID; + else if (strcmp(s, "not-found") == 0) + c->data.ext_opaq = EXT_COMMUNITY_OVS_NOTFOUND; + else { + yyerror("Bad ext-community %s is %s", s, errstr); + return (-1); + } + break; } c->type = type; c->subtype = subtype; /* verify type/subtype combo */ - for (i = 0; i < sizeof(iana)/sizeof(iana[0]); i++) { - if (iana[i].type == type && iana[i].subtype == subtype) { - if (iana[i].transitive) - c->type |= EXT_COMMUNITY_TRANSITIVE; + for (cp = iana_ext_comms; cp->subname != NULL; cp++) { + if (cp->type == type && cp->subtype == subtype) { c->flags |= EXT_COMMUNITY_FLAG_VALID; return (0); } diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c index 9e5710a1362..afa96e40bb4 100644 --- a/usr.sbin/bgpd/printconf.c +++ b/usr.sbin/bgpd/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.103 2017/05/27 18:12:23 phessler Exp $ */ +/* $OpenBSD: printconf.c,v 1.104 2017/05/31 10:44:00 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -145,25 +145,39 @@ print_largecommunity(int64_t as, int64_t ld1, int64_t ld2) void print_extcommunity(struct filter_extcommunity *c) { - switch (c->type & EXT_COMMUNITY_VALUE) { - case EXT_COMMUNITY_TWO_AS: - printf("%s %hu:%u ", log_ext_subtype(c->subtype), - c->data.ext_as.as, c->data.ext_as.val); + printf("%s ", log_ext_subtype(c->type, c->subtype)); + + switch (c->type) { + case EXT_COMMUNITY_TRANS_TWO_AS: + printf("%hu:%u ", c->data.ext_as.as, c->data.ext_as.val); + break; + case EXT_COMMUNITY_TRANS_IPV4: + printf("%s:%u ", inet_ntoa(c->data.ext_ip.addr), + c->data.ext_ip.val); break; - case EXT_COMMUNITY_IPV4: - printf("%s %s:%u ", log_ext_subtype(c->subtype), - inet_ntoa(c->data.ext_ip.addr), c->data.ext_ip.val); + case EXT_COMMUNITY_TRANS_FOUR_AS: + printf("%s:%u ", log_as(c->data.ext_as4.as4), + c->data.ext_as.val); break; - case EXT_COMMUNITY_FOUR_AS: - printf("%s %s:%u ", log_ext_subtype(c->subtype), - log_as(c->data.ext_as4.as4), c->data.ext_as.val); + case EXT_COMMUNITY_TRANS_OPAQUE: + case EXT_COMMUNITY_TRANS_EVPN: + printf("0x%llx ", c->data.ext_opaq); break; - case EXT_COMMUNITY_OPAQUE: - printf("%s 0x%llx ", log_ext_subtype(c->subtype), - c->data.ext_opaq); + case EXT_COMMUNITY_NON_TRANS_OPAQUE: + switch (c->data.ext_opaq) { + case EXT_COMMUNITY_OVS_VALID: + printf("valid "); + break; + case EXT_COMMUNITY_OVS_NOTFOUND: + printf("not-found "); + break; + case EXT_COMMUNITY_OVS_INVALID: + printf("invalid "); + break; + } break; default: - printf("0x%x 0x%llx ", c->type, c->data.ext_opaq); + printf("0x%llx ", c->data.ext_opaq); break; } } diff --git a/usr.sbin/bgpd/rde_attr.c b/usr.sbin/bgpd/rde_attr.c index 179849d74ae..c53c211ef79 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.99 2017/05/30 18:08:15 benno Exp $ */ +/* $OpenBSD: rde_attr.c,v 1.100 2017/05/31 10:44:00 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org> @@ -1253,23 +1253,23 @@ community_ext_conv(struct filter_extcommunity *c, u_int16_t neighas, com = (u_int64_t)c->type << 56; switch (c->type & EXT_COMMUNITY_VALUE) { - case EXT_COMMUNITY_TWO_AS: + case EXT_COMMUNITY_TRANS_TWO_AS: com |= (u_int64_t)c->subtype << 48; com |= (u_int64_t)c->data.ext_as.as << 32; com |= c->data.ext_as.val; break; - case EXT_COMMUNITY_IPV4: + case EXT_COMMUNITY_TRANS_IPV4: com |= (u_int64_t)c->subtype << 48; ip = ntohl(c->data.ext_ip.addr.s_addr); com |= (u_int64_t)ip << 16; com |= c->data.ext_ip.val; break; - case EXT_COMMUNITY_FOUR_AS: + case EXT_COMMUNITY_TRANS_FOUR_AS: com |= (u_int64_t)c->subtype << 48; com |= (u_int64_t)c->data.ext_as4.as4 << 16; com |= c->data.ext_as4.val; break; - case EXT_COMMUNITY_OPAQUE: + case EXT_COMMUNITY_TRANS_OPAQUE: com |= (u_int64_t)c->subtype << 48; com |= c->data.ext_opaq & EXT_COMMUNITY_OPAQUE_MAX; break; @@ -1298,10 +1298,10 @@ community_ext_matchone(struct filter_extcommunity *c, u_int16_t neighas, return (0); switch (c->type & EXT_COMMUNITY_VALUE) { - case EXT_COMMUNITY_TWO_AS: - case EXT_COMMUNITY_IPV4: - case EXT_COMMUNITY_FOUR_AS: - case EXT_COMMUNITY_OPAQUE: + case EXT_COMMUNITY_TRANS_TWO_AS: + case EXT_COMMUNITY_TRANS_IPV4: + case EXT_COMMUNITY_TRANS_FOUR_AS: + case EXT_COMMUNITY_TRANS_OPAQUE: com = (u_int64_t)c->subtype << 48; mask = 0xffULL << 48; if ((com & mask) != (community & mask)) @@ -1317,7 +1317,7 @@ community_ext_matchone(struct filter_extcommunity *c, u_int16_t neighas, switch (c->type & EXT_COMMUNITY_VALUE) { - case EXT_COMMUNITY_TWO_AS: + case EXT_COMMUNITY_TRANS_TWO_AS: com = (u_int64_t)c->data.ext_as.as << 32; mask = 0xffffULL << 32; if ((com & mask) != (community & mask)) @@ -1328,7 +1328,7 @@ community_ext_matchone(struct filter_extcommunity *c, u_int16_t neighas, if ((com & mask) == (community & mask)) return (1); break; - case EXT_COMMUNITY_IPV4: + case EXT_COMMUNITY_TRANS_IPV4: ip = ntohl(c->data.ext_ip.addr.s_addr); com = (u_int64_t)ip << 16; mask = 0xffffffff0000ULL; @@ -1340,7 +1340,7 @@ community_ext_matchone(struct filter_extcommunity *c, u_int16_t neighas, if ((com & mask) == (community & mask)) return (1); break; - case EXT_COMMUNITY_FOUR_AS: + case EXT_COMMUNITY_TRANS_FOUR_AS: com = (u_int64_t)c->data.ext_as4.as4 << 16; mask = 0xffffffffULL << 16; if ((com & mask) != (community & mask)) @@ -1351,7 +1351,7 @@ community_ext_matchone(struct filter_extcommunity *c, u_int16_t neighas, if ((com & mask) == (community & mask)) return (1); break; - case EXT_COMMUNITY_OPAQUE: + case EXT_COMMUNITY_TRANS_OPAQUE: com = c->data.ext_opaq & EXT_COMMUNITY_OPAQUE_MAX; mask = EXT_COMMUNITY_OPAQUE_MAX; if ((com & mask) == (community & mask)) diff --git a/usr.sbin/bgpd/util.c b/usr.sbin/bgpd/util.c index f6b264101fe..bcf257e982b 100644 --- a/usr.sbin/bgpd/util.c +++ b/usr.sbin/bgpd/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.24 2017/01/24 04:22:42 benno Exp $ */ +/* $OpenBSD: util.c,v 1.25 2017/05/31 10:44:00 claudio Exp $ */ /* * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org> @@ -112,17 +112,17 @@ log_rd(u_int64_t rd) rd = betoh64(rd); switch (rd >> 48) { - case EXT_COMMUNITY_TWO_AS: + case EXT_COMMUNITY_TRANS_TWO_AS: u32 = rd & 0xffffffff; u16 = (rd >> 32) & 0xffff; snprintf(buf, sizeof(buf), "rd %hu:%u", u16, u32); break; - case EXT_COMMUNITY_FOUR_AS: + case EXT_COMMUNITY_TRANS_FOUR_AS: u32 = (rd >> 16) & 0xffffffff; u16 = rd & 0xffff; snprintf(buf, sizeof(buf), "rd %s:%hu", log_as(u32), u16); break; - case EXT_COMMUNITY_IPV4: + case EXT_COMMUNITY_TRANS_IPV4: u32 = (rd >> 16) & 0xffffffff; u16 = rd & 0xffff; addr.s_addr = htonl(u32); @@ -134,30 +134,22 @@ log_rd(u_int64_t rd) return (buf); } +const struct ext_comm_pairs iana_ext_comms[] = IANA_EXT_COMMUNITIES; + /* NOTE: this function does not check if the type/subtype combo is * actually valid. */ const char * -log_ext_subtype(u_int8_t subtype) +log_ext_subtype(u_int8_t type, u_int8_t subtype) { static char etype[6]; + const struct ext_comm_pairs *cp; - switch (subtype) { - case EXT_COMMUNITY_ROUTE_TGT: - return ("rt"); /* route target */ - case EXT_COMMUNITY_ROUTE_ORIG: - return ("soo"); /* source of origin */ - case EXT_COMMUNITY_OSPF_DOM_ID: - return ("odi"); /* ospf domain id */ - case EXT_COMMUNITY_OSPF_RTR_TYPE: - return ("ort"); /* ospf route type */ - case EXT_COMMUNITY_OSPF_RTR_ID: - return ("ori"); /* ospf router id */ - case EXT_COMMUNITY_BGP_COLLECT: - return ("bdc"); /* bgp data collection */ - default: - snprintf(etype, sizeof(etype), "[%u]", subtype); - return (etype); + for (cp = iana_ext_comms; cp->subname != NULL; cp++) { + if (type == cp->type && subtype == cp->subtype) + return (cp->subname); } + snprintf(etype, sizeof(etype), "[%u]", subtype); + return (etype); } const char * |