summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bgpctl
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2019-02-11 15:47:55 +0000
committerclaudio <claudio@openbsd.org>2019-02-11 15:47:55 +0000
commita73789d3d0423310455c6d09fa097e496e0b58a0 (patch)
tree7c1ffba07a6fa0cab65b0e60f58032b8ea3a01f1 /usr.sbin/bgpctl
parentThe definition of VPNs in bgpd was never super elegant. The 'depend on (diff)
downloadwireguard-openbsd-a73789d3d0423310455c6d09fa097e496e0b58a0.tar.xz
wireguard-openbsd-a73789d3d0423310455c6d09fa097e496e0b58a0.zip
Adjust to last bgpd commit changing the MPLS VPN configuration.
Sync the community handling code to be in sync with parsing code of bgpd. To inject networks into MPLS VPN it is required to specify the route distinguisher as part of the attributes. With and OK dlg@, OK denis@
Diffstat (limited to 'usr.sbin/bgpctl')
-rw-r--r--usr.sbin/bgpctl/bgpctl.c15
-rw-r--r--usr.sbin/bgpctl/parser.c498
-rw-r--r--usr.sbin/bgpctl/parser.h4
3 files changed, 268 insertions, 249 deletions
diff --git a/usr.sbin/bgpctl/bgpctl.c b/usr.sbin/bgpctl/bgpctl.c
index 22eb0deda84..d7423e04237 100644
--- a/usr.sbin/bgpctl/bgpctl.c
+++ b/usr.sbin/bgpctl/bgpctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpctl.c,v 1.228 2019/01/20 23:30:15 claudio Exp $ */
+/* $OpenBSD: bgpctl.c,v 1.229 2019/02/11 15:47:55 claudio Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@@ -346,7 +346,7 @@ main(int argc, char *argv[])
bzero(&net, sizeof(net));
net.prefix = res->addr;
net.prefixlen = res->prefixlen;
- net.rtableid = tableid;
+ net.rd = res->rd;
/* attribute sets are not supported */
if (res->action == NETWORK_ADD) {
imsg_compose(ibuf, IMSG_NETWORK_ADD, 0, 0, -1,
@@ -927,7 +927,7 @@ show_fib_head(void)
printf("flags: "
"* = valid, B = BGP, C = Connected, S = Static, D = Dynamic\n");
printf(" "
- "N = BGP Nexthop reachable via this route R = redistributed\n");
+ "N = BGP Nexthop reachable via this route\n");
printf(" r = reject route, b = blackhole route\n\n");
printf("flags prio destination gateway\n");
}
@@ -969,11 +969,6 @@ show_fib_flags(u_int16_t flags)
else
printf(" ");
- if (flags & F_REDISTRIBUTED)
- printf("R");
- else
- printf(" ");
-
if (flags & F_REJECT && flags & F_BLACKHOLE)
printf("f");
else if (flags & F_REJECT)
@@ -1983,7 +1978,7 @@ network_bulk(struct parse_result *res)
errx(1, "bad prefix: %s", b);
net.prefix = h;
net.prefixlen = len;
- net.rtableid = tableid;
+ net.rd = res->rd;
if (res->action == NETWORK_BULK_ADD) {
imsg_compose(ibuf, IMSG_NETWORK_ADD,
@@ -2128,7 +2123,7 @@ network_mrt_dump(struct mrt_rib *mr, struct mrt_peer *mp, void *arg)
net.prefix = ctl.prefix;
net.prefixlen = ctl.prefixlen;
net.type = NETWORK_MRTCLONE;
- /* XXX rtableid */
+ /* XXX rd can't be set and will be 0 */
imsg_compose(ibuf, IMSG_NETWORK_ADD, 0, 0, -1,
&net, sizeof(net));
diff --git a/usr.sbin/bgpctl/parser.c b/usr.sbin/bgpctl/parser.c
index 44d73d41fb5..63f70ac6e4d 100644
--- a/usr.sbin/bgpctl/parser.c
+++ b/usr.sbin/bgpctl/parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.c,v 1.89 2019/01/20 23:30:15 claudio Exp $ */
+/* $OpenBSD: parser.c,v 1.90 2019/02/11 15:47:55 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -58,6 +58,7 @@ enum token_type {
PREPNBR,
PREPSELF,
WEIGHT,
+ RD,
FAMILY,
GETOPT,
RTABLE,
@@ -374,6 +375,11 @@ static const struct token t_network_show[] = {
{ ENDTOKEN, "", NONE, NULL}
};
+static const struct token t_rd[] = {
+ { RD, "", NONE, t_set},
+ { ENDTOKEN, "", NONE, NULL}
+};
+
static const struct token t_set[] = {
{ NOTOKEN, "", NONE, NULL},
{ KEYWORD, "community", NONE, t_community},
@@ -386,6 +392,7 @@ static const struct token t_set[] = {
{ KEYWORD, "pftable", NONE, t_pftable},
{ KEYWORD, "prepend-neighbor", NONE, t_prepnbr},
{ KEYWORD, "prepend-self", NONE, t_prepself},
+ { KEYWORD, "rd", NONE, t_rd},
{ KEYWORD, "weight", NONE, t_weight},
{ KEYWORD, "add", NETWORK_BULK_ADD, NULL},
{ KEYWORD, "delete", NETWORK_BULK_REMOVE, NULL},
@@ -493,18 +500,14 @@ static struct parse_result res;
const struct token *match_token(int *argc, char **argv[],
const struct token []);
void show_valid_args(const struct token []);
-int parse_addr(const char *, struct bgpd_addr *);
-int parse_asnum(const char *, size_t, u_int32_t *);
-int parse_number(const char *, struct parse_result *,
- enum token_type);
-int parse_community(const char *, struct parse_result *);
-int parsesubtype(const char *, u_int8_t *, u_int8_t *);
-int parseextvalue(const char *, u_int32_t *);
-u_int parseextcommunity(const char *, struct parse_result *);
-int parse_largecommunity(const char *,
- struct parse_result *);
-int parse_nexthop(const char *, struct parse_result *);
-int bgpctl_getopt(int *, char **[], int);
+
+int parse_addr(const char *, struct bgpd_addr *);
+int parse_asnum(const char *, size_t, u_int32_t *);
+int parse_number(const char *, struct parse_result *, enum token_type);
+void parsecommunity(struct filter_community *c, int type, char *s);
+int parseextcommunity(struct filter_community *c, const char *t, char *s);
+int parse_nexthop(const char *, struct parse_result *);
+int bgpctl_getopt(int *, char **[], int);
struct parse_result *
parse(int argc, char *argv[])
@@ -675,8 +678,25 @@ match_token(int *argc, char **argv[], const struct token table[])
}
break;
case COMMUNITY:
- if (word != NULL && wordlen > 0 &&
- parse_community(word, &res)) {
+ case LARGE_COMMUNITY:
+ if (word != NULL && wordlen > 0) {
+ int type = COMMUNITY_TYPE_BASIC;
+ char *p = strdup(word);
+
+ if (p == NULL)
+ err(1, NULL);
+ if (table[i].type == LARGE_COMMUNITY)
+ type = COMMUNITY_TYPE_LARGE;
+ parsecommunity(&res.community,
+ COMMUNITY_TYPE_BASIC, p);
+ free(p);
+
+ if ((fs = calloc(1, sizeof(*fs))) == NULL)
+ err(1, NULL);
+ fs->type = ACTION_SET_COMMUNITY;
+ fs->action.community = res.community;
+ TAILQ_INSERT_TAIL(&res.set, fs, entry);
+
match++;
t = &table[i];
}
@@ -684,24 +704,62 @@ match_token(int *argc, char **argv[], const struct token table[])
case EXTCOM_SUBTYPE:
if (word != NULL && strncmp(word, table[i].keyword,
wordlen) == 0) {
- if (parsesubtype(word, &res.community.c.e.type,
- &res.community.c.e.subtype) == 0)
- errx(1, "Bad ext-community unknown "
- "type");
+ res.ext_comm_subtype = table[i].keyword;
match++;
t = &table[i];
}
break;
case EXTCOMMUNITY:
- if (word != NULL && wordlen > 0 &&
- parseextcommunity(word, &res)) {
+ if (word != NULL && wordlen > 0) {
+ char *p = strdup(word);
+
+ if (p == NULL)
+ err(1, NULL);
+ parseextcommunity(&res.community,
+ res.ext_comm_subtype, p);
+ free(p);
+
+ if ((fs = calloc(1, sizeof(*fs))) == NULL)
+ err(1, NULL);
+ fs->type = ACTION_SET_COMMUNITY;
+ fs->action.community = res.community;
+ TAILQ_INSERT_TAIL(&res.set, fs, entry);
+
match++;
t = &table[i];
}
break;
- case LARGE_COMMUNITY:
- if (word != NULL && wordlen > 0 &&
- parse_largecommunity(word, &res)) {
+ case RD:
+ if (word != NULL && wordlen > 0) {
+ char *p = strdup(word);
+ struct filter_community ext;
+ u_int64_t rd;
+
+ if (p == NULL)
+ err(1, NULL);
+ parseextcommunity(&ext, "rt", p);
+ free(p);
+
+ switch (ext.c.e.type) {
+ case EXT_COMMUNITY_TRANS_TWO_AS:
+ rd = (0ULL << 48);
+ rd |= (u_int64_t)ext.c.e.data1 << 32;
+ rd |= ext.c.e.data2 & 0xffffffff;
+ break;
+ case EXT_COMMUNITY_TRANS_IPV4:
+ rd = (1ULL << 48);
+ rd |= (u_int64_t)ext.c.e.data1 << 16;
+ rd |= ext.c.e.data2 & 0xffff;
+ break;
+ case EXT_COMMUNITY_TRANS_FOUR_AS:
+ rd = (2ULL << 48);
+ rd |= (u_int64_t)ext.c.e.data1 << 16;
+ rd |= ext.c.e.data2 & 0xffff;
+ break;
+ default:
+ errx(1, "bad encoding of rd");
+ }
+ res.rd = htobe64(rd);
match++;
t = &table[i];
}
@@ -823,11 +881,14 @@ show_valid_args(const struct token table[])
case COMMUNITY:
fprintf(stderr, " <community>\n");
break;
+ case LARGE_COMMUNITY:
+ fprintf(stderr, " <large-community>\n");
+ break;
case EXTCOMMUNITY:
fprintf(stderr, " <extended-community>\n");
break;
- case LARGE_COMMUNITY:
- fprintf(stderr, " <large-community>\n");
+ case RD:
+ fprintf(stderr, " <route-distinguisher>\n");
break;
case LOCALPREF:
case MED:
@@ -1035,95 +1096,118 @@ parse_number(const char *word, struct parse_result *r, enum token_type type)
return (1);
}
-static u_int32_t
-getcommunity(const char *s, int large, u_int8_t *flag)
+static void
+getcommunity(char *s, int large, u_int32_t *val, u_int8_t *flag)
{
int64_t max = USHRT_MAX;
const char *errstr;
- u_int32_t uval;
+ *flag = 0;
+ *val = 0;
if (strcmp(s, "*") == 0) {
*flag = COMMUNITY_ANY;
- return (0);
+ return;
+ } else if (strcmp(s, "neighbor-as") == 0) {
+ *flag = COMMUNITY_NEIGHBOR_AS;
+ return;
+ } else if (strcmp(s, "local-as") == 0) {
+ *flag = COMMUNITY_LOCAL_AS;
+ return;
}
-
if (large)
max = UINT_MAX;
-
- uval = strtonum(s, 0, max, &errstr);
+ *val = strtonum(s, 0, max, &errstr);
if (errstr)
- errx(1, "Community is %s: %s", errstr, s);
-
- *flag = 0;
- return (uval);
+ errx(1, "Community %s is %s (max: %llu)", s, errstr, max);
}
-int
-parse_community(const char *word, struct parse_result *r)
+static void
+setcommunity(struct filter_community *c, u_int32_t as, u_int32_t data,
+ u_int8_t asflag, u_int8_t dataflag)
{
- struct filter_set *fs;
- char *p;
- u_int32_t as, type;
- u_int8_t asflag, tflag;
+ memset(c, 0, sizeof(*c));
+ c->type = COMMUNITY_TYPE_BASIC;
+ c->dflag1 = asflag;
+ c->dflag2 = dataflag;
+ c->c.b.data1 = as;
+ c->c.b.data2 = data;
+}
- /* Well-known communities */
- if (strcasecmp(word, "GRACEFUL_SHUTDOWN") == 0) {
- as = COMMUNITY_WELLKNOWN;
- type = COMMUNITY_GRACEFUL_SHUTDOWN;
- goto done;
- } else if (strcasecmp(word, "NO_EXPORT") == 0) {
- as = COMMUNITY_WELLKNOWN;
- type = COMMUNITY_NO_EXPORT;
- goto done;
- } else if (strcasecmp(word, "NO_ADVERTISE") == 0) {
- as = COMMUNITY_WELLKNOWN;
- type = COMMUNITY_NO_ADVERTISE;
- goto done;
- } else if (strcasecmp(word, "NO_EXPORT_SUBCONFED") == 0) {
- as = COMMUNITY_WELLKNOWN;
- type = COMMUNITY_NO_EXPSUBCONFED;
- goto done;
- } else if (strcasecmp(word, "NO_PEER") == 0) {
- as = COMMUNITY_WELLKNOWN;
- type = COMMUNITY_NO_PEER;
- goto done;
- } else if (strcasecmp(word, "BLACKHOLE") == 0) {
- as = COMMUNITY_WELLKNOWN;
- type = COMMUNITY_BLACKHOLE;
- goto done;
- }
+static void
+parselargecommunity(struct filter_community *c, char *s)
+{
+ char *p, *q;
- if ((p = strchr(word, ':')) == NULL) {
- fprintf(stderr, "Bad community syntax\n");
- return (0);
- }
+ if ((p = strchr(s, ':')) == NULL)
+ errx(1, "Bad community syntax");
*p++ = 0;
- as = getcommunity(word, 0, &asflag);
- type = getcommunity(p, 0, &tflag);
+ if ((q = strchr(p, ':')) == NULL)
+ errx(1, "Bad community syntax");
+ *q++ = 0;
-done:
- if ((fs = calloc(1, sizeof(struct filter_set))) == NULL)
- err(1, NULL);
- fs->type = ACTION_SET_COMMUNITY;
- fs->action.community.type = COMMUNITY_TYPE_BASIC;
- fs->action.community.c.b.data1 = as;
- fs->action.community.c.b.data2 = type;
- fs->action.community.dflag1 = asflag;
- fs->action.community.dflag2 = tflag;
+ getcommunity(s, 1, &c->c.l.data1, &c->dflag1);
+ getcommunity(p, 1, &c->c.l.data2, &c->dflag2);
+ getcommunity(q, 1, &c->c.l.data3, &c->dflag3);
- r->community = fs->action.community;
+ c->type = COMMUNITY_TYPE_LARGE;
+}
- TAILQ_INSERT_TAIL(&r->set, fs, entry);
- return (1);
+void
+parsecommunity(struct filter_community *c, int type, char *s)
+{
+ char *p;
+ u_int32_t as, data;
+ u_int8_t asflag, dataflag;
+
+ if (type == COMMUNITY_TYPE_LARGE) {
+ parselargecommunity(c, s);
+ return;
+ }
+
+ /* Well-known communities */
+ if (strcasecmp(s, "GRACEFUL_SHUTDOWN") == 0) {
+ setcommunity(c, COMMUNITY_WELLKNOWN,
+ COMMUNITY_GRACEFUL_SHUTDOWN, 0, 0);
+ return;
+ } else if (strcasecmp(s, "NO_EXPORT") == 0) {
+ setcommunity(c, COMMUNITY_WELLKNOWN,
+ COMMUNITY_NO_EXPORT, 0, 0);
+ return;
+ } else if (strcasecmp(s, "NO_ADVERTISE") == 0) {
+ setcommunity(c, COMMUNITY_WELLKNOWN,
+ COMMUNITY_NO_ADVERTISE, 0, 0);
+ return;
+ } else if (strcasecmp(s, "NO_EXPORT_SUBCONFED") == 0) {
+ setcommunity(c, COMMUNITY_WELLKNOWN,
+ COMMUNITY_NO_EXPSUBCONFED, 0, 0);
+ return;
+ } else if (strcasecmp(s, "NO_PEER") == 0) {
+ setcommunity(c, COMMUNITY_WELLKNOWN,
+ COMMUNITY_NO_PEER, 0, 0);
+ return;
+ } else if (strcasecmp(s, "BLACKHOLE") == 0) {
+ setcommunity(c, COMMUNITY_WELLKNOWN,
+ COMMUNITY_BLACKHOLE, 0, 0);
+ return;
+ }
+
+ if ((p = strchr(s, ':')) == NULL)
+ errx(1, "Bad community syntax");
+ *p++ = 0;
+
+ getcommunity(s, 0, &as, &asflag);
+ getcommunity(p, 0, &data, &dataflag);
+ setcommunity(c, as, data, asflag, dataflag);
}
-int
-parsesubtype(const char *name, u_int8_t *type, u_int8_t *subtype)
+static int
+parsesubtype(const char *name, int *type, int *subtype)
{
const struct ext_comm_pairs *cp;
int found = 0;
+printf("%s: looking for %s\n", __func__, name);
for (cp = iana_ext_comms; cp->subname != NULL; cp++) {
if (strcmp(name, cp->subname) == 0) {
if (found == 0) {
@@ -1138,79 +1222,89 @@ parsesubtype(const char *name, u_int8_t *type, u_int8_t *subtype)
return (found);
}
-int
-parseextvalue(const char *s, u_int32_t *v)
+static int
+parseextvalue(int type, char *s, u_int32_t *v)
{
- const char *errstr;
+ const char *errstr;
char *p;
struct in_addr ip;
- u_int32_t uvalh = 0, uval;
+ u_int32_t uvalh, uval;
- if ((p = strchr(s, '.')) == NULL) {
+ if (type != -1) {
+ /* nothing */
+ } else if ((p = strchr(s, '.')) == NULL) {
/* AS_PLAIN number (4 or 2 byte) */
- uval = strtonum(s, 0, UINT_MAX, &errstr);
- if (errstr) {
- fprintf(stderr, "Bad ext-community: %s is %s\n", s,
- errstr);
- return (-1);
- }
- *v = uval;
- if (uval <= USHRT_MAX)
- return (EXT_COMMUNITY_TRANS_TWO_AS);
+ strtonum(s, 0, USHRT_MAX, &errstr);
+ if (errstr == NULL)
+ type = EXT_COMMUNITY_TRANS_TWO_AS;
else
- return (EXT_COMMUNITY_TRANS_FOUR_AS);
+ type = EXT_COMMUNITY_TRANS_FOUR_AS;
} else if (strchr(p + 1, '.') == NULL) {
/* AS_DOT number (4-byte) */
+ type = EXT_COMMUNITY_TRANS_FOUR_AS;
+ } else {
+ /* more than one dot -> IP address */
+ type = EXT_COMMUNITY_TRANS_IPV4;
+ }
+
+ switch (type) {
+ case EXT_COMMUNITY_TRANS_TWO_AS:
+ uval = strtonum(s, 0, USHRT_MAX, &errstr);
+ if (errstr)
+ errx(1, "Bad ext-community %s is %s", s, errstr);
+ *v = uval;
+ break;
+ case EXT_COMMUNITY_TRANS_FOUR_AS:
+ if ((p = strchr(s, '.')) == NULL) {
+ uval = strtonum(s, 0, UINT_MAX, &errstr);
+ if (errstr)
+ errx(1, "Bad ext-community %s is %s", s,
+ errstr);
+ *v = uval;
+ break;
+ }
*p++ = '\0';
uvalh = strtonum(s, 0, USHRT_MAX, &errstr);
- if (errstr) {
- fprintf(stderr, "Bad ext-community: %s is %s\n", s,
- errstr);
- return (-1);
- }
+ if (errstr)
+ errx(1, "Bad ext-community %s is %s", s, errstr);
uval = strtonum(p, 0, USHRT_MAX, &errstr);
- if (errstr) {
- fprintf(stderr, "Bad ext-community: %s is %s\n", p,
- errstr);
- return (-1);
- }
+ if (errstr)
+ errx(1, "Bad ext-community %s is %s", p, errstr);
*v = uval | (uvalh << 16);
- return (EXT_COMMUNITY_TRANS_FOUR_AS);
- } else {
- /* more than one dot -> IP address */
- if (inet_aton(s, &ip) == 0) {
- fprintf(stderr, "Bad ext-community: %s not parseable\n",
- s);
- return (-1);
- }
+ break;
+ case EXT_COMMUNITY_TRANS_IPV4:
+ if (inet_aton(s, &ip) == 0)
+ errx(1, "Bad ext-community %s not parseable", s);
*v = ntohl(ip.s_addr);
- return (EXT_COMMUNITY_TRANS_IPV4);
+ break;
+ default:
+ errx(1, "%s: unexpected type %d", __func__, type);
}
- return (-1);
+ return (type);
}
-u_int
-parseextcommunity(const char *word, struct parse_result *r)
+int
+parseextcommunity(struct filter_community *c, const char *t, char *s)
{
- struct filter_set *fs;
- const struct ext_comm_pairs *cp;
- const char *errstr;
- u_int64_t ullval;
- u_int32_t uval;
- char *p, *ep;
- int type;
+ const struct ext_comm_pairs *cp;
+ const char *errstr;
+ u_int64_t ullval;
+ u_int32_t uval;
+ char *p, *ep;
+ int type, subtype;
- type = r->community.c.e.type;
+ if (parsesubtype(t, &type, &subtype) == 0)
+ errx(1, "Bad ext-community unknown type");
switch (type) {
- case 0xff:
- if ((p = strchr(word, ':')) == NULL) {
- fprintf(stderr, "Bad ext-community: %s\n", word);
- return (0);
- }
+ case EXT_COMMUNITY_TRANS_TWO_AS:
+ case EXT_COMMUNITY_TRANS_FOUR_AS:
+ case EXT_COMMUNITY_TRANS_IPV4:
+ case -1:
+ if ((p = strchr(s, ':')) == NULL)
+ errx(1, "Bad ext-community %s", s);
*p++ = '\0';
- if ((type = parseextvalue(word, &uval)) == -1)
- return (0);
+ type = parseextvalue(type, s, &uval);
switch (type) {
case EXT_COMMUNITY_TRANS_TWO_AS:
ullval = strtonum(p, 0, UINT_MAX, &errstr);
@@ -1220,118 +1314,46 @@ parseextcommunity(const char *word, struct parse_result *r)
ullval = strtonum(p, 0, USHRT_MAX, &errstr);
break;
default:
- fprintf(stderr, "parseextcommunity: unexpected "
- "result\n");
- return (0);
- }
- if (errstr) {
- fprintf(stderr, "Bad ext-community: %s is %s\n", p,
- errstr);
- return (0);
- }
- switch (type) {
- case EXT_COMMUNITY_TRANS_TWO_AS:
- r->community.c.e.data1 = uval;
- r->community.c.e.data2 = ullval;
- break;
- case EXT_COMMUNITY_TRANS_IPV4:
- case EXT_COMMUNITY_TRANS_FOUR_AS:
- r->community.c.e.data1 = uval;
- r->community.c.e.data2 = ullval;
- break;
+ errx(1, "parseextcommunity: unexpected result");
}
+ if (errstr)
+ errx(1, "Bad ext-community %s is %s", p, errstr);
+ c->c.e.data1 = uval;
+ c->c.e.data2 = ullval;
break;
case EXT_COMMUNITY_TRANS_OPAQUE:
case EXT_COMMUNITY_TRANS_EVPN:
errno = 0;
- ullval = strtoull(word, &ep, 0);
- if (word[0] == '\0' || *ep != '\0') {
- fprintf(stderr, "Bad ext-community: bad value\n");
- return (0);
- }
- if (errno == ERANGE && ullval > EXT_COMMUNITY_OPAQUE_MAX) {
- fprintf(stderr, "Bad ext-community: too big\n");
- return (0);
- }
- r->community.c.e.data2 = ullval;
+ ullval = strtoull(s, &ep, 0);
+ if (s[0] == '\0' || *ep != '\0')
+ errx(1, "Bad ext-community bad value");
+ if (errno == ERANGE && ullval > EXT_COMMUNITY_OPAQUE_MAX)
+ errx(1, "Bad ext-community value too big");
+ c->c.e.data2 = ullval;
break;
case EXT_COMMUNITY_NON_TRANS_OPAQUE:
- if (strcmp(word, "valid") == 0)
- r->community.c.e.data2 = EXT_COMMUNITY_OVS_VALID;
- else if (strcmp(word, "invalid") == 0)
- r->community.c.e.data2 = EXT_COMMUNITY_OVS_INVALID;
- else if (strcmp(word, "not-found") == 0)
- r->community.c.e.data2 = EXT_COMMUNITY_OVS_NOTFOUND;
- else {
- fprintf(stderr, "Bad ext-community value: %s\n", word);
- return (0);
- }
+ if (strcmp(s, "valid") == 0)
+ c->c.e.data2 = EXT_COMMUNITY_OVS_VALID;
+ else if (strcmp(s, "invalid") == 0)
+ c->c.e.data2 = EXT_COMMUNITY_OVS_INVALID;
+ else if (strcmp(s, "not-found") == 0)
+ c->c.e.data2 = EXT_COMMUNITY_OVS_NOTFOUND;
+ else
+ errx(1, "Bad ext-community %s", s);
break;
}
- r->community.c.e.type = type;
+ c->c.e.type = type;
+ c->c.e.subtype = subtype;
/* verify type/subtype combo */
for (cp = iana_ext_comms; cp->subname != NULL; cp++) {
- if (cp->type == r->community.c.e.type &&
- cp->subtype == r->community.c.e.subtype) {
- r->community.type = COMMUNITY_TYPE_EXT;;
- if ((fs = calloc(1, sizeof(struct filter_set))) == NULL)
- err(1, NULL);
-
- fs->type = ACTION_SET_COMMUNITY;
- memcpy(&fs->action.community, &r->community,
- sizeof(struct filter_community));
-
- TAILQ_INSERT_TAIL(&r->set, fs, entry);
- return (1);
+ if (cp->type == type && cp->subtype == subtype) {
+ c->type = COMMUNITY_TYPE_EXT;
+ return (0);
}
}
- fprintf(stderr, "Bad ext-community: bad format for type\n");
- return (0);
-}
-
-int
-parse_largecommunity(const char *word, struct parse_result *r)
-{
- struct filter_set *fs;
- char *p, *po = strdup(word);
- char *array[3] = { NULL, NULL, NULL };
- char *val;
- u_int32_t as, ld1, ld2;
- u_int8_t asflag, ld1flag, ld2flag;
- int i = 0;
-
- p = po;
- while ((p != NULL) && (i < 3)) {
- val = strsep(&p, ":");
- array[i++] = val;
- }
-
- if ((p != NULL) || !(array[0] && array[1] && array[2]))
- errx(1, "Invalid Large-Community syntax");
-
- as = getcommunity(array[0], 1, &asflag);
- ld1 = getcommunity(array[1], 1, &ld1flag);
- ld2 = getcommunity(array[2], 1, &ld2flag);
-
- free(po);
-
- if ((fs = calloc(1, sizeof(struct filter_set))) == NULL)
- err(1, NULL);
- fs->type = ACTION_SET_COMMUNITY;
- fs->action.community.type = COMMUNITY_TYPE_LARGE;
- fs->action.community.c.l.data1 = as;
- fs->action.community.c.l.data2 = ld1;
- fs->action.community.c.l.data3 = ld2;
- fs->action.community.dflag1 = asflag;
- fs->action.community.dflag2 = ld1flag;
- fs->action.community.dflag3 = ld2flag;
-
- r->community = fs->action.community;
-
- TAILQ_INSERT_TAIL(&r->set, fs, entry);
- return (1);
+ errx(1, "Bad ext-community bad format for type");
}
int
diff --git a/usr.sbin/bgpctl/parser.h b/usr.sbin/bgpctl/parser.h
index 236dea8467e..4981054cdab 100644
--- a/usr.sbin/bgpctl/parser.h
+++ b/usr.sbin/bgpctl/parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.h,v 1.34 2019/01/20 23:30:15 claudio Exp $ */
+/* $OpenBSD: parser.h,v 1.35 2019/02/11 15:47:55 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -67,6 +67,8 @@ struct parse_result {
char rib[PEER_DESCR_LEN];
char shutcomm[SHUT_COMM_LEN];
char *irr_outdir;
+ const char *ext_comm_subtype;
+ u_int64_t rd;
int flags;
int is_group;
u_int8_t validation_state;