]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: add API to allocate a range of table identifiers
authorPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 5 Mar 2018 17:09:57 +0000 (18:09 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Thu, 29 Mar 2018 07:20:01 +0000 (09:20 +0200)
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 <philippe.guibert@6wind.com>
bgpd/bgp_zebra.c
bgpd/bgp_zebra.h
bgpd/bgpd.c
lib/zebra.h
zebra/zserv.c

index 77416e3cfd47b080f0ff9cbf4995513e5606116f..269dcc7cb67b00d5c7384173584518d0e517f59e 100644 (file)
@@ -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)
index 68c495cf8b3fed67f79987509e966ef07549bfc6..7263317b6f5a07aa3941447ef6d407b80258118d 100644 (file)
 #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);
index 515d90e04934fe4e6066cc9d5aeddd9a334fd3a1..97f0ffcf2c54706f2a2ffb755b371dd2319030ee 100644 (file)
@@ -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;
 }
 
index ec530397be8cdd3ce4b422960ef9c76f19642dac..3887602231a4a1252e25588f2914ec29c732d655 100644 (file)
@@ -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;
 
 /*
index 76e5ea2f08a3b258682733b7e0b02c49c4b4e7d4..645deac277bed6d7c9ae520600105de425ff5617 100644 (file)
@@ -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;