]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: Code to handle BGP aggregate's as-path.
authorNaveen Thanikachalam <nthanikachal@vmware.com>
Wed, 6 Feb 2019 13:44:20 +0000 (05:44 -0800)
committerNaveen Thanikachalam <nthanikachal@vmware.com>
Fri, 1 Mar 2019 04:22:30 +0000 (20:22 -0800)
With this commit:
1) 'struct bgp_aggregate' is moved to bgp_route.h from bgp_route.c
2) Hashes to accommodate the as-path, communities, extended-communities and
   large-communities attributes of all the routes aggregated by an
   aggregate route is introduced in 'struct bgp_aggregate'.
3) Place-holders for the aggregate route's as-path, communities,
   extended-communities and large-communities attributes are introduced in
   'struct bgp_aggregate'.
4) The code to manage the as-path of the routes that are aggregatable under
   a configured aggregate-address is introduced.
5) The code to compute the aggregate-route's as-path is introduced.

Signed-off-by: NaveenThanikachalam <nthanikachal@vmware.com>
bgpd/bgp_aspath.c
bgpd/bgp_aspath.h
bgpd/bgp_route.c
bgpd/bgp_route.h

index 9521a9e912eafcc86aaf2f7c50d847d5c9d42249..bf6f3f81f6b548d65b1140be22d7534388878ff2 100644 (file)
@@ -212,6 +212,9 @@ static struct assegment *assegment_append_asns(struct assegment *seg,
 {
        as_t *newas;
 
+       if (!seg)
+               return seg;
+
        newas = XREALLOC(MTYPE_AS_SEG_DATA, seg->as,
                         ASSEGMENT_DATA_SIZE(seg->length + num, 1));
 
@@ -1372,7 +1375,8 @@ static struct aspath *aspath_merge(struct aspath *as1, struct aspath *as2)
        while (last && last->next)
                last = last->next;
 
-       last->next = as2->segments;
+       if (last)
+               last->next = as2->segments;
        as2->segments = new;
        aspath_str_update(as2, false);
        return as2;
@@ -1447,7 +1451,8 @@ struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2)
                 * bypass the merged seg2, and attach any chain after it
                 * to chain descending from as2's head
                 */
-               as2segtail->next = as2seghead->next;
+               if (as2segtail)
+                       as2segtail->next = as2seghead->next;
 
                /* as2->segments is now referenceless and useless */
                assegment_free(as2seghead);
@@ -2096,3 +2101,110 @@ void aspath_print_all_vty(struct vty *vty)
                                       void *))aspath_show_all_iterator,
                     vty);
 }
+
+static struct aspath *bgp_aggr_aspath_lookup(struct bgp_aggregate *aggregate,
+                                            struct aspath *aspath)
+{
+       return hash_lookup(aggregate->aspath_hash, aspath);
+}
+
+static void *bgp_aggr_aspath_hash_alloc(void *p)
+{
+       struct aspath *ref = (struct aspath *)p;
+       struct aspath *aspath = NULL;
+
+       aspath = aspath_dup(ref);
+       return aspath;
+}
+
+static void bgp_aggr_aspath_prepare(struct hash_backet *hb, void *arg)
+{
+       struct aspath *asmerge = NULL;
+       struct aspath *hb_aspath = hb->data;
+       struct aspath **aggr_aspath = arg;
+
+       if (*aggr_aspath) {
+               asmerge = aspath_aggregate(*aggr_aspath, hb_aspath);
+               aspath_free(*aggr_aspath);
+               *aggr_aspath = asmerge;
+       } else
+               *aggr_aspath = aspath_dup(hb_aspath);
+}
+
+void bgp_aggr_aspath_remove(void *arg)
+{
+       struct aspath *aspath = arg;
+
+       aspath_free(aspath);
+}
+
+void bgp_compute_aggregate_aspath(struct bgp_aggregate *aggregate,
+                                 struct aspath *aspath)
+{
+       struct aspath *aggr_aspath = NULL;
+
+       if ((aggregate == NULL) || (aspath == NULL))
+               return;
+
+       /* Create hash if not already created.
+        */
+       if (aggregate->aspath_hash == NULL)
+               aggregate->aspath_hash = hash_create(
+                                       aspath_key_make, aspath_cmp,
+                                       "BGP Aggregator as-path hash");
+
+       aggr_aspath = bgp_aggr_aspath_lookup(aggregate, aspath);
+       if (aggr_aspath == NULL) {
+               /* Insert as-path into hash.
+                */
+               aggr_aspath = hash_get(aggregate->aspath_hash, aspath,
+                                      bgp_aggr_aspath_hash_alloc);
+
+               /* Compute aggregate's as-path.
+                */
+               hash_iterate(aggregate->aspath_hash,
+                            bgp_aggr_aspath_prepare,
+                            &aggregate->aspath);
+       }
+
+       /* Increment refernce counter.
+        */
+       aggr_aspath->refcnt++;
+}
+
+void bgp_remove_aspath_from_aggregate(struct bgp_aggregate *aggregate,
+                                     struct aspath *aspath)
+{
+       struct aspath *aggr_aspath = NULL;
+       struct aspath *ret_aspath = NULL;
+
+       if ((aggregate == NULL) || (aspath == NULL))
+               return;
+
+       if (aggregate->aspath_hash == NULL)
+               return;
+
+       /* Look-up the aspath in the hash.
+        */
+       aggr_aspath = bgp_aggr_aspath_lookup(aggregate, aspath);
+       if (aggr_aspath) {
+               aggr_aspath->refcnt--;
+
+               if (aggr_aspath->refcnt == 0) {
+                       ret_aspath = hash_release(aggregate->aspath_hash,
+                                                 aggr_aspath);
+                       aspath_free(ret_aspath);
+
+                       /* Remove aggregate's old as-path.
+                        */
+                       aspath_free(aggregate->aspath);
+                       aggregate->aspath = NULL;
+
+                       /* Compute aggregate's as-path.
+                        */
+                       hash_iterate(aggregate->aspath_hash,
+                                    bgp_aggr_aspath_prepare,
+                                    &aggregate->aspath);
+               }
+       }
+}
index 9c9c687a6b7ae9d801dff98f2f2556d3446b733e..be5725c1aea739a5aa088b0eb786aa5036f2c1a9 100644 (file)
@@ -22,6 +22,7 @@
 #define _QUAGGA_BGP_ASPATH_H
 
 #include "lib/json.h"
