lib, zebra: handle failure in get chunk

when requesting a specific label chunk (e.g. for the SRGB),
it might happen that we cannot get what we want. In this
event, we must be prepared to receive a response with no
label chunk. Without this fix, if the remote label manager
was not able to alloate the chunk we requested, we would
hang indefinitely trying to read data from the stream which
was not there.

Signed-off-by: Emanuele Di Pascale <emanuele@voltanet.io>
This commit is contained in:
Emanuele Di Pascale 2019-06-27 10:59:22 +02:00
parent 0e3b6a926a
commit f004f7c3ce
2 changed files with 16 additions and 6 deletions

View File

@ -2107,6 +2107,15 @@ int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, uint32_t base,
"Wrong instId (%u) in get chunk response Should be %u",
instance, zclient->instance);
/* if we requested a specific chunk and it could not be allocated, the
* response message will end here
*/
if (!STREAM_READABLE(s)) {
zlog_info("Unable to assign Label Chunk to %s instance %u",
zebra_route_string(proto), instance);
return -1;
}
/* keep */
response_keep = stream_getc(s);
/* start and end labels */

View File

@ -929,19 +929,20 @@ int zsend_pw_update(struct zserv *client, struct zebra_pw *pw)
/* Send response to a get label chunk request to client */
static int zsend_assign_label_chunk_response(struct zserv *client,
vrf_id_t vrf_id,
vrf_id_t vrf_id, uint8_t proto,
uint16_t instance,
struct label_manager_chunk *lmc)
{
int ret;
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, vrf_id);
/* proto */
stream_putc(s, proto);
/* instance */
stream_putw(s, instance);
if (lmc) {
/* proto */
stream_putc(s, lmc->proto);
/* instance */
stream_putw(s, lmc->instance);
/* keep */
stream_putc(s, lmc->keep);
/* start and end labels */
@ -1953,7 +1954,7 @@ static void zread_get_label_chunk(struct zserv *client, struct stream *msg,
lmc->start, lmc->end,
zebra_route_string(proto), instance);
/* send response back */
zsend_assign_label_chunk_response(client, vrf_id, lmc);
zsend_assign_label_chunk_response(client, vrf_id, proto, instance, lmc);
stream_failure:
return;