summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2015-05-20 03:04:20 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2015-05-20 03:04:20 +0200
commit0de4848df68903c8805e55569624e2522f96dcda (patch)
tree508cc98ccc32b8936b8f970cdd2d3039c95053ee
parentbgpd-nht-import-check-fix.patch (diff)
downloadfrr-0de4848df68903c8805e55569624e2522f96dcda.tar.xz
frr-0de4848df68903c8805e55569624e2522f96dcda.zip
If a route-map is used on a neighbor default-originate statement we need to dynamically add/del the default route if the permit/deny result of the route-map changes.
-rw-r--r--bgpd/bgp_route.c12
-rw-r--r--bgpd/bgp_updgrp.c42
-rw-r--r--bgpd/bgp_updgrp.h1
-rw-r--r--bgpd/bgpd.c7
-rw-r--r--bgpd/bgpd.h4
5 files changed, 64 insertions, 2 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 55c2f1392..be35c9c1f 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -2556,7 +2556,17 @@ bgp_process_main (struct work_queue *wq, void *data)
/* bestpath has changed; bump version */
if (old_select || new_select)
- bgp_bump_version(rn);
+ {
+ bgp_bump_version(rn);
+
+ if (!bgp->t_rmap_def_originate_eval)
+ {
+ bgp_lock (bgp);
+ THREAD_TIMER_ON(master, bgp->t_rmap_def_originate_eval,
+ update_group_refresh_default_originate_route_map,
+ bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER);
+ }
+ }
if (old_select)
bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c
index 667a30c6d..3c4e79366 100644
--- a/bgpd/bgp_updgrp.c
+++ b/bgpd/bgp_updgrp.c
@@ -1739,7 +1739,9 @@ update_group_af_walk (struct bgp *bgp, afi_t afi, safi_t safi,
memset (&wctx, 0, sizeof (wctx));
wctx.cb = cb;
wctx.context = ctx;
- hash_walk (bgp->update_groups[afid], update_group_walkcb, &wctx);
+
+ if (bgp->update_groups[afid])
+ hash_walk (bgp->update_groups[afid], update_group_walkcb, &wctx);
}
void
@@ -1763,6 +1765,44 @@ update_group_periodic_merge (struct bgp *bgp)
(void *) reason);
}
+static int
+update_group_default_originate_route_map_walkcb(struct update_group *updgrp,
+ void *arg)
+{
+ struct update_subgroup *subgrp;
+ struct peer *peer;
+ struct peer_af *paf;
+ afi_t afi;
+ safi_t safi;
+
+ UPDGRP_FOREACH_SUBGRP (updgrp, subgrp)
+ {
+ peer = SUBGRP_PEER (subgrp);
+ afi = SUBGRP_AFI (subgrp);
+ safi = SUBGRP_SAFI (subgrp);
+
+ if (peer->default_rmap[afi][safi].name)
+ {
+ subgroup_default_originate (subgrp, 0);
+ }
+ }
+
+ return UPDWALK_CONTINUE;
+}
+
+void
+update_group_refresh_default_originate_route_map (struct thread *thread)
+{
+ struct bgp *bgp;
+ char reason[] = "refresh default-originate route-map";
+
+ bgp = THREAD_ARG(thread);
+ update_group_walk (bgp, update_group_default_originate_route_map_walkcb,
+ reason);
+ THREAD_TIMER_OFF (bgp->t_rmap_def_originate_eval);
+ bgp_unlock(bgp);
+}
+
/*
* peer_af_announce_route
*
diff --git a/bgpd/bgp_updgrp.h b/bgpd/bgp_updgrp.h
index 49fdc26e9..1a04f0ad3 100644
--- a/bgpd/bgp_updgrp.h
+++ b/bgpd/bgp_updgrp.h
@@ -377,6 +377,7 @@ extern void update_group_af_walk (struct bgp *bgp, afi_t afi, safi_t safi,
updgrp_walkcb cb, void *ctx);
extern void update_group_walk (struct bgp *bgp, updgrp_walkcb cb, void *ctx);
extern void update_group_periodic_merge (struct bgp *bgp);
+extern void update_group_refresh_default_originate_route_map (struct thread *thread);
extern void update_group_start_advtimer (struct bgp *bgp);
extern void update_subgroup_inherit_info (struct update_subgroup *to,
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index eb61d8b40..61b2fb93c 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -2612,6 +2612,7 @@ bgp_get (struct bgp **bgp_val, as_t *as, const char *name)
bgp_router_id_set(bgp, &router_id_zebra);
*bgp_val = bgp;
+ bgp->t_rmap_def_originate_eval = NULL;
bgp->t_rmap_update = NULL;
bgp->rmap_update_timer = RMAP_DEFAULT_UPDATE_TIMER;
@@ -2694,6 +2695,12 @@ bgp_delete (struct bgp *bgp)
peer_delete(bgp->peer_self);
bgp->peer_self = NULL;
}
+
+ if (bgp->t_rmap_def_originate_eval)
+ {
+ BGP_TIMER_OFF(bgp->t_rmap_def_originate_eval);
+ bgp_unlock(bgp);
+ }
/* Remove visibility via the master list - there may however still be
* routes to be processed still referencing the struct bgp.
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index fc8683f2b..0cd72e0e6 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -266,6 +266,10 @@ struct bgp
u_int32_t rmap_update_timer; /* Route map update timer */
#define RMAP_DEFAULT_UPDATE_TIMER 5 /* disabled by default */
+ /* timer to re-evaluate neighbor default-originate route-maps */
+ struct thread *t_rmap_def_originate_eval;
+#define RMAP_DEFAULT_ORIGINATE_EVAL_TIMER 5
+
/* BGP distance configuration. */
u_char distance_ebgp;
u_char distance_ibgp;