summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFredi Raspall <fredi@voltanet.io>2018-04-26 10:56:19 +0200
committerFredi Raspall <fredi@voltanet.io>2018-05-01 21:43:10 +0200
commit5dffb0e9aaafd7543ae22c48f26d3ca9efd77b66 (patch)
tree347b32ed33d5b39ba1d27833e886e45ad9037fa8
parentzebra: fix broken label manager proxy mode. (diff)
downloadfrr-5dffb0e9aaafd7543ae22c48f26d3ca9efd77b66.tar.xz
frr-5dffb0e9aaafd7543ae22c48f26d3ca9efd77b66.zip
zebra, lib: Add client proto & instance in zserv
Add client proto and instance number in all msg (request and responses) to/form a label manager. This is required for a label manager acting as 'proxy' (i.e. relaying messages towards another label manager) to correctly deliver responses to the requesting clients. Signed-off-by: Fredi Raspall <fredi@voltanet.io>
-rw-r--r--lib/zclient.c41
-rw-r--r--zebra/zapi_msg.c51
2 files changed, 87 insertions, 5 deletions
diff --git a/lib/zclient.c b/lib/zclient.c
index dc27cbef7..8af702aaf 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -2079,8 +2079,21 @@ int lm_label_manager_connect(struct zclient *zclient)
!= 0)
return -1;
- /* result */
s = zclient->ibuf;
+
+ /* read instance and proto */
+ uint8_t proto = stream_getc(s);
+ uint16_t instance = stream_getw(s);
+
+ /* sanity */
+ if (proto != zclient->redist_default)
+ zlog_err("Wrong proto (%u) in lm_connect response. Should be %u",
+ proto, zclient->redist_default);
+ if (instance != zclient->instance)
+ zlog_err("Wrong instId (%u) in lm_connect response Should be %u",
+ instance, zclient->instance);
+
+ /* result code */
result = stream_getc(s);
if (zclient_debug)
zlog_debug(
@@ -2115,6 +2128,10 @@ int zclient_send_get_label_chunk(
stream_reset(s);
zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
+ /* proto */
+ stream_putc(s, zclient->redist_default);
+ /* instance */
+ stream_putw(s, zclient->instance);
stream_putc(s, keep);
stream_putl(s, chunk_size);
@@ -2154,6 +2171,10 @@ int lm_get_label_chunk(struct zclient *zclient, uint8_t keep,
s = zclient->obuf;
stream_reset(s);
zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
+ /* proto */
+ stream_putc(s, zclient->redist_default);
+ /* instance */
+ stream_putw(s, zclient->instance);
/* keep */
stream_putc(s, keep);
/* chunk size */
@@ -2182,7 +2203,21 @@ int lm_get_label_chunk(struct zclient *zclient, uint8_t keep,
if (zclient_read_sync_response(zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
return -1;
+ /* parse response */
s = zclient->ibuf;
+
+ /* read proto and instance */
+ uint8_t proto = stream_getc(s);
+ uint16_t instance = stream_getw(s);
+
+ /* sanities */
+ if (proto != zclient->redist_default)
+ zlog_err("Wrong proto (%u) in get chunk response. Should be %u",
+ proto, zclient->redist_default);
+ if (instance != zclient->instance)
+ zlog_err("Wrong instId (%u) in get chunk response Should be %u",
+ instance, zclient->instance);
+
/* keep */
response_keep = stream_getc(s);
/* start and end labels */
@@ -2235,6 +2270,10 @@ int lm_release_label_chunk(struct zclient *zclient, uint32_t start,
stream_reset(s);
zclient_create_header(s, ZEBRA_RELEASE_LABEL_CHUNK, VRF_DEFAULT);
+ /* proto */
+ stream_putc(s, zclient->redist_default);
+ /* instance */
+ stream_putw(s, zclient->instance);
/* start */
stream_putl(s, start);
/* end */
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 9353d7133..24f1748e2 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -887,6 +887,10 @@ static int zsend_assign_label_chunk_response(struct zserv *client,
zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, vrf_id);
if (lmc) {
+ /* proto */
+ stream_putc(s, lmc->proto);
+ /* instance */
+ stream_putw(s, lmc->instance);
/* keep */
stream_putc(s, lmc->keep);
/* start and end labels */
@@ -912,6 +916,12 @@ static int zsend_label_manager_connect_response(struct zserv *client,
zclient_create_header(s, ZEBRA_LABEL_MANAGER_CONNECT, vrf_id);
+ /* proto */
+ stream_putc(s, client->proto);
+
+ /* instance */
+ stream_putw(s, client->instance);
+
/* result */
stream_putc(s, result);
@@ -2398,6 +2408,23 @@ static void zread_label_manager_connect(struct zserv *client,
stream_failure:
return;
}
+static int msg_client_id_mismatch(const char *op, struct zserv *client,
+ uint8_t proto, unsigned int instance)
+{
+ if (proto != client->proto) {
+ zlog_err("%s: msg vs client proto mismatch, client=%u msg=%u",
+ op, client->proto, proto);
+ return 1;
+ }
+
+ if (instance != client->instance) {
+ zlog_err("%s: msg vs client instance mismatch, client=%u msg=%u",
+ op, client->instance, instance);
+ return 1;
+ }
+
+ return 0;
+}
static void zread_get_label_chunk(struct zserv *client, struct stream *msg,
vrf_id_t vrf_id)
@@ -2406,21 +2433,29 @@ static void zread_get_label_chunk(struct zserv *client, struct stream *msg,
uint8_t keep;
uint32_t size;
struct label_manager_chunk *lmc;
+ uint8_t proto;
+ unsigned short instance;
/* Get input stream. */
s = msg;
/* Get data. */
+ STREAM_GETC(s, proto);
+ STREAM_GETW(s, instance);
STREAM_GETC(s, keep);
STREAM_GETL(s, size);
+ /* detect client vs message (proto,instance) mismatch */
+ if (msg_client_id_mismatch("Get-label-chunk", client, proto, instance))
+ return;
+
lmc = assign_label_chunk(client->proto, client->instance, keep, size);
if (!lmc)
- zlog_err("%s: Unable to assign Label Chunk of size %u",
- __func__, size);
+ zlog_err("Unable to assign Label Chunk of size %u to %s instance %u",
+ size, zebra_route_string(client->proto), client->instance);
else
- zlog_debug("Assigned Label Chunk %u - %u to %u", lmc->start,
- lmc->end, keep);
+ zlog_debug("Assigned Label Chunk %u - %u to %s instance %u", lmc->start,
+ lmc->end, zebra_route_string(client->proto), client->instance);
/* send response back */
zsend_assign_label_chunk_response(client, vrf_id, lmc);
@@ -2432,14 +2467,22 @@ static void zread_release_label_chunk(struct zserv *client, struct stream *msg)
{
struct stream *s;
uint32_t start, end;
+ uint8_t proto;
+ unsigned short instance;
/* Get input stream. */
s = msg;
/* Get data. */
+ STREAM_GETC(s, proto);
+ STREAM_GETW(s, instance);
STREAM_GETL(s, start);
STREAM_GETL(s, end);
+ /* detect client vs message (proto,instance) mismatch */
+ if (msg_client_id_mismatch("Release-label-chunk", client, proto, instance))
+ return;
+
release_label_chunk(client->proto, client->instance, start, end);
stream_failure: