From 0c5e7be5b3702a4e1e1320c99786956a8e4d4e35 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 11 Oct 2017 08:58:02 -0400 Subject: [PATCH] zebra: Add a function handler for zserv commands The zserv command handlers make an already long function even longer. Isolate this code so that we can rearrange the zebra_client_read function. Signed-off-by: Donald Sharp --- zebra/zserv.c | 238 ++++++++++++++++++++++++++------------------------ 1 file changed, 123 insertions(+), 115 deletions(-) diff --git a/zebra/zserv.c b/zebra/zserv.c index b76c9a9a17..cb83d32a1f 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -2228,122 +2228,11 @@ static int zread_interface_set_master(struct zserv *client, return 1; } -/* Handler of zebra service request. */ -static int zebra_client_read(struct thread *thread) +static inline void zserv_handle_commands(struct zserv *client, + uint16_t command, + uint16_t length, + struct zebra_vrf *zvrf) { - int sock; - struct zserv *client; - size_t already; - uint16_t length, command; - uint8_t marker, version; - vrf_id_t vrf_id; - struct zebra_vrf *zvrf; - - /* Get thread data. Reset reading thread because I'm running. */ - sock = THREAD_FD(thread); - client = THREAD_ARG(thread); - client->t_read = NULL; - - if (client->t_suicide) { - zebra_client_close(client); - return -1; - } - - /* Read length and command (if we don't have it already). */ - if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE) { - ssize_t nbyte; - if (((nbyte = stream_read_try(client->ibuf, sock, - ZEBRA_HEADER_SIZE - already)) - == 0) - || (nbyte == -1)) { - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug("connection closed socket [%d]", - sock); - zebra_client_close(client); - return -1; - } - if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) { - /* Try again later. */ - zebra_event(ZEBRA_READ, sock, client); - return 0; - } - already = ZEBRA_HEADER_SIZE; - } - - /* Reset to read from the beginning of the incoming packet. */ - stream_set_getp(client->ibuf, 0); - - /* Fetch header values */ - length = stream_getw(client->ibuf); - marker = stream_getc(client->ibuf); - version = stream_getc(client->ibuf); - vrf_id = stream_getw(client->ibuf); - command = stream_getw(client->ibuf); - - if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) { - zlog_err( - "%s: socket %d version mismatch, marker %d, version %d", - __func__, sock, marker, version); - zebra_client_close(client); - return -1; - } - if (length < ZEBRA_HEADER_SIZE) { - zlog_warn( - "%s: socket %d message length %u is less than header size %d", - __func__, sock, length, ZEBRA_HEADER_SIZE); - zebra_client_close(client); - return -1; - } - if (length > STREAM_SIZE(client->ibuf)) { - zlog_warn( - "%s: socket %d message length %u exceeds buffer size %lu", - __func__, sock, length, - (u_long)STREAM_SIZE(client->ibuf)); - zebra_client_close(client); - return -1; - } - - /* Read rest of data. */ - if (already < length) { - ssize_t nbyte; - if (((nbyte = stream_read_try(client->ibuf, sock, - length - already)) - == 0) - || (nbyte == -1)) { - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug( - "connection closed [%d] when reading zebra data", - sock); - zebra_client_close(client); - return -1; - } - if (nbyte != (ssize_t)(length - already)) { - /* Try again later. */ - zebra_event(ZEBRA_READ, sock, client); - return 0; - } - } - - length -= ZEBRA_HEADER_SIZE; - - /* Debug packet information. */ - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug("zebra message comes from socket [%d]", sock); - - if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) - zlog_debug("zebra message received [%s] %d in VRF %u", - zserv_command_string(command), length, vrf_id); - - client->last_read_time = monotime(NULL); - client->last_read_cmd = command; - - zvrf = zebra_vrf_lookup_by_id(vrf_id); - if (!zvrf) { - if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) - zlog_debug("zebra received unknown VRF[%u]", vrf_id); - goto zclient_read_out; - } - switch (command) { case ZEBRA_ROUTER_ID_ADD: zread_router_id_add(client, length, zvrf); @@ -2485,6 +2374,125 @@ static int zebra_client_read(struct thread *thread) zlog_info("Zebra received unknown command %d", command); break; } +} + +/* Handler of zebra service request. */ +static int zebra_client_read(struct thread *thread) +{ + int sock; + struct zserv *client; + size_t already; + uint16_t length, command; + uint8_t marker, version; + vrf_id_t vrf_id; + struct zebra_vrf *zvrf; + + /* Get thread data. Reset reading thread because I'm running. */ + sock = THREAD_FD(thread); + client = THREAD_ARG(thread); + client->t_read = NULL; + + if (client->t_suicide) { + zebra_client_close(client); + return -1; + } + + /* Read length and command (if we don't have it already). */ + if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE) { + ssize_t nbyte; + if (((nbyte = stream_read_try(client->ibuf, sock, + ZEBRA_HEADER_SIZE - already)) + == 0) + || (nbyte == -1)) { + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug("connection closed socket [%d]", + sock); + zebra_client_close(client); + return -1; + } + if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) { + /* Try again later. */ + zebra_event(ZEBRA_READ, sock, client); + return 0; + } + already = ZEBRA_HEADER_SIZE; + } + + /* Reset to read from the beginning of the incoming packet. */ + stream_set_getp(client->ibuf, 0); + + /* Fetch header values */ + length = stream_getw(client->ibuf); + marker = stream_getc(client->ibuf); + version = stream_getc(client->ibuf); + vrf_id = stream_getw(client->ibuf); + command = stream_getw(client->ibuf); + + if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) { + zlog_err( + "%s: socket %d version mismatch, marker %d, version %d", + __func__, sock, marker, version); + zebra_client_close(client); + return -1; + } + if (length < ZEBRA_HEADER_SIZE) { + zlog_warn( + "%s: socket %d message length %u is less than header size %d", + __func__, sock, length, ZEBRA_HEADER_SIZE); + zebra_client_close(client); + return -1; + } + if (length > STREAM_SIZE(client->ibuf)) { + zlog_warn( + "%s: socket %d message length %u exceeds buffer size %lu", + __func__, sock, length, + (u_long)STREAM_SIZE(client->ibuf)); + zebra_client_close(client); + return -1; + } + + /* Read rest of data. */ + if (already < length) { + ssize_t nbyte; + if (((nbyte = stream_read_try(client->ibuf, sock, + length - already)) + == 0) + || (nbyte == -1)) { + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug( + "connection closed [%d] when reading zebra data", + sock); + zebra_client_close(client); + return -1; + } + if (nbyte != (ssize_t)(length - already)) { + /* Try again later. */ + zebra_event(ZEBRA_READ, sock, client); + return 0; + } + } + + length -= ZEBRA_HEADER_SIZE; + + /* Debug packet information. */ + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug("zebra message comes from socket [%d]", sock); + + if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) + zlog_debug("zebra message received [%s] %d in VRF %u", + zserv_command_string(command), length, vrf_id); + + client->last_read_time = monotime(NULL); + client->last_read_cmd = command; + + zvrf = zebra_vrf_lookup_by_id(vrf_id); + if (!zvrf) { + if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) + zlog_debug("zebra received unknown VRF[%u]", vrf_id); + goto zclient_read_out; + } + + zserv_handle_commands(client, command, length, zvrf); if (client->t_suicide) { /* No need to wait for thread callback, just kill immediately. -- 2.39.5