]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: An ability to set attributes for default-originate via route-map
authorDonatas Abraitis <donatas.abraitis@gmail.com>
Wed, 27 Nov 2019 20:50:33 +0000 (22:50 +0200)
committerDonatas Abraitis <donatas.abraitis@gmail.com>
Tue, 7 Jan 2020 08:05:33 +0000 (10:05 +0200)
With this change, we are able to set attributes via route-map to the default
route. It's useful in cases where we have two or more spines and we want to
prefer one router over others for leaves. This simplifies configuration instead
of using 'network 0.0.0.0/0' or 'ip route 0.0.0.0/0 ...' and 'redistribute
static' combination.

Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
bgpd/bgp_updgrp_adv.c

index 49e87adc3cf2914e28394794d360093620ec62c1..07aa3eafb6272cf859300832afad932c710856b8 100644 (file)
@@ -710,12 +710,11 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
 {
        struct bgp *bgp;
        struct attr attr;
+       struct attr *new_attr = &attr;
        struct aspath *aspath;
-       struct bgp_path_info tmp_info;
        struct prefix p;
        struct peer *from;
        struct bgp_node *rn;
-       struct bgp_path_info *ri;
        struct peer *peer;
        route_map_result_t ret = RMAP_DENYMATCH;
        afi_t afi;
@@ -755,37 +754,33 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
        }
 
        if (peer->default_rmap[afi][safi].name) {
+               struct attr attr_tmp = attr;
+               struct bgp_path_info bpi_rmap = {0};
+
+               bpi_rmap.peer = bgp->peer_self;
+               bpi_rmap.attr = &attr_tmp;
+
                SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT);
+
+               /* Iterate over the RIB to see if we can announce
+                * the default route. We announce the default
+                * route only if route-map has a match.
+                */
                for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
                     rn = bgp_route_next(rn)) {
-                       for (ri = bgp_node_get_bgp_path_info(rn);
-                            ri; ri = ri->next) {
-                               struct attr dummy_attr;
-
-                               /* Provide dummy so the route-map can't modify
-                                * the attributes */
-                               dummy_attr = *ri->attr;
-                               tmp_info.peer = ri->peer;
-                               tmp_info.attr = &dummy_attr;
-
-                               ret = route_map_apply(
-                                       peer->default_rmap[afi][safi].map,
-                                       &rn->p, RMAP_BGP, &tmp_info);
-
-                               /* The route map might have set attributes. If
-                                * we don't flush them
-                                * here, they will be leaked. */
-                               bgp_attr_flush(&dummy_attr);
-                               if (ret != RMAP_DENYMATCH)
-                                       break;
-                       }
+                       ret = route_map_apply(peer->default_rmap[afi][safi].map,
+                                             &rn->p, RMAP_BGP, &bpi_rmap);
+
                        if (ret != RMAP_DENYMATCH)
                                break;
                }
                bgp->peer_self->rmap_type = 0;
+               new_attr = bgp_attr_intern(&attr_tmp);
 
-               if (ret == RMAP_DENYMATCH)
+               if (ret == RMAP_DENYMATCH) {
+                       bgp_attr_flush(&attr_tmp);
                        withdraw = 1;
+               }
        }
 
        if (withdraw) {
@@ -797,12 +792,12 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
                                SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
 
                        if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
-                               bgp_attr_add_gshut_community(&attr);
+                               bgp_attr_add_gshut_community(new_attr);
                        }
 
                        SET_FLAG(subgrp->sflags,
                                 SUBGRP_STATUS_DEFAULT_ORIGINATE);
-                       subgroup_default_update_packet(subgrp, &attr, from);
+                       subgroup_default_update_packet(subgrp, new_attr, from);
 
                        /* The 'neighbor x.x.x.x default-originate' default will
                         * act as an