summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nest/route.h3
-rw-r--r--nest/rt-table.c44
-rw-r--r--proto/bgp/packets.c2
3 files changed, 38 insertions, 11 deletions
diff --git a/nest/route.h b/nest/route.h
index ade14857..98d605c8 100644
--- a/nest/route.h
+++ b/nest/route.h
@@ -346,8 +346,9 @@ int rt_feed_channel(struct channel *c);
void rt_feed_channel_abort(struct channel *c);
int rt_reload_channel(struct channel *c);
void rt_reload_channel_abort(struct channel *c);
+void rt_refeed_channel(struct channel *c);
void rt_prune_sync(rtable *t, int all);
-int rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old, struct rte_storage **old_exported, int refeed);
+int rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old, struct rte_storage **old_exported);
struct rtable_config *rt_new_table(struct symbol *s, uint addr_type);
diff --git a/nest/rt-table.c b/nest/rt-table.c
index 837e0ab9..b005f6f3 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -451,8 +451,11 @@ do_rt_notify(struct channel *c, const net_addr *net, rte *new, rte *old, int ref
struct rte_storage *old_exported = NULL;
if (c->out_table)
{
- if (!rte_update_out(c, net, new, old, &old_exported, refeed))
+ if (!rte_update_out(c, net, new, old, &old_exported))
+ {
+ rte_trace_out(D_ROUTES, c, new, "idempotent");
return;
+ }
}
if (new)
@@ -2406,7 +2409,7 @@ again:
*/
int
-rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, struct rte_storage **old_exported, int refeed)
+rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, struct rte_storage **old_exported)
{
struct rtable *tab = c->out_table;
struct rte_src *src;
@@ -2423,7 +2426,7 @@ rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, struct
src = old0->src;
if (!net)
- goto drop_withdraw;
+ goto drop;
}
/* Find the old rte */
@@ -2433,7 +2436,7 @@ rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, struct
if (old = *pos)
{
if (new && rte_same(&(*pos)->rte, new))
- goto drop_update;
+ goto drop;
/* Remove the old rte */
*pos = old->next;
@@ -2444,7 +2447,7 @@ rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, struct
if (!new)
{
if (!old)
- goto drop_withdraw;
+ goto drop;
if (!net->routes)
fib_delete(&tab->fib, net);
@@ -2460,13 +2463,36 @@ rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, struct
tab->rt_count++;
return 1;
-drop_update:
- return refeed;
-
-drop_withdraw:
+drop:
return 0;
}
+void
+rt_refeed_channel(struct channel *c)
+{
+ if (!c->out_table)
+ {
+ channel_request_feeding(c);
+ return;
+ }
+
+ ASSERT_DIE(c->ra_mode != RA_ANY);
+
+ c->proto->feed_begin(c, 0);
+
+ FIB_WALK(&c->out_table->fib, net, n)
+ {
+ if (!n->routes)
+ continue;
+
+ rte e = n->routes->rte;
+ c->proto->rt_notify(c->proto, c, n->n.addr, &e, NULL);
+ }
+ FIB_WALK_END;
+
+ c->proto->feed_end(c);
+}
+
/*
* Hostcache
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index 647551e5..f1e6d7d2 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -2695,7 +2695,7 @@ bgp_rx_route_refresh(struct bgp_conn *conn, byte *pkt, uint len)
{
case BGP_RR_REQUEST:
BGP_TRACE(D_PACKETS, "Got ROUTE-REFRESH");
- channel_request_feeding(&c->c);
+ rt_refeed_channel(&c->c);
break;
case BGP_RR_BEGIN: