summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;