summaryrefslogtreecommitdiff
path: root/proto/bgp/bgp.c
diff options
context:
space:
mode:
Diffstat (limited to 'proto/bgp/bgp.c')
-rw-r--r--proto/bgp/bgp.c94
1 files changed, 24 insertions, 70 deletions
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index 35e9ea59..78c36bc7 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -140,15 +140,6 @@ static void bgp_update_bfd(struct bgp_proto *p, const struct bfd_options *bfd);
static int bgp_incoming_connection(sock *sk, uint dummy UNUSED);
static void bgp_listen_sock_err(sock *sk UNUSED, int err);
-static void bgp_graceful_restart_feed(struct bgp_channel *c);
-static inline void channel_refresh_end_reload(struct channel *c)
-{
- channel_refresh_end(c);
-
- if (c->in_table)
- channel_request_reload(c);
-}
-
/**
* bgp_open - open a BGP instance
* @p: BGP instance
@@ -784,25 +775,25 @@ bgp_handle_graceful_restart(struct bgp_proto *p)
{
case BGP_GRS_NONE:
c->gr_active = BGP_GRS_ACTIVE;
- channel_refresh_begin(&c->c);
+ rt_refresh_begin(c->c.table, &c->c.in_req);
break;
case BGP_GRS_ACTIVE:
- channel_refresh_end(&c->c);
- channel_refresh_begin(&c->c);
+ rt_refresh_end(c->c.table, &c->c.in_req);
+ rt_refresh_begin(c->c.table, &c->c.in_req);
break;
case BGP_GRS_LLGR:
- channel_refresh_begin(&c->c);
- bgp_graceful_restart_feed(c);
+ rt_refresh_begin(c->c.table, &c->c.in_req);
+ rt_modify_stale(c->c.table, &c->c.in_req);
break;
}
}
else
{
/* Just flush the routes */
- channel_refresh_begin(&c->c);
- channel_refresh_end(&c->c);
+ rt_refresh_begin(c->c.table, &c->c.in_req);
+ rt_refresh_end(c->c.table, &c->c.in_req);
}
/* Reset bucket and prefix tables */
@@ -820,50 +811,6 @@ bgp_handle_graceful_restart(struct bgp_proto *p)
tm_start(p->gr_timer, p->conn->remote_caps->gr_time S);
}
-static void
-bgp_graceful_restart_feed_done(struct rt_export_request *req)
-{
- req->hook = NULL;
-}
-
-static void
-bgp_graceful_restart_feed_dump_req(struct rt_export_request *req)
-{
- struct bgp_channel *c = SKIP_BACK(struct bgp_channel, stale_feed, req);
- debug(" BGP-GR %s.%s export request %p\n", c->c.proto->name, c->c.name, req);
-}
-
-static void
-bgp_graceful_restart_feed_log_state_change(struct rt_export_request *req, u8 state)
-{
- struct bgp_channel *c = SKIP_BACK(struct bgp_channel, stale_feed, req);
- struct bgp_proto *p = (void *) c->c.proto;
- BGP_TRACE(D_EVENTS, "Long-lived graceful restart export state changed to %s", rt_export_state_name(state));
-
- if (state == TES_READY)
- rt_stop_export(req, bgp_graceful_restart_feed_done);
-}
-
-static void
-bgp_graceful_restart_drop_export(struct rt_export_request *req UNUSED, const net_addr *n UNUSED, struct rt_pending_export *rpe UNUSED)
-{ /* Nothing to do */ }
-
-static void
-bgp_graceful_restart_feed(struct bgp_channel *c)
-{
- c->stale_feed = (struct rt_export_request) {
- .name = "BGP-GR",
- .trace_routes = c->c.debug | c->c.proto->debug,
- .dump_req = bgp_graceful_restart_feed_dump_req,
- .log_state_change = bgp_graceful_restart_feed_log_state_change,
- .export_bulk = bgp_rte_modify_stale,
- .export_one = bgp_graceful_restart_drop_export,
- };
-
- rt_request_export(c->c.table, &c->stale_feed);
-}
-
-
/**
* bgp_graceful_restart_done - finish active BGP graceful restart
* @c: BGP channel
@@ -886,11 +833,8 @@ bgp_graceful_restart_done(struct bgp_channel *c)
if (!p->gr_active_num)
BGP_TRACE(D_EVENTS, "Neighbor graceful restart done");
- if (c->stale_feed.hook)
- rt_stop_export(&c->stale_feed, bgp_graceful_restart_feed_done);
-
tm_stop(c->stale_timer);
- channel_refresh_end_reload(&c->c);
+ rt_refresh_end(c->c.table, &c->c.in_req);
}
/**
@@ -932,7 +876,7 @@ bgp_graceful_restart_timeout(timer *t)
/* Channel is in GR, and supports LLGR -> start LLGR */
c->gr_active = BGP_GRS_LLGR;
tm_start(c->stale_timer, c->stale_time S);
- bgp_graceful_restart_feed(c);
+ rt_modify_stale(c->c.table, &c->c.in_req);
}
}
else
@@ -970,7 +914,10 @@ bgp_refresh_begin(struct bgp_channel *c)
{ log(L_WARN "%s: BEGIN-OF-RR received before END-OF-RIB, ignoring", p->p.name); return; }
c->load_state = BFS_REFRESHING;
- channel_refresh_begin(&c->c);
+ rt_refresh_begin(c->c.table, &c->c.in_req);
+
+ if (c->c.in_table)
+ rt_refresh_begin(c->c.in_table, &c->c.in_req);
}
/**
@@ -991,7 +938,10 @@ bgp_refresh_end(struct bgp_channel *c)
{ log(L_WARN "%s: END-OF-RR received without prior BEGIN-OF-RR, ignoring", p->p.name); return; }
c->load_state = BFS_NONE;
- channel_refresh_end_reload(&c->c);
+ rt_refresh_end(c->c.table, &c->c.in_req);
+
+ if (c->c.in_table)
+ rt_prune_sync(c->c.in_table, 0);
}
@@ -1458,9 +1408,12 @@ bgp_reload_routes(struct channel *C)
struct bgp_proto *p = (void *) C->proto;
struct bgp_channel *c = (void *) C;
- ASSERT(p->conn && (p->route_refresh));
+ ASSERT(p->conn && (p->route_refresh || c->c.in_table));
- bgp_schedule_packet(p->conn, c, PKT_ROUTE_REFRESH);
+ if (c->c.in_table)
+ channel_schedule_reload(C);
+ else
+ bgp_schedule_packet(p->conn, c, PKT_ROUTE_REFRESH);
}
static void
@@ -1740,6 +1693,7 @@ bgp_init(struct proto_config *CF)
P->rte_better = bgp_rte_better;
P->rte_mergable = bgp_rte_mergable;
P->rte_recalculate = cf->deterministic_med ? bgp_rte_recalculate : NULL;
+ P->rte_modify = bgp_rte_modify_stale;
P->rte_igp_metric = bgp_rte_igp_metric;
p->cf = cf;
@@ -1802,7 +1756,7 @@ bgp_channel_start(struct channel *C)
bgp_init_prefix_table(c);
if (c->cf->import_table)
- channel_setup_in_table(C, 0);
+ channel_setup_in_table(C);
if (c->cf->export_table)
channel_setup_out_table(C);