Claudio Jeker([email protected]) on 2018.12.12 14:19:36 +0100:
> Time to fold ext-communities into filter_community so that bgpd can match
> multiple ext-communities at the same time as well. Additionally this fixes
> parsing some of the ext-community types. Rather large diff again so more
> testing and review very welcome. After this more refactoring will be
> possible (esp on the attribute matching and altering side).
ok benno@
one space too much, see below.
I like it.
Unfortunatly, the diff shows how stupid extended communities are, and
refactoring it can't do much to improve that.
/B.
>
> --
> :wq Claudio
>
> PS: diff is agains /usr/src since it includes bgpctl and bgpd diffs.
>
>
> Index: usr.sbin/bgpctl/bgpctl.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
> retrieving revision 1.226
> diff -u -p -r1.226 bgpctl.c
> --- usr.sbin/bgpctl/bgpctl.c 11 Dec 2018 09:03:36 -0000 1.226
> +++ usr.sbin/bgpctl/bgpctl.c 12 Dec 2018 08:29:35 -0000
> @@ -281,8 +281,6 @@ main(int argc, char *argv[])
> ribreq.as = res->as;
> if (res->community.type != COMMUNITY_TYPE_NONE)
> ribreq.community = res->community;
> - if (res->extcommunity.flags == EXT_COMMUNITY_FLAG_VALID)
> - ribreq.extcommunity = res->extcommunity;
> ribreq.neighbor = neighbor;
> strlcpy(ribreq.rib, res->rib, sizeof(ribreq.rib));
> ribreq.aid = res->aid;
> Index: usr.sbin/bgpctl/parser.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpctl/parser.c,v
> retrieving revision 1.87
> diff -u -p -r1.87 parser.c
> --- usr.sbin/bgpctl/parser.c 28 Nov 2018 08:33:59 -0000 1.87
> +++ usr.sbin/bgpctl/parser.c 12 Dec 2018 08:29:35 -0000
> @@ -662,8 +662,8 @@ match_token(int *argc, char **argv[], co
> case EXTCOM_SUBTYPE:
> if (word != NULL && strncmp(word, table[i].keyword,
> wordlen) == 0) {
> - if (parsesubtype(word, &res.extcommunity.type,
> - &res.extcommunity.subtype) == 0)
> + if (parsesubtype(word, &res.community.c.e.type,
> + &res.community.c.e.subtype) == 0)
> errx(1, "Bad ext-community unknown "
> "type");
> match++;
> @@ -1084,8 +1084,8 @@ done:
> err(1, NULL);
> fs->type = ACTION_SET_COMMUNITY;
> fs->action.community.type = COMMUNITY_TYPE_BASIC;
> - fs->action.community.data1 = as;
> - fs->action.community.data2 = type;
> + fs->action.community.c.b.data1 = as;
> + fs->action.community.c.b.data2 = type;
> fs->action.community.dflag1 = asflag;
> fs->action.community.dflag2 = tflag;
>
> @@ -1160,7 +1160,7 @@ parseextvalue(const char *s, u_int32_t *
> s);
> return (-1);
> }
> - *v = ip.s_addr;
> + *v = ntohl(ip.s_addr);
> return (EXT_COMMUNITY_TRANS_IPV4);
> }
> return (-1);
> @@ -1177,7 +1177,7 @@ parseextcommunity(const char *word, stru
> char *p, *ep;
> int type;
>
> - type = r->extcommunity.type;
> + type = r->community.c.e.type;
>
> switch (type) {
> case 0xff:
> @@ -1208,16 +1208,13 @@ parseextcommunity(const char *word, stru
> }
> switch (type) {
> case EXT_COMMUNITY_TRANS_TWO_AS:
> - r->extcommunity.data.ext_as.as = uval;
> - r->extcommunity.data.ext_as.val = ullval;
> + r->community.c.e.data1 = uval;
> + r->community.c.e.data2 = ullval;
> break;
> case EXT_COMMUNITY_TRANS_IPV4:
> - r->extcommunity.data.ext_ip.addr.s_addr = uval;
> - r->extcommunity.data.ext_ip.val = ullval;
> - break;
> case EXT_COMMUNITY_TRANS_FOUR_AS:
> - r->extcommunity.data.ext_as4.as4 = uval;
> - r->extcommunity.data.ext_as4.val = ullval;
> + r->community.c.e.data1 = uval;
> + r->community.c.e.data2 = ullval;
> break;
> }
> break;
> @@ -1233,36 +1230,34 @@ parseextcommunity(const char *word, stru
> fprintf(stderr, "Bad ext-community: too big\n");
> return (0);
> }
> - r->extcommunity.data.ext_opaq = ullval;
> + r->community.c.e.data2 = ullval;
> break;
> case EXT_COMMUNITY_NON_TRANS_OPAQUE:
> if (strcmp(word, "valid") == 0)
> - r->extcommunity.data.ext_opaq = EXT_COMMUNITY_OVS_VALID;
> + r->community.c.e.data2 = EXT_COMMUNITY_OVS_VALID;
> else if (strcmp(word, "invalid") == 0)
> - r->extcommunity.data.ext_opaq =
> - EXT_COMMUNITY_OVS_INVALID;
> + r->community.c.e.data2 = EXT_COMMUNITY_OVS_INVALID;
> else if (strcmp(word, "not-found") == 0)
> - r->extcommunity.data.ext_opaq =
> - EXT_COMMUNITY_OVS_NOTFOUND;
> + r->community.c.e.data2 = EXT_COMMUNITY_OVS_NOTFOUND;
> else {
> fprintf(stderr, "Bad ext-community value: %s\n", word);
> return (0);
> }
> break;
> }
> - r->extcommunity.type = type;
> + r->community.c.e.type = type;
>
> /* verify type/subtype combo */
> for (cp = iana_ext_comms; cp->subname != NULL; cp++) {
> - if (cp->type == r->extcommunity.type &&
> - cp->subtype == r->extcommunity.subtype) {
> - r->extcommunity.flags |= EXT_COMMUNITY_FLAG_VALID;
> + 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_EXT_COMMUNITY;
> - memcpy(&fs->action.ext_community, &r->extcommunity,
> - sizeof(struct filter_extcommunity));
> + fs->type = ACTION_SET_COMMUNITY;
> + memcpy(&fs->action.community, &r->community,
> + sizeof(struct filter_community));
>
> TAILQ_INSERT_TAIL(&r->set, fs, entry);
> return (1);
> @@ -1303,9 +1298,9 @@ parse_largecommunity(const char *word, s
> err(1, NULL);
> fs->type = ACTION_SET_COMMUNITY;
> fs->action.community.type = COMMUNITY_TYPE_LARGE;
> - fs->action.community.data1 = as;
> - fs->action.community.data2 = ld1;
> - fs->action.community.data3 = ld2;
> + 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;
> Index: usr.sbin/bgpctl/parser.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpctl/parser.h,v
> retrieving revision 1.32
> diff -u -p -r1.32 parser.h
> --- usr.sbin/bgpctl/parser.h 28 Nov 2018 08:33:59 -0000 1.32
> +++ usr.sbin/bgpctl/parser.h 12 Dec 2018 08:29:35 -0000
> @@ -63,7 +63,6 @@ struct parse_result {
> struct filter_as as;
> struct filter_set_head set;
> struct filter_community community;
> - struct filter_extcommunity extcommunity;
> char peerdesc[PEER_DESCR_LEN];
> char rib[PEER_DESCR_LEN];
> char shutcomm[SHUT_COMM_LEN];
> Index: usr.sbin/bgpd/bgpd.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
> retrieving revision 1.357
> diff -u -p -r1.357 bgpd.h
> --- usr.sbin/bgpd/bgpd.h 11 Dec 2018 09:02:14 -0000 1.357
> +++ usr.sbin/bgpd/bgpd.h 12 Dec 2018 12:56:51 -0000
> @@ -742,30 +742,23 @@ struct filter_community {
> u_int8_t dflag1; /* one of set, any, local-as, neighbor-as */
> u_int8_t dflag2;
> u_int8_t dflag3;
> - u_int32_t data1;
> - u_int32_t data2;
> - u_int32_t data3;
> -};
> -
> -struct filter_extcommunity {
> - u_int16_t flags;
> - u_int8_t type;
> - u_int8_t subtype; /* if extended type */
> union {
> - struct ext_as {
> - u_int16_t as;
> - u_int32_t val;
> - } ext_as;
> - struct ext_as4 {
> - u_int32_t as4;
> - u_int16_t val;
> - } ext_as4;
> - struct ext_ip {
> - struct in_addr addr;
> - u_int16_t val;
> - } ext_ip;
> - u_int64_t ext_opaq; /* only 48 bits */
> - } data;
> + struct basic {
> + u_int32_t data1;
> + u_int32_t data2;
> + } b;
> + struct large {
> + u_int32_t data1;
> + u_int32_t data2;
> + u_int32_t data3;
> + } l;
> + struct ext {
> + u_int32_t data1;
> + u_int64_t data2;
> + u_int8_t type;
> + u_int8_t subtype; /* if extended type */
> + } e;
> + } c;
> };
>
> struct ctl_show_rib_request {
> @@ -774,7 +767,6 @@ struct ctl_show_rib_request {
> struct bgpd_addr prefix;
> struct filter_as as;
> struct filter_community community;
> - struct filter_extcommunity extcommunity;
> u_int32_t peerid;
> u_int32_t flags;
> u_int8_t validation_state;
> @@ -929,7 +921,6 @@ struct filter_match {
> struct filter_as as;
> struct filter_aslen aslen;
> struct filter_community community[MAX_COMM_MATCH];
> - struct filter_extcommunity ext_community;
> struct filter_prefixset prefixset;
> struct filter_originset originset;
> struct filter_ovs ovs;
> @@ -968,8 +959,6 @@ enum action_types {
> ACTION_SET_NEXTHOP_SELF,
> ACTION_DEL_COMMUNITY,
> ACTION_SET_COMMUNITY,
> - ACTION_DEL_EXT_COMMUNITY,
> - ACTION_SET_EXT_COMMUNITY,
> ACTION_PFTABLE,
> ACTION_PFTABLE_ID,
> ACTION_RTLABEL,
> @@ -988,7 +977,6 @@ struct filter_set {
> struct bgpd_addr nexthop;
> struct nexthop *nh;
> struct filter_community community;
> - struct filter_extcommunity ext_community;
> char pftable[PFTABLE_LEN];
> char rtlabel[RTLABEL_LEN];
> u_int8_t origin;
> Index: usr.sbin/bgpd/parse.y
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
> retrieving revision 1.365
> diff -u -p -r1.365 parse.y
> --- usr.sbin/bgpd/parse.y 6 Dec 2018 12:38:01 -0000 1.365
> +++ usr.sbin/bgpd/parse.y 12 Dec 2018 12:56:51 -0000
> @@ -155,8 +155,7 @@ struct filter_rule *get_rule(enum action
>
> int parsecommunity(struct filter_community *, int, char *);
> int parsesubtype(char *, int *, int *);
> -int parseextvalue(char *, u_int32_t *);
> -int parseextcommunity(struct filter_extcommunity *, char *,
> +int parseextcommunity(struct filter_community *, char *,
> char *);
> static int new_as_set(char *);
> static void add_as_set(u_int32_t);
> @@ -1078,8 +1077,8 @@ rdomainopts_l : /* empty */
> ;
>
> rdomainopts : RD STRING {
> - struct filter_extcommunity ext;
> - u_int64_t rd;
> + struct filter_community ext;
> + u_int64_t rd;
>
> if (parseextcommunity(&ext, "rt", $2) == -1) {
> free($2);
> @@ -1095,7 +1094,7 @@ rdomainopts : RD STRING {
> YYERROR;
> }
> rd = betoh64(rd) & 0xffffffffffffULL;
> - switch (ext.type) {
> + switch (ext.c.e.type) {
> case EXT_COMMUNITY_TRANS_TWO_AS:
> rd |= (0ULL << 48);
> break;
> @@ -1117,8 +1116,8 @@ rdomainopts : RD STRING {
> if ((set = calloc(1, sizeof(struct filter_set))) ==
> NULL)
> fatal(NULL);
> - set->type = ACTION_SET_EXT_COMMUNITY;
> - if (parseextcommunity(&set->action.ext_community,
> + set->type = ACTION_SET_COMMUNITY;
> + if (parseextcommunity(&set->action.community,
> $2, $3) == -1) {
> free($3);
> free($2);
> @@ -1135,8 +1134,8 @@ rdomainopts : RD STRING {
> if ((set = calloc(1, sizeof(struct filter_set))) ==
> NULL)
> fatal(NULL);
> - set->type = ACTION_SET_EXT_COMMUNITY;
> - if (parseextcommunity(&set->action.ext_community,
> + set->type = ACTION_SET_COMMUNITY;
> + if (parseextcommunity(&set->action.community,
> $2, $3) == -1) {
> free($3);
> free($2);
> @@ -2160,15 +2159,20 @@ filter_elm : filter_prefix_h {
> free($2);
> }
> | EXTCOMMUNITY STRING STRING {
> - if (fmopts.m.ext_community.flags &
> - EXT_COMMUNITY_FLAG_VALID) {
> - yyerror("\"ext-community\" already specified");
> + int i;
> + for (i = 0; i < MAX_COMM_MATCH; i++) {
> + if (fmopts.m.community[i].type ==
> + COMMUNITY_TYPE_NONE)
> + break;
> + }
> + if (i >= MAX_COMM_MATCH) {
> + yyerror("too many \"community\" filters "
> + "specified");
> free($2);
> free($3);
> YYERROR;
> }
> -
> - if (parseextcommunity(&fmopts.m.ext_community,
> + if (parseextcommunity(&fmopts.m.community[i],
> $2, $3) == -1) {
> free($2);
> free($3);
> @@ -2178,14 +2182,19 @@ filter_elm : filter_prefix_h {
> free($3);
> }
> | EXTCOMMUNITY OVS STRING {
> - if (fmopts.m.ext_community.flags &
> - EXT_COMMUNITY_FLAG_VALID) {
> - yyerror("\"ext-community\" already specified");
> + int i;
> + for (i = 0; i < MAX_COMM_MATCH; i++) {
> + if (fmopts.m.community[i].type ==
> + COMMUNITY_TYPE_NONE)
> + break;
> + }
> + if (i >= MAX_COMM_MATCH) {
> + yyerror("too many \"community\" filters "
> + "specified");
> free($3);
> YYERROR;
> }
> -
> - if (parseextcommunity(&fmopts.m.ext_community,
> + if (parseextcommunity(&fmopts.m.community[i],
> "ovs", $3) == -1) {
> free($3);
> YYERROR;
> @@ -2659,11 +2668,11 @@ filter_set_opt : LOCALPREF NUMBER
> {
> if (($$ = calloc(1, sizeof(struct filter_set))) == NULL)
> fatal(NULL);
> if ($2)
> - $$->type = ACTION_DEL_EXT_COMMUNITY;
> + $$->type = ACTION_DEL_COMMUNITY;
> else
> - $$->type = ACTION_SET_EXT_COMMUNITY;
> + $$->type = ACTION_SET_COMMUNITY;
>
> - if (parseextcommunity(&$$->action.ext_community,
> + if (parseextcommunity(&$$->action.community,
> $3, $4) == -1) {
> free($3);
> free($4);
> @@ -2677,11 +2686,11 @@ filter_set_opt : LOCALPREF NUMBER
> {
> if (($$ = calloc(1, sizeof(struct filter_set))) == NULL)
> fatal(NULL);
> if ($2)
> - $$->type = ACTION_DEL_EXT_COMMUNITY;
> + $$->type = ACTION_DEL_COMMUNITY;
> else
> - $$->type = ACTION_SET_EXT_COMMUNITY;
> + $$->type = ACTION_SET_COMMUNITY;
>
> - if (parseextcommunity(&$$->action.ext_community,
> + if (parseextcommunity(&$$->action.community,
> "ovs", $4) == -1) {
> free($4);
> free($$);
> @@ -3479,8 +3488,8 @@ setcommunity(struct filter_community *c,
> c->type = COMMUNITY_TYPE_BASIC;
> c->dflag1 = asflag;
> c->dflag2 = dataflag;
> - c->data1 = as;
> - c->data2 = data;
> + c->c.b.data1 = as;
> + c->c.b.data2 = data;
> }
>
> static int
> @@ -3500,9 +3509,9 @@ parselargecommunity(struct filter_commun
> }
> *q++ = 0;
>
> - if (getcommunity(s, 1, &c->data1, &c->dflag1) == -1 ||
> - getcommunity(p, 1, &c->data2, &c->dflag2) == -1 ||
> - getcommunity(q, 1, &c->data3, &c->dflag3) == -1)
> + if (getcommunity(s, 1, &c->c.l.data1, &c->dflag1) == -1 ||
> + getcommunity(p, 1, &c->c.l.data2, &c->dflag2) == -1 ||
> + getcommunity(q, 1, &c->c.l.data3, &c->dflag3) == -1)
> return (-1);
> c->type = COMMUNITY_TYPE_LARGE;
> return (0);
> @@ -3578,28 +3587,51 @@ parsesubtype(char *name, int *type, int
> return (found);
> }
>
> -int
> -parseextvalue(char *s, u_int32_t *v)
> +static int
> +parseextvalue(int type, char *s, u_int32_t *v)
> {
> const char *errstr;
> char *p;
> struct in_addr ip;
> u_int32_t uvalh = 0, 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);
> + strtonum(s, 0, USHRT_MAX, &errstr);
> + if (errstr == NULL)
> + type = EXT_COMMUNITY_TRANS_TWO_AS;
> + else
> + 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) {
> yyerror("Bad ext-community %s is %s", s, errstr);
> return (-1);
> }
> *v = uval;
> - if (uval <= USHRT_MAX)
> - return (EXT_COMMUNITY_TRANS_TWO_AS);
> - else
> - return (EXT_COMMUNITY_TRANS_FOUR_AS);
> - } else if (strchr(p + 1, '.') == NULL) {
> - /* AS_DOT number (4-byte) */
> + break;
> + case EXT_COMMUNITY_TRANS_FOUR_AS:
> + if ((p = strchr(s, '.')) == NULL) {
> + uval = strtonum(s, 0, UINT_MAX, &errstr);
> + if (errstr) {
> + yyerror("Bad ext-community %s is %s", s,
> + errstr);
> + return (-1);
> + }
> + *v = uval;
> + break;
> + }
^space
> *p++ = '\0';
> uvalh = strtonum(s, 0, USHRT_MAX, &errstr);
> if (errstr) {
> @@ -3612,21 +3644,20 @@ parseextvalue(char *s, u_int32_t *v)
> return (-1);
> }
> *v = uval | (uvalh << 16);
> - return (EXT_COMMUNITY_TRANS_FOUR_AS);
> - } else {
> - /* more than one dot -> IP address */
> + break;
> + case EXT_COMMUNITY_TRANS_IPV4:
> if (inet_aton(s, &ip) == 0) {
> yyerror("Bad ext-community %s not parseable", s);
> return (-1);
> }
> - *v = ip.s_addr;
> - return (EXT_COMMUNITY_TRANS_IPV4);
> + *v = ntohl(ip.s_addr);
> + break;
> }
> - return (-1);
> + return (type);
> }
>
> int
> -parseextcommunity(struct filter_extcommunity *c, char *t, char *s)
> +parseextcommunity(struct filter_community *c, char *t, char *s)
> {
> const struct ext_comm_pairs *cp;
> const char *errstr;
> @@ -3641,13 +3672,16 @@ parseextcommunity(struct filter_extcommu
> }
>
> switch (type) {
> + case EXT_COMMUNITY_TRANS_TWO_AS:
> + case EXT_COMMUNITY_TRANS_FOUR_AS:
> + case EXT_COMMUNITY_TRANS_IPV4:
> case -1:
> if ((p = strchr(s, ':')) == NULL) {
> yyerror("Bad ext-community %s", s);
> return (-1);
> }
> *p++ = '\0';
> - if ((type = parseextvalue(s, &uval)) == -1)
> + if ((type = parseextvalue(type, s, &uval)) == -1)
> return (-1);
> switch (type) {
> case EXT_COMMUNITY_TRANS_TWO_AS:
> @@ -3664,20 +3698,8 @@ parseextcommunity(struct filter_extcommu
> yyerror("Bad ext-community %s is %s", p, errstr);
> return (-1);
> }
> - switch (type) {
> - case EXT_COMMUNITY_TRANS_TWO_AS:
> - c->data.ext_as.as = uval;
> - c->data.ext_as.val = ullval;
> - break;
> - case EXT_COMMUNITY_TRANS_IPV4:
> - c->data.ext_ip.addr.s_addr = uval;
> - c->data.ext_ip.val = ullval;
> - break;
> - case EXT_COMMUNITY_TRANS_FOUR_AS:
> - c->data.ext_as4.as4 = uval;
> - c->data.ext_as4.val = ullval;
> - break;
> - }
> + c->c.e.data1 = uval;
> + c->c.e.data2 = ullval;
> break;
> case EXT_COMMUNITY_TRANS_OPAQUE:
> case EXT_COMMUNITY_TRANS_EVPN:
> @@ -3691,28 +3713,28 @@ parseextcommunity(struct filter_extcommu
> yyerror("Bad ext-community value too big");
> return (-1);
> }
> - c->data.ext_opaq = ullval;
> + c->c.e.data2 = ullval;
> break;
> case EXT_COMMUNITY_NON_TRANS_OPAQUE:
> if (strcmp(s, "valid") == 0)
> - c->data.ext_opaq = EXT_COMMUNITY_OVS_VALID;
> + c->c.e.data2 = EXT_COMMUNITY_OVS_VALID;
> else if (strcmp(s, "invalid") == 0)
> - c->data.ext_opaq = EXT_COMMUNITY_OVS_INVALID;
> + c->c.e.data2 = EXT_COMMUNITY_OVS_INVALID;
> else if (strcmp(s, "not-found") == 0)
> - c->data.ext_opaq = EXT_COMMUNITY_OVS_NOTFOUND;
> + c->c.e.data2 = EXT_COMMUNITY_OVS_NOTFOUND;
> else {
> yyerror("Bad ext-community %s", s);
> return (-1);
> }
> break;
> }
> - c->type = type;
> - c->subtype = subtype;
> + 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 == type && cp->subtype == subtype) {
> - c->flags |= EXT_COMMUNITY_FLAG_VALID;
> + c->type = COMMUNITY_TYPE_EXT;
> return (0);
> }
> }
> @@ -4206,18 +4228,6 @@ filterset_add(struct filter_set_head *sh
> sizeof(s->action.community)) == 0)
> break;
> continue;
> - case ACTION_SET_EXT_COMMUNITY:
> - case ACTION_DEL_EXT_COMMUNITY:
> - if (memcmp(&s->action.ext_community,
> - &t->action.ext_community,
> - sizeof(s->action.ext_community)) < 0) {
> - TAILQ_INSERT_BEFORE(t, s, entry);
> - return;
> - } else if (memcmp(&s->action.ext_community,
> - &t->action.ext_community,
> - sizeof(s->action.ext_community)) == 0)
> - break;
> - continue;
> case ACTION_SET_NEXTHOP:
> /* only last nexthop per AF matters */
> if (s->action.nexthop.aid <
> @@ -4288,11 +4298,6 @@ merge_filterset(struct filter_set_head *
> yyerror("community is already set");
> else if (s->type == ACTION_DEL_COMMUNITY)
> yyerror("community will already be deleted");
> - else if (s->type == ACTION_SET_EXT_COMMUNITY)
> - yyerror("ext-community is already set");
> - else if (s->type == ACTION_DEL_EXT_COMMUNITY)
> - yyerror(
> - "ext-community will already be deleted");
> else
> yyerror("redefining set parameter %s",
> filterset_name(s->type));
> Index: usr.sbin/bgpd/printconf.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v
> retrieving revision 1.124
> diff -u -p -r1.124 printconf.c
> --- usr.sbin/bgpd/printconf.c 28 Nov 2018 08:32:27 -0000 1.124
> +++ usr.sbin/bgpd/printconf.c 12 Dec 2018 12:56:51 -0000
> @@ -32,8 +32,6 @@
> void print_prefix(struct filter_prefix *p);
> const char *community_type(struct filter_community *c);
> void print_community(struct filter_community *c);
> -void print_largecommunity(int64_t, int64_t, int64_t);
> -void print_extcommunity(struct filter_extcommunity *);
> void print_origin(u_int8_t);
> void print_set(struct filter_set_head *);
> void print_mainconf(struct bgpd_config *);
> @@ -113,6 +111,8 @@ community_type(struct filter_community *
> return "community";
> case COMMUNITY_TYPE_LARGE:
> return "large-community";
> + case COMMUNITY_TYPE_EXT:
> + return "ext-community";
> default:
> return "???";
> }
> @@ -121,6 +121,8 @@ community_type(struct filter_community *
> void
> print_community(struct filter_community *c)
> {
> + struct in_addr addr;
> +
> switch (c->type) {
> case COMMUNITY_TYPE_BASIC:
> switch (c->dflag1) {
> @@ -134,7 +136,7 @@ print_community(struct filter_community
> printf("local-as:");
> break;
> default:
> - printf("%u:", c->data1);
> + printf("%u:", c->c.b.data1);
> break;
> }
> switch (c->dflag2) {
> @@ -148,7 +150,7 @@ print_community(struct filter_community
> printf("local-as ");
> break;
> default:
> - printf("%u ", c->data2);
> + printf("%u ", c->c.b.data2);
> break;
> }
> break;
> @@ -164,7 +166,7 @@ print_community(struct filter_community
> printf("local-as:");
> break;
> default:
> - printf("%u:", c->data1);
> + printf("%u:", c->c.l.data1);
> break;
> }
> switch (c->dflag2) {
> @@ -178,7 +180,7 @@ print_community(struct filter_community
> printf("local-as:");
> break;
> default:
> - printf("%u:", c->data2);
> + printf("%u:", c->c.l.data2);
> break;
> }
> switch (c->dflag3) {
> @@ -192,50 +194,44 @@ print_community(struct filter_community
> printf("local-as ");
> break;
> default:
> - printf("%u ", c->data3);
> + printf("%u ", c->c.l.data3);
> break;
> }
> break;
> - }
> -}
> -
> -void
> -print_extcommunity(struct filter_extcommunity *c)
> -{
> - 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_TRANS_FOUR_AS:
> - printf("%s:%u ", log_as(c->data.ext_as4.as4),
> - c->data.ext_as.val);
> - break;
> - case EXT_COMMUNITY_TRANS_OPAQUE:
> - case EXT_COMMUNITY_TRANS_EVPN:
> - printf("0x%llx ", c->data.ext_opaq);
> - break;
> - 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 ");
> + case COMMUNITY_TYPE_EXT:
> + printf("%s ", log_ext_subtype(c->c.e.type, c->c.e.subtype));
> + switch (c->c.e.type) {
> + case EXT_COMMUNITY_TRANS_TWO_AS:
> + case EXT_COMMUNITY_TRANS_FOUR_AS:
> + printf("%s:%llu ", log_as(c->c.e.data1),
> + c->c.e.data2);
> + break;
> + case EXT_COMMUNITY_TRANS_IPV4:
> + addr.s_addr = htonl(c->c.e.data1);
> + printf("%s:%llu ", inet_ntoa(addr),
> + c->c.e.data2);
> + break;
> + case EXT_COMMUNITY_TRANS_OPAQUE:
> + case EXT_COMMUNITY_TRANS_EVPN:
> + printf("0x%llx ", c->c.e.data2);
> + break;
> + case EXT_COMMUNITY_NON_TRANS_OPAQUE:
> + switch (c->c.e.data2) {
> + 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;
> - case EXT_COMMUNITY_OVS_INVALID:
> - printf("invalid ");
> + default:
> + printf("0x%llx ", c->c.e.data2);
> break;
> }
> - break;
> - default:
> - printf("0x%llx ", c->data.ext_opaq);
> - break;
> }
> }
>
> @@ -326,14 +322,6 @@ print_set(struct filter_set_head *set)
> /* not possible */
> printf("king bula saiz: config broken");
> break;
> - case ACTION_SET_EXT_COMMUNITY:
> - printf("ext-community ");
> - print_extcommunity(&s->action.ext_community);
> - break;
> - case ACTION_DEL_EXT_COMMUNITY:
> - printf("ext-community delete ");
> - print_extcommunity(&s->action.ext_community);
> - break;
> }
> }
> printf("}");
> @@ -391,7 +379,7 @@ print_rdomain_targets(struct filter_set_
> struct filter_set *s;
> TAILQ_FOREACH(s, set, entry) {
> printf("\t%s ", tgt);
> - print_extcommunity(&s->action.ext_community);
> + print_community(&s->action.community);
> printf("\n");
> }
> }
> @@ -847,10 +835,6 @@ print_rule(struct peer *peer_l, struct f
> printf("%s ", community_type(c));
> print_community(c);
> }
> - }
> - if (r->match.ext_community.flags & EXT_COMMUNITY_FLAG_VALID) {
> - printf("ext-community ");
> - print_extcommunity(&r->match.ext_community);
> }
>
> print_set(&r->set);
> Index: usr.sbin/bgpd/rde.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
> retrieving revision 1.452
> diff -u -p -r1.452 rde.c
> --- usr.sbin/bgpd/rde.c 11 Dec 2018 09:02:14 -0000 1.452
> +++ usr.sbin/bgpd/rde.c 12 Dec 2018 12:56:51 -0000
> @@ -2229,10 +2229,11 @@ rde_dump_filter(struct prefix *p, struct
> if (!community_large_match(asp, &req->community, NULL))
> return;
> break;
> + case COMMUNITY_TYPE_EXT:
> + if (!community_ext_match(asp, &req->community, 0))
> + return;
> + break;
> }
> - if (req->extcommunity.flags == EXT_COMMUNITY_FLAG_VALID &&
> - !community_ext_match(asp, &req->extcommunity, 0))
> - return;
> if (!ovs_match(p, req->flags))
> return;
> rde_dump_rib_as(p, asp, req->pid, req->flags);
> @@ -2436,7 +2437,7 @@ rde_rdomain_import(struct rde_aspath *as
> struct filter_set *s;
>
> TAILQ_FOREACH(s, &rd->import, entry) {
> - if (community_ext_match(asp, &s->action.ext_community, 0))
> + if (community_match(asp, &s->action.community, 0))
> return (1);
> }
> return (0);
> Index: usr.sbin/bgpd/rde.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
> retrieving revision 1.204
> diff -u -p -r1.204 rde.h
> --- usr.sbin/bgpd/rde.h 11 Dec 2018 09:02:14 -0000 1.204
> +++ usr.sbin/bgpd/rde.h 12 Dec 2018 12:56:51 -0000
> @@ -375,12 +375,12 @@ int community_large_set(struct rde_aspa
> void community_large_delete(struct rde_aspath *, struct filter_community *,
> struct rde_peer *);
> int community_ext_match(struct rde_aspath *,
> - struct filter_extcommunity *, u_int16_t);
> + struct filter_community *, struct rde_peer *);
> int community_ext_set(struct rde_aspath *,
> - struct filter_extcommunity *, u_int16_t);
> + struct filter_community *, struct rde_peer *);
> void community_ext_delete(struct rde_aspath *,
> - struct filter_extcommunity *, u_int16_t);
> -int community_ext_conv(struct filter_extcommunity *, u_int16_t,
> + struct filter_community *, struct rde_peer *);
> +int community_ext_conv(struct filter_community *, struct rde_peer *,
> u_int64_t *);
> u_char *community_ext_delete_non_trans(u_char *, u_int16_t, u_int16_t
> *);
>
> Index: usr.sbin/bgpd/rde_attr.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde_attr.c,v
> retrieving revision 1.114
> diff -u -p -r1.114 rde_attr.c
> --- usr.sbin/bgpd/rde_attr.c 11 Dec 2018 09:02:14 -0000 1.114
> +++ usr.sbin/bgpd/rde_attr.c 12 Dec 2018 12:56:51 -0000
> @@ -1106,8 +1106,6 @@ aspath_lenmatch(struct aspath *a, enum a
> * Functions handling communities and extended communities.
> */
>
> -int community_ext_matchone(struct filter_extcommunity *, u_int16_t,
> u_int64_t);
> -
> static int
> community_extract(struct filter_community *fc, struct rde_peer *peer,
> int field, int large, u_int32_t *value)
> @@ -1117,15 +1115,21 @@ community_extract(struct filter_communit
> switch (field) {
> case 1:
> flag = fc->dflag1;
> - data = fc->data1;
> + if (large)
> + data = fc->c.l.data1;
> + else
> + data = fc->c.b.data1;
> break;
> case 2:
> flag = fc->dflag2;
> - data = fc->data2;
> + if (large)
> + data = fc->c.l.data2;
> + else
> + data = fc->c.b.data2;
> break;
> case 3:
> flag = fc->dflag3;
> - data = fc->data3;
> + data = fc->c.l.data3;
> break;
> default:
> fatalx("%s: unknown field %d", __func__, field);
> @@ -1148,6 +1152,73 @@ community_extract(struct filter_communit
> return 0;
> }
>
> +static int
> +community_ext_matchone(struct filter_community *c, struct rde_peer *peer,
> + u_int64_t community)
> +{
> + u_int64_t com, mask;
> +
> + community = betoh64(community);
> +
> + com = (u_int64_t)c->c.e.type << 56;
> + mask = 0xffULL << 56;
> + if ((com & mask) != (community & mask))
> + return (0);
> +
> + switch (c->c.e.type & EXT_COMMUNITY_VALUE) {
> + 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->c.e.subtype << 48;
> + mask = 0xffULL << 48;
> + if ((com & mask) != (community & mask))
> + return (0);
> + break;
> + default:
> + com = c->c.e.data2 & 0xffffffffffffffULL;
> + mask = 0xffffffffffffffULL;
> + if ((com & mask) == (community & mask))
> + return (1);
> + return (0);
> + }
> +
> +
> + switch (c->c.e.type & EXT_COMMUNITY_VALUE) {
> + case EXT_COMMUNITY_TRANS_TWO_AS:
> + com = (u_int64_t)c->c.e.data1 << 32;
> + mask = 0xffffULL << 32;
> + if ((com & mask) != (community & mask))
> + return (0);
> +
> + com = c->c.e.data2;
> + mask = 0xffffffffULL;
> + if ((com & mask) == (community & mask))
> + return (1);
> + break;
> + case EXT_COMMUNITY_TRANS_IPV4:
> + case EXT_COMMUNITY_TRANS_FOUR_AS:
> + com = (u_int64_t)c->c.e.data1 << 16;
> + mask = 0xffffffffULL << 16;
> + if ((com & mask) != (community & mask))
> + return (0);
> +
> + com = c->c.e.data2;
> + mask = 0xffff;
> + if ((com & mask) == (community & mask))
> + return (1);
> + break;
> + case EXT_COMMUNITY_TRANS_OPAQUE:
> + com = c->c.e.data2;
> + mask = EXT_COMMUNITY_OPAQUE_MAX;
> + if ((com & mask) == (community & mask))
> + return (1);
> + break;
> + }
> +
> + return (0);
> +}
> +
> int
> community_match(struct rde_aspath *asp, struct filter_community *fc,
> struct rde_peer *peer)
> @@ -1308,8 +1379,8 @@ community_delete(struct rde_aspath *asp,
> }
>
> int
> -community_ext_match(struct rde_aspath *asp, struct filter_extcommunity *c,
> - u_int16_t neighas)
> +community_ext_match(struct rde_aspath *asp, struct filter_community *c,
> + struct rde_peer *peer)
> {
> struct attr *attr;
> u_int8_t *p;
> @@ -1324,7 +1395,7 @@ community_ext_match(struct rde_aspath *a
> p = attr->data;
> for (len = attr->len / sizeof(ec); len > 0; len--) {
> memcpy(&ec, p, sizeof(ec));
> - if (community_ext_matchone(c, neighas, ec))
> + if (community_ext_matchone(c, peer, ec))
> return (1);
> p += sizeof(ec);
> }
> @@ -1333,8 +1404,8 @@ community_ext_match(struct rde_aspath *a
> }
>
> int
> -community_ext_set(struct rde_aspath *asp, struct filter_extcommunity *c,
> - u_int16_t neighas)
> +community_ext_set(struct rde_aspath *asp, struct filter_community *c,
> + struct rde_peer *peer)
> {
> struct attr *attr;
> u_int8_t *p = NULL;
> @@ -1342,7 +1413,7 @@ community_ext_set(struct rde_aspath *asp
> unsigned int i, ncommunities = 0;
> u_int8_t f = ATTR_OPTIONAL|ATTR_TRANSITIVE;
>
> - if (community_ext_conv(c, neighas, &community))
> + if (community_ext_conv(c, peer, &community))
> return (0);
>
> attr = attr_optget(asp, ATTR_EXT_COMMUNITIES);
> @@ -1381,8 +1452,8 @@ community_ext_set(struct rde_aspath *asp
> }
>
> void
> -community_ext_delete(struct rde_aspath *asp, struct filter_extcommunity *c,
> - u_int16_t neighas)
> +community_ext_delete(struct rde_aspath *asp, struct filter_community *c,
> + struct rde_peer *peer)
> {
> struct attr *attr;
> u_int8_t *p, *n;
> @@ -1390,7 +1461,7 @@ community_ext_delete(struct rde_aspath *
> u_int16_t l, len = 0;
> u_int8_t f;
>
> - if (community_ext_conv(c, neighas, &community))
> + if (community_ext_conv(c, peer, &community))
> return;
>
> attr = attr_optget(asp, ATTR_EXT_COMMUNITIES);
> @@ -1432,119 +1503,34 @@ community_ext_delete(struct rde_aspath *
> }
>
> int
> -community_ext_conv(struct filter_extcommunity *c, u_int16_t neighas,
> +community_ext_conv(struct filter_community *c, struct rde_peer *peer,
> u_int64_t *community)
> {
> u_int64_t com;
> - u_int32_t ip;
>
> - com = (u_int64_t)c->type << 56;
> - switch (c->type & EXT_COMMUNITY_VALUE) {
> + com = (u_int64_t)c->c.e.type << 56;
> + switch (c->c.e.type & EXT_COMMUNITY_VALUE) {
> 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;
> + com |= (u_int64_t)c->c.e.subtype << 48;
> + com |= (u_int64_t)c->c.e.data1 << 32;
> + com |= c->c.e.data2 & 0xffffffff;
> break;
> 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_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;
> + com |= (u_int64_t)c->c.e.subtype << 48;
> + com |= (u_int64_t)c->c.e.data1 << 16;
> + com |= c->c.e.data2 & 0xffff;
> break;
> case EXT_COMMUNITY_TRANS_OPAQUE:
> - com |= (u_int64_t)c->subtype << 48;
> - com |= c->data.ext_opaq & EXT_COMMUNITY_OPAQUE_MAX;
> + com |= (u_int64_t)c->c.e.subtype << 48;
> + com |= c->c.e.data2 & EXT_COMMUNITY_OPAQUE_MAX;
> break;
> default:
> - com |= c->data.ext_opaq & 0xffffffffffffffULL;
> + com |= c->c.e.data2 & 0xffffffffffffffULL;
> break;
> }
>
> *community = htobe64(com);
> -
> - return (0);
> -}
> -
> -int
> -community_ext_matchone(struct filter_extcommunity *c, u_int16_t neighas,
> - u_int64_t community)
> -{
> - u_int64_t com, mask;
> - u_int32_t ip;
> -
> - community = betoh64(community);
> -
> - com = (u_int64_t)c->type << 56;
> - mask = 0xffULL << 56;
> - if ((com & mask) != (community & mask))
> - return (0);
> -
> - switch (c->type & EXT_COMMUNITY_VALUE) {
> - 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))
> - return (0);
> - break;
> - default:
> - com = c->data.ext_opaq & 0xffffffffffffffULL;
> - mask = 0xffffffffffffffULL;
> - if ((com & mask) == (community & mask))
> - return (1);
> - return (0);
> - }
> -
> -
> - switch (c->type & EXT_COMMUNITY_VALUE) {
> - case EXT_COMMUNITY_TRANS_TWO_AS:
> - com = (u_int64_t)c->data.ext_as.as << 32;
> - mask = 0xffffULL << 32;
> - if ((com & mask) != (community & mask))
> - return (0);
> -
> - com = c->data.ext_as.val;
> - mask = 0xffffffffULL;
> - if ((com & mask) == (community & mask))
> - return (1);
> - break;
> - case EXT_COMMUNITY_TRANS_IPV4:
> - ip = ntohl(c->data.ext_ip.addr.s_addr);
> - com = (u_int64_t)ip << 16;
> - mask = 0xffffffff0000ULL;
> - if ((com & mask) != (community & mask))
> - return (0);
> -
> - com = c->data.ext_ip.val;
> - mask = 0xffff;
> - if ((com & mask) == (community & mask))
> - return (1);
> - break;
> - case EXT_COMMUNITY_TRANS_FOUR_AS:
> - com = (u_int64_t)c->data.ext_as4.as4 << 16;
> - mask = 0xffffffffULL << 16;
> - if ((com & mask) != (community & mask))
> - return (0);
> -
> - com = c->data.ext_as4.val;
> - mask = 0xffff;
> - if ((com & mask) == (community & mask))
> - return (1);
> - break;
> - case EXT_COMMUNITY_TRANS_OPAQUE:
> - com = c->data.ext_opaq & EXT_COMMUNITY_OPAQUE_MAX;
> - mask = EXT_COMMUNITY_OPAQUE_MAX;
> - if ((com & mask) == (community & mask))
> - return (1);
> - break;
> - }
>
> return (0);
> }
> Index: usr.sbin/bgpd/rde_filter.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde_filter.c,v
> retrieving revision 1.115
> diff -u -p -r1.115 rde_filter.c
> --- usr.sbin/bgpd/rde_filter.c 11 Dec 2018 09:02:14 -0000 1.115
> +++ usr.sbin/bgpd/rde_filter.c 12 Dec 2018 12:56:51 -0000
> @@ -149,6 +149,10 @@ rde_apply_set(struct filter_set_head *sh
> community_large_set(&state->aspath,
> &set->action.community, peer);
> break;
> + case COMMUNITY_TYPE_EXT:
> + community_ext_set(&state->aspath,
> + &set->action.community, peer);
> + break;
> }
> break;
> case ACTION_DEL_COMMUNITY:
> @@ -161,6 +165,9 @@ rde_apply_set(struct filter_set_head *sh
> community_large_delete(&state->aspath,
> &set->action.community, peer);
> break;
> + case COMMUNITY_TYPE_EXT:
> + community_ext_delete(&state->aspath,
> + &set->action.community, peer);
> }
> break;
> case ACTION_PFTABLE:
> @@ -184,16 +191,6 @@ rde_apply_set(struct filter_set_head *sh
> case ACTION_SET_ORIGIN:
> state->aspath.origin = set->action.origin;
> break;
> - case ACTION_SET_EXT_COMMUNITY:
> - community_ext_set(&state->aspath,
> - &set->action.ext_community,
> - peer->conf.remote_as);
> - break;
> - case ACTION_DEL_EXT_COMMUNITY:
> - community_ext_delete(&state->aspath,
> - &set->action.ext_community,
> - peer->conf.remote_as);
> - break;
> }
> }
> }
> @@ -244,13 +241,12 @@ rde_filter_match(struct filter_rule *f,
> peer) == 0)
> return (0);
> break;
> + case COMMUNITY_TYPE_EXT:
> + if (community_ext_match(asp, &f->match.community[i],
> + peer) == 0)
> + return (0);
> }
> }
> - if (asp != NULL &&
> - (f->match.ext_community.flags & EXT_COMMUNITY_FLAG_VALID))
> - if (community_ext_match(asp, &f->match.ext_community,
> - peer->conf.remote_as) == 0)
> - return (0);
>
> if (state != NULL && f->match.nexthop.flags != 0) {
> struct bgpd_addr *nexthop, *cmpaddr;
> @@ -540,12 +536,6 @@ filterset_cmp(struct filter_set *a, stru
> sizeof(a->action.community)));
> }
>
> - if (a->type == ACTION_SET_EXT_COMMUNITY ||
> - a->type == ACTION_DEL_EXT_COMMUNITY) { /* a->type == b->type */
> - return (memcmp(&a->action.ext_community,
> - &b->action.ext_community, sizeof(a->action.ext_community)));
> - }
> -
> if (a->type == ACTION_SET_NEXTHOP && b->type == ACTION_SET_NEXTHOP) {
> /*
> * This is the only interesting case, all others are considered
> @@ -658,14 +648,6 @@ filterset_equal(struct filter_set_head *
> a->action.origin == b->action.origin)
> continue;
> break;
> - case ACTION_SET_EXT_COMMUNITY:
> - case ACTION_DEL_EXT_COMMUNITY:
> - if (a->type == b->type && memcmp(
> - &a->action.ext_community,
> - &b->action.ext_community,
> - sizeof(a->action.ext_community)) == 0)
> - continue;
> - break;
> }
> /* compare failed */
> return (0);
> @@ -710,10 +692,6 @@ filterset_name(enum action_types type)
> return ("rtlabel");
> case ACTION_SET_ORIGIN:
> return ("origin");
> - case ACTION_SET_EXT_COMMUNITY:
> - return ("ext-community");
> - case ACTION_DEL_EXT_COMMUNITY:
> - return ("ext-community delete");
> }
>
> fatalx("filterset_name: got lost");
> Index: usr.sbin/bgpd/rde_update.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde_update.c,v
> retrieving revision 1.105
> diff -u -p -r1.105 rde_update.c
> --- usr.sbin/bgpd/rde_update.c 29 Nov 2018 12:10:51 -0000 1.105
> +++ usr.sbin/bgpd/rde_update.c 12 Dec 2018 12:56:51 -0000
> @@ -68,18 +68,18 @@ SIPHASH_KEY uptree_key;
>
> static struct filter_community comm_no_advertise = {
> .type = COMMUNITY_TYPE_BASIC,
> - .data1 = COMMUNITY_WELLKNOWN,
> - .data2 = COMMUNITY_NO_ADVERTISE
> + .c.b.data1 = COMMUNITY_WELLKNOWN,
> + .c.b.data2 = COMMUNITY_NO_ADVERTISE
> };
> static struct filter_community comm_no_export = {
> .type = COMMUNITY_TYPE_BASIC,
> - .data1 = COMMUNITY_WELLKNOWN,
> - .data2 = COMMUNITY_NO_EXPORT
> + .c.b.data1 = COMMUNITY_WELLKNOWN,
> + .c.b.data2 = COMMUNITY_NO_EXPORT
> };
> static struct filter_community comm_no_expsubconfed = {
> .type = COMMUNITY_TYPE_BASIC,
> - .data1 = COMMUNITY_WELLKNOWN,
> - .data2 = COMMUNITY_NO_EXPSUBCONFED
> + .c.b.data1 = COMMUNITY_WELLKNOWN,
> + .c.b.data2 = COMMUNITY_NO_EXPSUBCONFED
> };
>
> void
>