]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Add Large community support to aggregate routes
authorDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 16 Oct 2018 12:24:01 +0000 (08:24 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 16 Oct 2018 12:24:01 +0000 (08:24 -0400)
Add the ability to track and support Large communities for aggregate
routes.

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

index 2360408283803565a1adc73ed96811dade3c514c..fb7db9d57eda86fc1f0432c94eea82926a7875d9 100644 (file)
@@ -725,6 +725,7 @@ struct attr *bgp_attr_aggregate_intern(struct bgp *bgp, uint8_t origin,
                                       struct aspath *aspath,
                                       struct community *community,
                                       struct ecommunity *ecommunity,
+                                      struct lcommunity *lcommunity,
                                       int as_set, uint8_t atomic_aggregate)
 {
        struct attr attr;
@@ -766,6 +767,11 @@ struct attr *bgp_attr_aggregate_intern(struct bgp *bgp, uint8_t origin,
                attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
        }
 
+       if (lcommunity) {
+               attr.lcommunity = lcommunity;
+               attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
+       }
+
        if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
                bgp_attr_add_gshut_community(&attr);
        }
index daac86ba9777d373c02b650a62d6e902f97280b9..4c8f98947e31e5fe02197624ec9e15771147cb7e 100644 (file)
@@ -276,6 +276,7 @@ extern struct attr *bgp_attr_aggregate_intern(struct bgp *bgp, uint8_t origin,
                                              struct aspath *aspath,
                                              struct community *community,
                                              struct ecommunity *ecommunity,
+                                             struct lcommunity *lcommunity,
                                              int as_set,
                                              uint8_t atomic_aggregate);
 extern bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *,
index 8f2bdea179ec02442ee7d92602423696b44050e4..bb6b8aab3c90b4b0dd950bcca4604494aebd67e9 100644 (file)
@@ -5483,7 +5483,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 ecommunity *ecomm)
+                                  struct ecommunity *ecomm,
+                                  struct lcommunity *lcomm)
 {
        static struct aspath *ae = NULL;
 
@@ -5505,6 +5506,9 @@ static int bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
        if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
                return 0;
 
+       if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
+               return 0;
+
        if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
                return 0;
 
@@ -5516,6 +5520,7 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
                                  struct aspath *aspath,
                                  struct community *community,
                                  struct ecommunity *ecommunity,
+                                 struct lcommunity *lcommunity,
                                  uint8_t atomic_aggregate,
                                  struct bgp_aggregate *aggregate)
 {
@@ -5538,7 +5543,7 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
                 * no need to re-install it again.
                 */
                if (bgp_aggregate_info_same(rn->info, origin, aspath, community,
-                                           ecommunity)) {
+                                           ecommunity, lcommunity)) {
                        bgp_unlock_node(rn);
 
                        if (aspath)
@@ -5547,6 +5552,8 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
                                community_free(community);
                        if (ecommunity)
                                ecommunity_free(&ecommunity);
+                       if (lcommunity)
+                               lcommunity_free(&lcommunity);
 
                        return;
                }
@@ -5561,6 +5568,7 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
                                bgp->peer_self,
                                bgp_attr_aggregate_intern(bgp, origin, aspath,
                                                          community, ecommunity,
+                                                         lcommunity,
                                                          aggregate->as_set,
                                                          atomic_aggregate),
                                rn);
@@ -5601,6 +5609,8 @@ static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
        struct community *commerge = NULL;
        struct ecommunity *ecommunity = NULL;
        struct ecommunity *ecommerge = NULL;
+       struct lcommunity *lcommunity = NULL;
+       struct lcommunity *lcommerge = NULL;
        struct bgp_path_info *pi;
        unsigned long match = 0;
        uint8_t atomic_aggregate = 0;
@@ -5704,6 +5714,19 @@ static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
                                        ecommunity = ecommunity_dup(
                                                pi->attr->ecommunity);
                        }
+
+                       if (pi->attr->lcommunity) {
+                               if (lcommunity) {
+                                       lcommerge = lcommunity_merge(
+                                               lcommunity,
+                                               pi->attr->lcommunity);
+                                       lcommunity =
+                                               lcommunity_uniq_sort(lcommerge);
+                                       lcommunity_free(&lcommerge);
+                               } else
+                                       lcommunity = lcommunity_dup(
+                                               pi->attr->lcommunity);
+                       }
                }
                if (match)
                        bgp_process(bgp, rn, afi, safi);
@@ -5753,11 +5776,25 @@ static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
                                        ecommunity = ecommunity_dup(
                                                pinew->attr->ecommunity);
                        }
+
+                       if (pinew->attr->lcommunity) {
+                               if (lcommunity) {
+                                       lcommerge = lcommunity_merge(
+                                               lcommunity,
+                                               pinew->attr->lcommunity);
+                                       lcommunity =
+                                               lcommunity_uniq_sort(lcommerge);
+                                       lcommunity_free(&lcommerge);
+                               } else
+                                       lcommunity = lcommunity_dup(
+                                               pinew->attr->lcommunity);
+                       }
                }
        }
 
        bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
-                             ecommunity, atomic_aggregate, aggregate);
+                             ecommunity, lcommunity, atomic_aggregate,
+                             aggregate);
 
        if (aggregate->count == 0) {
                if (aspath)
@@ -5766,6 +5803,8 @@ static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
                        community_free(community);
                if (ecommunity)
                        ecommunity_free(&ecommunity);
+               if (lcommunity)
+                       lcommunity_free(&lcommunity);
        }
 }
 
@@ -5910,8 +5949,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, NULL, 0,
-                             aggregate);
+       bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
+                             NULL, NULL,  0, aggregate);
 
        /* Unlock aggregate address configuration. */
        bgp_aggregate_set_node_info(rn, NULL);