summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Franke <chris@opensourcerouting.org>2012-12-07 16:45:52 +0000
committerDavid Lamparter <equinox@opensourcerouting.org>2013-01-16 01:45:57 +0100
commitdcab1bb822161d55795aad59b14c5c5d79b71e1f (patch)
tree0e55397d41d91f613123c6c812bc8691caa02b27
parent86998bc2bc9506841250c8d49dd2df2464660a18 (diff)
bgpd: conditional default-originate using route-map
Incorporate a patch by Svetozar Mihailov which implements default-originate route-maps to behave as expected, i.e. allowing the default route to be advertised conditionally, depending on a criterion given by the route-map. I am aware that the performance attributes of the following implementation are far from optimal. However, this affects only code paths belonging to a feature that is broken without this patch, therefore, it seems reasonable to me to have this in the mainline for now. Cc: Svetozar Mihailov <quagga@j.zarhi.com> Reported-by: Sébastien Cramatte <scramatte@gmail.com> Signed-off-by: Christian Franke <chris@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
-rw-r--r--NEWS5
-rw-r--r--bgpd/bgp_nexthop.c10
-rw-r--r--bgpd/bgp_route.c48
3 files changed, 49 insertions, 14 deletions
diff --git a/NEWS b/NEWS
index d67d6646..fe0d5ad2 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,10 @@
Note: this file lists major user-visible changes only.
+- [bgpd] The semantics of default-originate route-map have changed.
+ The route-map is now used to advertise the default route conditionally.
+ The old behaviour which allowed to set attributes on the originated
+ default route is no longer supported.
+
* Changes in Quagga 0.99.21
- [bgpd] BGP multipath support has been merged
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 0e56d368..d4692366 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -506,6 +506,16 @@ bgp_scan (afi_t afi, safi_t safi)
else if (afi == AFI_IP6)
zlog_debug ("scanning IPv6 Unicast routing tables");
}
+
+ /* Reevaluate default-originate route-maps and announce/withdraw
+ * default route if neccesary. */
+ for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
+ {
+ if (peer->status == Established
+ && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)
+ && peer->default_rmap[afi][safi].name)
+ bgp_default_originate (peer, afi, safi, 0);
+ }
}
/* BGP scan thread. This thread check nexthop reachability. */
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 06bd5991..8bc72d7b 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -2462,8 +2462,9 @@ bgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw)
struct attr attr;
struct aspath *aspath;
struct prefix p;
- struct bgp_info binfo;
struct peer *from;
+ struct bgp_node *rn;
+ struct bgp_info *ri;
int ret = RMAP_DENYMATCH;
if (!(afi == AFI_IP || afi == AFI_IP6))
@@ -2505,21 +2506,37 @@ bgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw)
if (peer->default_rmap[afi][safi].name)
{
- binfo.peer = bgp->peer_self;
- binfo.attr = &attr;
-
SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT);
-
- ret = route_map_apply (peer->default_rmap[afi][safi].map, &p,
- RMAP_BGP, &binfo);
-
+ for (rn = bgp_table_top(bgp->rib[afi][safi]); rn; rn = bgp_route_next(rn))
+ {
+ for (ri = rn->info; ri; ri = ri->next)
+ {
+ struct attr dummy_attr;
+ struct attr_extra dummy_extra;
+ struct bgp_info info;
+
+ /* Provide dummy so the route-map can't modify the attributes */
+ dummy_attr.extra = &dummy_extra;
+ bgp_attr_dup(&dummy_attr, ri->attr);
+ info.peer = ri->peer;
+ info.attr = &dummy_attr;
+
+ ret = route_map_apply(peer->default_rmap[afi][safi].map, &rn->p,
+ RMAP_BGP, &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;
+ }
+ if (ret != RMAP_DENYMATCH)
+ break;
+ }
bgp->peer_self->rmap_type = 0;
if (ret == RMAP_DENYMATCH)
- {
- bgp_attr_flush (&attr);
- withdraw = 1;
- }
+ withdraw = 1;
}
if (withdraw)
@@ -2530,8 +2547,11 @@ bgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw)
}
else
{
- SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE);
- bgp_default_update_send (peer, &attr, afi, safi, from);
+ if (! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE))
+ {
+ SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE);
+ bgp_default_update_send (peer, &attr, afi, safi, from);
+ }
}
bgp_attr_extra_free (&attr);