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).

-- 
: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;
+               } 
                *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

Reply via email to