diff options
author | Fredi Raspall <fredi@voltanet.io> | 2018-04-26 10:56:19 +0200 |
---|---|---|
committer | Fredi Raspall <fredi@voltanet.io> | 2018-05-01 21:43:10 +0200 |
commit | 5dffb0e9aaafd7543ae22c48f26d3ca9efd77b66 (patch) | |
tree | 347b32ed33d5b39ba1d27833e886e45ad9037fa8 | |
parent | zebra: fix broken label manager proxy mode. (diff) | |
download | frr-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.c | 41 | ||||
-rw-r--r-- | zebra/zapi_msg.c | 51 |
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: |