]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Add extended community to aggregates
authorDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 16 Oct 2018 12:13:03 +0000 (08:13 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 16 Oct 2018 12:13:03 +0000 (08:13 -0400)
Add the ability to aggregate routes to handle
extended communities.  Make the actions similiar
to what we do for normal communities.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
bgpd/bgp_attr.c
bgpd/bgp_attr.h
bgpd/bgp_route.c

index c7d7c56a126697c0c7a59ac8b6baf0e5d24227a4..2360408283803565a1adc73ed96811dade3c514c 100644 (file)
@@ -723,8 +723,9 @@ struct attr *bgp_attr_default_set(struct attr *attr, uint8_t origin)
 /* Create the attributes for an aggregate */
 struct attr *bgp_attr_aggregate_intern(struct bgp *bgp, uint8_t origin,
                                       struct aspath *aspath,
-                                      struct community *community, int as_set,
-                                      uint8_t atomic_aggregate)
+                                      struct community *community,
+                                      struct ecommunity *ecommunity,
+                                      int as_set, uint8_t atomic_aggregate)
 {
        struct attr attr;
        struct attr *new;
@@ -760,6 +761,11 @@ struct attr *bgp_attr_aggregate_intern(struct bgp *bgp, uint8_t origin,
                attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
        }
 
+       if (ecommunity) {
+               attr.ecommunity = ecommunity;
+               attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
+       }
+
        if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
                bgp_attr_add_gshut_community(&attr);
        }
index 883b129136220645e80aa1d63947e4dbda0170c3..daac86ba9777d373c02b650a62d6e902f97280b9 100644 (file)
@@ -272,10 +272,12 @@ extern void bgp_attr_unintern_sub(struct attr *);
 extern void bgp_attr_unintern(struct attr **);
 extern void bgp_attr_flush(struct attr *);
 extern struct attr *bgp_attr_default_set(struct attr *attr, uint8_t);
-extern struct attr *bgp_attr_aggregate_intern(struct bgp *, uint8_t,
-                                             struct aspath *,
-                                             struct community *, int as_set,
-                                             uint8_t);
+extern struct attr *bgp_attr_aggregate_intern(struct bgp *bgp, uint8_t origin,
+                                             struct aspath *aspath,
+                                             struct community *community,
+                                             struct ecommunity *ecommunity,
+                                             int as_set,
+                                             uint8_t atomic_aggregate);
 extern bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *,
                                       struct stream *, struct attr *,
                                       struct bpacket_attr_vec_arr *vecarr,
index c15ce7d9aacee18dc969a6e6430b46cd2bc36ca0..8f2bdea179ec02442ee7d92602423696b44050e4 100644 (file)
@@ -5482,7 +5482,8 @@ static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
 
 static int bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
                                   struct aspath *aspath,
-                                  struct community *comm)
+                                  struct community *comm,
+                                  struct ecommunity *ecomm)
 {
        static struct aspath *ae = NULL;
 
@@ -5501,6 +5502,9 @@ static int bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
        if (!community_cmp(pi->attr->community, comm))
                return 0;
 
+       if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
+               return 0;
+
        if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
                return 0;
 
@@ -5511,6 +5515,7 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
                                  struct prefix *p, uint8_t origin,
                                  struct aspath *aspath,
                                  struct community *community,
+                                 struct ecommunity *ecommunity,
                                  uint8_t atomic_aggregate,
                                  struct bgp_aggregate *aggregate)
 {
@@ -5532,14 +5537,16 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
                 * If the aggregate information has not changed
                 * no need to re-install it again.
                 */
-               if (bgp_aggregate_info_same(rn->info, origin, aspath,
-                                           community)) {
+               if (bgp_aggregate_info_same(rn->info, origin, aspath, community,
+                                           ecommunity)) {
                        bgp_unlock_node(rn);
 
                        if (aspath)
                                aspath_free(aspath);
                        if (community)
                                community_free(community);
+                       if (ecommunity)
+                               ecommunity_free(&ecommunity);
 
                        return;
                }
@@ -5550,12 +5557,13 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
                if (pi)
                        bgp_path_info_delete(rn, pi);
 
-               new = info_make(
-                       ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
-                       bgp_attr_aggregate_intern(bgp, origin, aspath,
-                                                 community, aggregate->as_set,
-                                                 atomic_aggregate),
-                       rn);
+               new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
+                               bgp->peer_self,
+                               bgp_attr_aggregate_intern(bgp, origin, aspath,
+                                                         community, ecommunity,
+                                                         aggregate->as_set,
+                                                         atomic_aggregate),
+                               rn);
                SET_FLAG(new->flags, BGP_PATH_VALID);
 
                bgp_path_info_add(rn, new);
@@ -5591,6 +5599,8 @@ static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
        struct aspath *asmerge = NULL;
        struct community *community = NULL;
        struct community *commerge = NULL;
+       struct ecommunity *ecommunity = NULL;
+       struct ecommunity *ecommerge = NULL;
        struct bgp_path_info *pi;
        unsigned long match = 0;
        uint8_t atomic_aggregate = 0;
@@ -5670,16 +5680,30 @@ static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
                        } else
                                aspath = aspath_dup(pi->attr->aspath);
 
-                       if (!pi->attr->community)
-                               continue;
+                       if (pi->attr->community) {
+                               if (community) {
+                                       commerge = community_merge(
+                                               community, pi->attr->community);
+                                       community =
+                                               community_uniq_sort(commerge);
+                                       community_free(commerge);
+                               } else
+                                       community = community_dup(
+                                               pi->attr->community);
+                       }
 
-                       if (community) {
-                               commerge = community_merge(community,
-                                                          pi->attr->community);
-                               community = community_uniq_sort(commerge);
-                               community_free(commerge);
-                       } else
-                               community = community_dup(pi->attr->community);
+                       if (pi->attr->ecommunity) {
+                               if (ecommunity) {
+                                       ecommerge = ecommunity_merge(
+                                               ecommunity,
+                                               pi->attr->ecommunity);
+                                       ecommunity =
+                                               ecommunity_uniq_sort(ecommerge);
+                                       ecommunity_free(&ecommerge);
+                               } else
+                                       ecommunity = ecommunity_dup(
+                                               pi->attr->ecommunity);
+                       }
                }
                if (match)
                        bgp_process(bgp, rn, afi, safi);
@@ -5716,17 +5740,32 @@ static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
                                        community = community_dup(
                                                pinew->attr->community);
                        }
+
+                       if (pinew->attr->ecommunity) {
+                               if (ecommunity) {
+                                       ecommerge = ecommunity_merge(
+                                               ecommunity,
+                                               pinew->attr->ecommunity);
+                                       ecommunity =
+                                               ecommunity_uniq_sort(ecommerge);
+                                       ecommunity_free(&ecommerge);
+                               } else
+                                       ecommunity = ecommunity_dup(
+                                               pinew->attr->ecommunity);
+                       }
                }
        }
 
        bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
-                             atomic_aggregate, aggregate);
+                             ecommunity, atomic_aggregate, aggregate);
 
        if (aggregate->count == 0) {
                if (aspath)
                        aspath_free(aspath);
                if (community)
                        community_free(community);
+               if (ecommunity)
+                       ecommunity_free(&ecommunity);
        }
 }
 
@@ -5871,7 +5910,8 @@ static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
 
        aggregate = bgp_aggregate_get_node_info(rn);
        bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
-       bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL, 0, aggregate);
+       bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL, NULL, 0,
+                             aggregate);
 
        /* Unlock aggregate address configuration. */
        bgp_aggregate_set_node_info(rn, NULL);