+#include "bgpd/bgp_route.h"
 
 /* AS path segment type.  */
 #define AS_SET                       1
@@ -130,4 +131,10 @@ extern unsigned int aspath_has_as4(struct aspath *);
 /* For SNMP BGP4PATHATTRASPATHSEGMENT, might be useful for debug */
 extern uint8_t *aspath_snmp_pathseg(struct aspath *, size_t *);
 
+extern void bgp_compute_aggregate_aspath(struct bgp_aggregate *aggregate,
+                                        struct aspath *aspath);
+extern void bgp_remove_aspath_from_aggregate(struct bgp_aggregate *aggregate,
+                                            struct aspath *aspath);
+extern void bgp_aggr_aspath_remove(void *arg);
+
 #endif /* _QUAGGA_BGP_ASPATH_H */
index 99dc9d81249cab749d136a476cfd6cdcc7d66771..7ac53b43f2307f20abffc905ad83c376a70637d9 100644 (file)
@@ -5513,33 +5513,6 @@ DEFPY(ipv6_bgp_network,
                label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
 }
 
-/* Aggreagete address:
-
-  advertise-map  Set condition to advertise attribute
-  as-set         Generate AS set path information
-  attribute-map  Set attributes of aggregate
-  route-map      Set parameters of aggregate
-  summary-only   Filter more specific routes from updates
-  suppress-map   Conditionally filter more specific routes from updates
-  <cr>
- */
-struct bgp_aggregate {
-       /* Summary-only flag. */
-       uint8_t summary_only;
-
-       /* AS set generation. */
-       uint8_t as_set;
-
-       /* Route-map for aggregated route. */
-       struct route_map *map;
-
-       /* Suppress-count. */
-       unsigned long count;
-
-       /* SAFI configuration. */
-       safi_t safi;
-};
-
 static struct bgp_aggregate *bgp_aggregate_new(void)
 {
        return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
index 97d4aaeeba3ced0fda7d9b2c7d6ff33154fabe7a..a1287152c7120d4e9b5bfef8fa1255abc2306931 100644 (file)
@@ -272,6 +272,71 @@ struct bgp_static {
        struct prefix gatewayIp;
 };
 
+/* Aggreagete address:
+ *
+ *  advertise-map  Set condition to advertise attribute
+ *  as-set         Generate AS set path information
+ *  attribute-map  Set attributes of aggregate
+ *  route-map      Set parameters of aggregate
+ *  summary-only   Filter more specific routes from updates
+ *  suppress-map   Conditionally filter more specific routes from updates
+ *  <cr>
+ */
+struct bgp_aggregate {
+       /* Summary-only flag. */
+       uint8_t summary_only;
+
+       /* AS set generation. */
+       uint8_t as_set;
+
+       /* Route-map for aggregated route. */
+       struct route_map *map;
+
+       /* Suppress-count. */
+       unsigned long count;
+
+       /* Count of routes of origin type incomplete under this aggregate. */
+       unsigned long incomplete_origin_count;
+
+       /* Count of routes of origin type egp under this aggregate. */
+       unsigned long egp_origin_count;
+
+       /* Hash containing the communities of all the
+        * routes under this aggregate.
+        */
+       struct hash *community_hash;
+
+       /* Hash containing the extended communities of all the
+        * routes under this aggregate.
+        */
+       struct hash *ecommunity_hash;
+
+       /* Hash containing the large communities of all the
+        * routes under this aggregate.
+        */
+       struct hash *lcommunity_hash;
+
+       /* Hash containing the AS-Path of all the
+        * routes under this aggregate.
+        */
+       struct hash *aspath_hash;
+
+       /* Aggregate route's community. */
+       struct community *community;
+
+       /* Aggregate route's extended community. */
+       struct ecommunity *ecommunity;
+
+       /* Aggregate route's large community. */
+       struct lcommunity *lcommunity;
+
+       /* Aggregate route's as-path. */
+       struct aspath *aspath;
+
+       /* SAFI configuration. */
+       safi_t safi;
+};
+
 #define BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen)                                      \
        ((nhlen) < IPV4_MAX_BYTELEN                                            \
                 ? 0                                                           \