]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: add framework for allocating routing table identifier IDs
authorPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 5 Mar 2018 16:57:29 +0000 (17:57 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Thu, 29 Mar 2018 07:19:52 +0000 (09:19 +0200)
The library changes add 3 new messages to exchange between daemons and
ZEBRA.
- ZEBRA_TABLE_MANAGER_CONNECT,
- ZEBRA_GET_TABLE_CHUNK,
- ZEBRA_RELEASE_TABLE_CHUNK,
the need is that routing tables identifier are shared by various
services. For the current case, policy routing enhancements are planned
to be used in FRR. Poliy routing relies on routing tables identifiers
from kernels. It will be mainly used by the future policy based routing
daemon, but not only. In the flowspec case, the BGP will need also to
inject policy routing information into specific routing tables.
For that, the proposal is made to let zebra give the appropriate range
that is needed for all daemons.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
lib/log.c
lib/zclient.c
lib/zclient.h

index 35298f1fa3f706328b0e4d4000444bd8aae57985..f5aff756dde5e2587986c87afa35e3ff5052cb97 100644 (file)
--- a/lib/log.c
+++ b/lib/log.c
@@ -965,6 +965,9 @@ static const struct zebra_desc_table command_types[] = {
        DESC_ENTRY(ZEBRA_RULE_ADD),
        DESC_ENTRY(ZEBRA_RULE_DELETE),
        DESC_ENTRY(ZEBRA_RULE_NOTIFY_OWNER),
+       DESC_ENTRY(ZEBRA_TABLE_MANAGER_CONNECT),
+       DESC_ENTRY(ZEBRA_GET_TABLE_CHUNK),
+       DESC_ENTRY(ZEBRA_RELEASE_TABLE_CHUNK),
 };
 #undef DESC_ENTRY
 
index 4659bce1b17082b44ae17ce066b524eb9a0e095d..7308beaaf25619ff0cca0acd8c528073a71fd1bc 100644 (file)
@@ -2123,6 +2123,168 @@ int lm_release_label_chunk(struct zclient *zclient, uint32_t start,
        return 0;
 }
 
+/**
+ * Connect to table manager in a syncronous way
+ *
+ * It first writes the request to zcient output buffer and then
+ * immediately reads the answer from the input buffer.
+ *
+ * @param zclient Zclient used to connect to table manager (zebra)
+ * @result Result of response
+ */
+int tm_table_manager_connect(struct zclient *zclient)
+{
+       int ret;
+       struct stream *s;
+       uint8_t result;
+
+       if (zclient_debug)
+               zlog_debug("Connecting to Table Manager");
+
+       if (zclient->sock < 0)
+               return -1;
+
+       /* send request */
+       s = zclient->obuf;
+       stream_reset(s);
+       zclient_create_header(s, ZEBRA_TABLE_MANAGER_CONNECT, VRF_DEFAULT);
+
+       /* proto */
+       stream_putc(s, zclient->redist_default);
+       /* instance */
+       stream_putw(s, zclient->instance);
+
+       /* Put length at the first point of the stream. */
+       stream_putw_at(s, 0, stream_get_endp(s));
+
+       ret = zclient_send_message(zclient);
+       if (ret < 0)
+               return -1;
+
+       if (zclient_debug)
+               zlog_debug("%s: Table manager connect request sent",
+                          __func__);
+
+       /* read response */
+       if (zclient_read_sync_response(zclient, ZEBRA_TABLE_MANAGER_CONNECT)
+           != 0)
+               return -1;
+
+       /* result */
+       s = zclient->ibuf;
+       STREAM_GETC(s, result);
+       if (zclient_debug)
+               zlog_debug(
+                       "%s: Table Manager connect response received, result %u",
+                       __func__, result);
+
+       return (int)result;
+stream_failure:
+       return 0;
+}
+
+/**
+ * Function to request a table chunk in a syncronous way
+ *
+ * It first writes the request to zclient output buffer and then
+ * immediately reads the answer from the input buffer.
+ *
+ * @param zclient Zclient used to connect to table manager (zebra)
+ * @param chunk_size Amount of table requested
+ * @param start to write first assigned chunk table RT ID to
+ * @param end To write last assigned chunk table RT ID to
+ * @result 0 on success, -1 otherwise
+ */
+int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size,
+                      uint32_t *start, uint32_t *end)
+{
+       int ret;
+       struct stream *s;
+
+       if (zclient_debug)
+               zlog_debug("Getting Table Chunk");
+
+       if (zclient->sock < 0)
+               return -1;
+
+       /* send request */
+       s = zclient->obuf;
+       stream_reset(s);
+       zclient_create_header(s, ZEBRA_GET_TABLE_CHUNK, VRF_DEFAULT);
+       /* chunk size */
+       stream_putl(s, chunk_size);
+       /* Put length at the first point of the stream. */
+       stream_putw_at(s, 0, stream_get_endp(s));
+
+       ret = writen(zclient->sock, s->data, stream_get_endp(s));
+       if (ret < 0) {
+               zlog_err("%s: can't write to zclient->sock", __func__);
+               close(zclient->sock);
+               zclient->sock = -1;
+               return -1;
+       }
+       if (ret == 0) {
+               zlog_err("%s: zclient->sock connection closed", __func__);
+               close(zclient->sock);
+               zclient->sock = -1;
+               return -1;
+       }
+       if (zclient_debug)
+               zlog_debug("%s: Table chunk request (%d bytes) sent", __func__,
+                          ret);
+
+       /* read response */
+       if (zclient_read_sync_response(zclient, ZEBRA_GET_TABLE_CHUNK) != 0)
+               return -1;
+
+       s = zclient->ibuf;
+       /* start and end table IDs */
+       STREAM_GETL(s, *start);
+       STREAM_GETL(s, *end);
+
+       if (zclient_debug)
+               zlog_debug("Table Chunk assign: %u - %u ", *start, *end);
+
+stream_failure:
+       return 0;
+}
+
+/**
+ * Function to release a table chunk
+ *
+ * @param zclient Zclient used to connect to table manager (zebra)
+ * @param start First label of table
+ * @param end Last label of chunk
+ * @result 0 on success, -1 otherwise
+ */
+int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
+                          uint32_t end)
+{
+       struct stream *s;
+
+       if (zclient_debug)
+               zlog_debug("Releasing Table Chunk");
+
+       if (zclient->sock < 0)
+               return -1;
+
+       /* send request */
+       s = zclient->obuf;
+       stream_reset(s);
+       zclient_create_header(s, ZEBRA_RELEASE_TABLE_CHUNK, VRF_DEFAULT);
+
+       /* start */
+       stream_putl(s, start);
+       /* end */
+       stream_putl(s, end);
+
+       /* Put length at the first point of the stream. */
+       stream_putw_at(s, 0, stream_get_endp(s));
+
+       return zclient_send_message(zclient);
+}
+
+
 int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw)
 {
        struct stream *s;
index b51c5184632e8cc203d99abfa5bee6c79df1ad04..04f2a5c17868bc5873f0e374c6146b93e1e65e39 100644 (file)
@@ -132,6 +132,9 @@ typedef enum {
        ZEBRA_RULE_ADD,
        ZEBRA_RULE_DELETE,
        ZEBRA_RULE_NOTIFY_OWNER,
+       ZEBRA_TABLE_MANAGER_CONNECT,
+       ZEBRA_GET_TABLE_CHUNK,
+       ZEBRA_RELEASE_TABLE_CHUNK,
 } zebra_message_types_t;
 
 struct redist_proto {
@@ -538,6 +541,12 @@ extern int lm_get_label_chunk(struct zclient *zclient, uint8_t keep,
                              uint32_t *end);
 extern int lm_release_label_chunk(struct zclient *zclient, uint32_t start,
                                  uint32_t end);
+extern int tm_table_manager_connect(struct zclient *zclient);
+extern int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size,
+                             uint32_t *start, uint32_t *end);
+extern int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
+                                 uint32_t end);
+
 extern int zebra_send_pw(struct zclient *zclient, int command,
                         struct zapi_pw *pw);
 extern void zebra_read_pw_status_update(int command, struct zclient *zclient,