aboutsummaryrefslogtreecommitdiffstats
path: root/proto
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2018-09-27 22:57:55 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2018-12-12 14:46:24 +0100
commit682d3f7de0905ca2e853844734cce7ff65f7d77d (patch)
treee84ab31b4c5b7e99a283cf4c2faf2523dd5d884c /proto
parent01fd00f5ed9298ab5829403cd7a8a9ba22bcc96a (diff)
downloadbird-682d3f7de0905ca2e853844734cce7ff65f7d77d.tar.gz
BGP: implement Adj-RIB-In
The patch implements optional internal import table to a channel and hooks it to BGP so it can be used as Adj-RIB-In. When enabled, all received (pre-filtered) routes are stored there and import filters can be re-evaluated without explicit route refresh. An import table can be examined using e.g. 'show route import table bgp1.ipv4'.
Diffstat (limited to 'proto')
-rw-r--r--proto/bgp/bgp.c18
-rw-r--r--proto/bgp/bgp.h1
-rw-r--r--proto/bgp/config.Y3
-rw-r--r--proto/bgp/packets.c4
4 files changed, 20 insertions, 6 deletions
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index e20097ae..b2dbd780 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -545,7 +545,7 @@ bgp_conn_enter_established_state(struct bgp_conn *conn)
int active = loc->ready && rem->ready;
c->c.disabled = !active;
- c->c.reloadable = p->route_refresh;
+ c->c.reloadable = p->route_refresh || c->cf->import_table;
c->index = active ? num++ : 0;
@@ -838,6 +838,9 @@ bgp_refresh_begin(struct bgp_channel *c)
c->load_state = BFS_REFRESHING;
rt_refresh_begin(c->c.table, &c->c);
+
+ if (c->c.in_table)
+ rt_refresh_begin(c->c.in_table, &c->c);
}
/**
@@ -859,6 +862,9 @@ bgp_refresh_end(struct bgp_channel *c)
c->load_state = BFS_NONE;
rt_refresh_end(c->c.table, &c->c);
+
+ if (c->c.in_table)
+ rt_prune_sync(c->c.in_table, 0);
}
@@ -1296,9 +1302,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
@@ -1598,6 +1607,9 @@ bgp_channel_start(struct channel *C)
bgp_init_bucket_table(c);
bgp_init_prefix_table(c);
+ if (c->cf->import_table)
+ channel_setup_in_table(C);
+
c->stale_timer = tm_new_init(c->pool, bgp_long_lived_stale_timeout, c, 0, 0);
c->next_hop_addr = c->cf->next_hop_addr;
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index e1ff013a..76b835fa 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -144,6 +144,7 @@ struct bgp_channel_config {
uint llgr_time; /* Long-lived graceful restart stale time */
u8 ext_next_hop; /* Allow both IPv4 and IPv6 next hops */
u8 add_path; /* Use ADD-PATH extension [RFC 7911] */
+ u8 import_table; /* Use c.in_table as Adj-RIB-In */
uint rest[0]; /* Remaining items are reconfigured separately */
struct rtable_config *igp_table_ip4; /* Table for recursive IPv4 next hop lookups */
diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y
index 120b1e88..f155eee2 100644
--- a/proto/bgp/config.Y
+++ b/proto/bgp/config.Y
@@ -29,7 +29,7 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE,
SECURITY, DETERMINISTIC, SECONDARY, ALLOW, BFD, ADD, PATHS, RX, TX,
GRACEFUL, RESTART, AWARE, CHECK, LINK, PORT, EXTENDED, MESSAGES, SETKEY,
STRICT, BIND, CONFEDERATION, MEMBER, MULTICAST, FLOW4, FLOW6, LONG,
- LIVED, STALE)
+ LIVED, STALE, IMPORT)
%type <i32> bgp_afi
@@ -229,6 +229,7 @@ bgp_channel_item:
| ADD PATHS RX { BGP_CC->add_path = BGP_ADD_PATH_RX; }
| ADD PATHS TX { BGP_CC->add_path = BGP_ADD_PATH_TX; }
| ADD PATHS bool { BGP_CC->add_path = $3 ? BGP_ADD_PATH_FULL : 0; }
+ | IMPORT TABLE bool { BGP_CC->import_table = $3; }
| IGP TABLE rtable {
if (BGP_CC->desc->no_igp)
cf_error("IGP table not allowed here");
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index 3be48c00..c2261870 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -1159,7 +1159,7 @@ bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0)
if (!a0)
{
/* Route withdraw */
- rte_update2(&s->channel->c, n, NULL, s->last_src);
+ rte_update3(&s->channel->c, n, NULL, s->last_src);
return;
}
@@ -1180,7 +1180,7 @@ bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0)
e->pflags = 0;
e->u.bgp.suppressed = 0;
e->u.bgp.stale = -1;
- rte_update2(&s->channel->c, n, e, s->last_src);
+ rte_update3(&s->channel->c, n, e, s->last_src);
}
static void