From: Philippe Guibert Date: Mon, 5 Mar 2018 17:09:57 +0000 (+0100) Subject: bgpd: add API to allocate a range of table identifiers X-Git-Tag: frr-5.0-dev~111^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=b98f77282b83f519f2134661d43b845fd69d5f60;p=matthieu%2Ffrr.git bgpd: add API to allocate a range of table identifiers In BGP, doing policy-routing requires to use table identifiers. Flowspec protocol will need to have that. 1 API from bgp zebra has been done to get the table chunk. Internally, onec flowspec is enabled, the BGP engine will try to connect smoothly to the table manager. If zebra is not connected, it will try to connect 10 seconds later. If zebra is connected, and it is success, then a polling mechanism each 60 seconds is put in place. All the internal mechanism has no impact on the BGP process. Signed-off-by: Philippe Guibert --- diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 77416e3cfd..269dcc7cb6 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -970,6 +970,64 @@ static int bgp_table_map_apply(struct route_map *map, struct prefix *p, return 0; } +static struct thread *bgp_tm_thread_connect; +static bool bgp_tm_status_connected; + +static int bgp_zebra_tm_connect(struct thread *t) +{ + struct zclient *zclient; + int delay = 10, ret = 0; + + zclient = THREAD_ARG(t); + if (bgp_tm_status_connected && zclient->sock > 0) + delay = 60; + else { + bgp_tm_status_connected = false; + ret = tm_table_manager_connect(zclient); + } + if (ret < 0) { + zlog_warn("Error connecting to table manager!"); + bgp_tm_status_connected = false; + } else { + if (!bgp_tm_status_connected) + zlog_debug("Connecting to table manager. Success"); + bgp_tm_status_connected = true; + } + thread_add_timer(bm->master, bgp_zebra_tm_connect, zclient, delay, + &bgp_tm_thread_connect); + return 0; +} + +void bgp_zebra_init_tm_connect(void) +{ + int delay = 1; + + /* if already set, do nothing + */ + if (bgp_tm_thread_connect != NULL) + return; + bgp_tm_status_connected = false; + thread_add_timer(bm->master, bgp_zebra_tm_connect, zclient, delay, + &bgp_tm_thread_connect); +} + +int bgp_zebra_get_table_range(uint32_t chunk_size, + uint32_t *start, uint32_t *end) +{ + int ret; + + if (!bgp_tm_status_connected) + return -1; + ret = tm_get_table_chunk(zclient, chunk_size, start, end); + if (ret < 0) { + zlog_err("BGP: Error getting table chunk %u", chunk_size); + return -1; + } + zlog_info("BGP: Table Manager returns range from chunk %u is [%u %u]", + chunk_size, *start, *end); + return 0; +} + void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, struct bgp_info *info, struct bgp *bgp, afi_t afi, safi_t safi) diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h index 68c495cf8b..7263317b6f 100644 --- a/bgpd/bgp_zebra.h +++ b/bgpd/bgp_zebra.h @@ -24,7 +24,10 @@ #include "vxlan.h" extern void bgp_zebra_init(struct thread_master *master); +extern void bgp_zebra_init_tm_connect(void); extern void bgp_zebra_destroy(void); +extern int bgp_zebra_get_table_range(uint32_t chunk_size, + uint32_t *start, uint32_t *end); extern int bgp_if_update_all(void); extern void bgp_config_write_maxpaths(struct vty *, struct bgp *, afi_t, safi_t); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 515d90e049..97f0ffcf2c 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1973,6 +1973,10 @@ int peer_activate(struct peer *peer, afi_t afi, safi_t safi) bgp_recalculate_afi_safi_bestpaths(bgp, afi, SAFI_UNICAST); } + if (safi == SAFI_FLOWSPEC) { + /* connect to table manager */ + bgp_zebra_init_tm_connect(); + } return ret; } diff --git a/lib/zebra.h b/lib/zebra.h index ec530397be..3887602231 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -433,7 +433,8 @@ typedef enum { SAFI_ENCAP = 4, SAFI_EVPN = 5, SAFI_LABELED_UNICAST = 6, - SAFI_MAX = 7 + SAFI_FLOWSPEC = 7, + SAFI_MAX = 8 } safi_t; /* diff --git a/zebra/zserv.c b/zebra/zserv.c index 76e5ea2f08..645deac277 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -2203,7 +2203,8 @@ static int zsend_table_manager_connect_response(struct zserv *client, } /* Send response to a table manager connect request to client */ -static void zread_table_manager_connect(struct zserv *client, struct stream *msg, +static void zread_table_manager_connect(struct zserv *client, + struct stream *msg, vrf_id_t vrf_id) { struct stream *s;