diff options
-rw-r--r-- | nest/route.h | 3 | ||||
-rw-r--r-- | nest/rt-table.c | 44 | ||||
-rw-r--r-- | proto/bgp/packets.c | 2 |
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: |