summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2017-05-31 10:44:01 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2017-05-31 10:44:01 +0000
commit958954d63c3be5782851b75d730e224de82a6026 (patch)
tree874ee9c056cea591e059811db7a7c1beb41037df
parent6f45ba7aa33384883e5f9b009f8820c1b56f58d7 (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.h80
-rw-r--r--usr.sbin/bgpd/kroute.c27
-rw-r--r--usr.sbin/bgpd/parse.y122
-rw-r--r--usr.sbin/bgpd/printconf.c44
-rw-r--r--usr.sbin/bgpd/rde_attr.c26
-rw-r--r--usr.sbin/bgpd/util.c34
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 *