diff --git a/zebra/label_manager.c b/zebra/label_manager.c index 6de94e63da..03cfa572db 100644 --- a/zebra/label_manager.c +++ b/zebra/label_manager.c @@ -38,297 +38,67 @@ #include "zebra/zebra_router.h" #include "zebra/label_manager.h" #include "zebra/zebra_errors.h" +#include "zebra/zapi_msg.h" #define CONNECTION_DELAY 5 struct label_manager lbl_mgr; -extern struct zebra_privs_t zserv_privs; - DEFINE_MGROUP(LBL_MGR, "Label Manager"); DEFINE_MTYPE_STATIC(LBL_MGR, LM_CHUNK, "Label Manager Chunk"); -/* In case this zebra daemon is not acting as label manager, - * it will be a proxy to relay messages to external label manager - * This zclient thus is to connect to it +/* define hooks for the basic API, so that it can be specialized or served + * externally */ -static struct stream *obuf; -static struct zclient *zclient; -bool lm_is_external; -static void delete_label_chunk(void *val) +DEFINE_HOOK(lm_client_connect, + (uint8_t proto, uint16_t instance, vrf_id_t vrf_id), + (proto, instance, vrf_id)); +DEFINE_HOOK(lm_client_disconnect, (uint8_t proto, uint16_t instance), + (proto, instance)); +DEFINE_HOOK(lm_get_chunk, + (struct label_manager_chunk * *lmc, uint8_t proto, + uint16_t instance, uint8_t keep, uint32_t size, uint32_t base, + vrf_id_t vrf_id), + (lmc, proto, instance, keep, size, base, vrf_id)); +DEFINE_HOOK(lm_release_chunk, + (uint8_t proto, uint16_t instance, uint32_t start, uint32_t end), + (proto, instance, start, end)); +DEFINE_HOOK(lm_cbs_inited, (), ()); + +/* define wrappers to be called in zapi_msg.c (as hooks must be called in + * source file where they were defined) + */ +void lm_client_connect_call(uint8_t proto, uint16_t instance, vrf_id_t vrf_id) +{ + hook_call(lm_client_connect, proto, instance, vrf_id); +} +void lm_get_chunk_call(struct label_manager_chunk **lmc, uint8_t proto, + uint16_t instance, uint8_t keep, uint32_t size, + uint32_t base, vrf_id_t vrf_id) +{ + hook_call(lm_get_chunk, lmc, proto, instance, keep, size, base, vrf_id); +} +void lm_release_chunk_call(uint8_t proto, uint16_t instance, uint32_t start, + uint32_t end) +{ + hook_call(lm_release_chunk, proto, instance, start, end); +} + +/* forward declarations of the static functions to be used for some hooks */ +static int label_manager_connect(uint8_t proto, uint16_t instance, + vrf_id_t vrf_id); +static int label_manager_disconnect(uint8_t proto, uint16_t instance); +static int label_manager_get_chunk(struct label_manager_chunk **lmc, + uint8_t proto, uint16_t instance, + uint8_t keep, uint32_t size, uint32_t base, + vrf_id_t vrf_id); + +void delete_label_chunk(void *val) { XFREE(MTYPE_LM_CHUNK, val); } -static int relay_response_back(void) -{ - int ret = 0; - struct stream *src, *dst; - uint16_t size = 0; - uint8_t marker; - uint8_t version; - vrf_id_t vrf_id; - uint16_t resp_cmd; - uint8_t proto; - const char *proto_str; - unsigned short instance; - struct zserv *zserv; - - /* sanity */ - if (!zclient || zclient->sock < 0) - return -1; - - /* input buffer with msg from label manager */ - src = zclient->ibuf; - - stream_reset(src); - - /* parse header */ - ret = zclient_read_header(src, zclient->sock, &size, &marker, &version, - &vrf_id, &resp_cmd); - if (ret < 0) { - if (errno != EAGAIN) - flog_err(EC_ZEBRA_LM_RESPONSE, - "Error reading Label Manager response: %s", - strerror(errno)); - return -1; - } - - /* do not relay a msg that has nothing to do with LM */ - switch (resp_cmd) { - case ZEBRA_LABEL_MANAGER_CONNECT: - case ZEBRA_LABEL_MANAGER_CONNECT_ASYNC: /* should not be seen */ - case ZEBRA_GET_LABEL_CHUNK: - case ZEBRA_RELEASE_LABEL_CHUNK: - break; - default: - zlog_debug("Not relaying '%s' response (size %d) from LM", - zserv_command_string(resp_cmd), size); - return -1; - } - - zlog_debug("Received '%s' response (size %d) from LM", - zserv_command_string(resp_cmd), size); - - if (size == 0) - return -1; - - /* Get the 'proto' field of the message */ - proto = stream_getc(src); - - /* Get the 'instance' field of the message */ - instance = stream_getw(src); - - proto_str = zebra_route_string(proto); - - /* lookup the client to relay the msg to */ - zserv = zserv_find_client(proto, instance); - if (!zserv) { - flog_err( - EC_ZEBRA_LM_NO_SUCH_CLIENT, - "Error relaying LM response: can't find client %s, instance %u", - proto_str, instance); - return -1; - } - zlog_debug("Found client to relay LM response to client %s instance %u", - proto_str, instance); - - /* copy msg into output buffer */ - dst = obuf; - stream_copy(dst, src); - - /* send response back */ - ret = writen(zserv->sock, dst->data, stream_get_endp(dst)); - if (ret <= 0) { - flog_err(EC_ZEBRA_LM_RELAY_FAILED, - "Error relaying LM response to %s instance %u: %s", - proto_str, instance, strerror(errno)); - return -1; - } - zlog_debug("Relayed LM response (%d bytes) to %s instance %u", ret, - proto_str, instance); - - return 0; -} - -static int lm_zclient_read(struct thread *t) -{ - int ret; - - zclient->t_read = NULL; - - /* read response and send it back */ - ret = relay_response_back(); - - /* re-arm read */ - thread_add_read(zclient->master, lm_zclient_read, NULL, - zclient->sock, &zclient->t_read); - return ret; -} - -static int reply_error(int cmd, struct zserv *zserv, vrf_id_t vrf_id) -{ - int ret; - struct stream *s; - - s = stream_new(ZEBRA_MAX_PACKET_SIZ); - - zclient_create_header(s, cmd, vrf_id); - - /* proto */ - stream_putc(s, zserv->proto); - /* instance */ - stream_putw(s, zserv->instance); - /* result */ - stream_putc(s, 1); - - /* Write packet size. */ - stream_putw_at(s, 0, stream_get_endp(s)); - - ret = writen(zserv->sock, s->data, stream_get_endp(s)); - - stream_free(s); - return ret; -} -/** - * Receive a request to get or release a label chunk and forward it to external - * label manager. - * - * It's called from zserv in case it's not an actual label manager, but just a - * proxy. - * - * @param cmd Type of request (connect, get or release) - * @param zserv - * @return 0 on success, -1 otherwise - */ -int zread_relay_label_manager_request(int cmd, struct zserv *zserv, - struct stream *msg, vrf_id_t vrf_id) -{ - struct stream *dst; - int ret = 0; - uint8_t proto; - const char *proto_str; - unsigned short instance; - - if (zclient->sock < 0) { - flog_err(EC_ZEBRA_LM_NO_SOCKET, - "Unable to relay LM request: no socket"); - reply_error(cmd, zserv, vrf_id); - return -1; - } - - /* peek msg to get proto and instance id. This zebra, which acts as - * a proxy needs to have such values for each client in order to - * relay responses back to it. - */ - - /* Get the 'proto' field of incoming msg */ - proto = stream_getc(msg); - - /* Get the 'instance' field of incoming msg */ - instance = stream_getw(msg); - - /* stringify proto */ - proto_str = zebra_route_string(proto); - - /* check & set client proto if unset */ - if (zserv->proto && zserv->proto != proto) { - flog_warn(EC_ZEBRAING_LM_PROTO_MISMATCH, - "Client proto(%u) != msg proto(%u)", zserv->proto, - proto); - return -1; - } - - /* check & set client instance if unset */ - if (zserv->instance && zserv->instance != instance) { - flog_err(EC_ZEBRA_LM_BAD_INSTANCE, - "Client instance(%u) != msg instance(%u)", - zserv->instance, instance); - return -1; - } - - /* recall proto and instance */ - zserv->instance = instance; - zserv->proto = proto; - - /* in case there's any incoming message enqueued, read and forward it */ - if (zserv->is_synchronous) - while (ret == 0) - ret = relay_response_back(); - - /* get the msg buffer used toward the 'master' Label Manager */ - dst = zclient->obuf; - - /* copy the message */ - stream_copy(dst, msg); - - /* Send request to external label manager */ - ret = writen(zclient->sock, dst->data, stream_get_endp(dst)); - if (ret <= 0) { - flog_err(EC_ZEBRA_LM_RELAY_FAILED, - "Error relaying LM request from %s instance %u: %s", - proto_str, instance, strerror(errno)); - reply_error(cmd, zserv, vrf_id); - return -1; - } - zlog_debug("Relayed LM request (%d bytes) from %s instance %u", ret, - proto_str, instance); - - - /* Release label chunk has no response */ - if (cmd == ZEBRA_RELEASE_LABEL_CHUNK) - return 0; - - /* make sure we listen to the response */ - if (!zclient->t_read) - thread_add_read(zclient->master, lm_zclient_read, NULL, - zclient->sock, &zclient->t_read); - - return 0; -} - -static int lm_zclient_connect(struct thread *t) -{ - zclient->t_connect = NULL; - - if (zclient->sock >= 0) - return 0; - - if (zclient_socket_connect(zclient) < 0) { - flog_err(EC_ZEBRA_LM_CLIENT_CONNECTION_FAILED, - "Error connecting synchronous zclient!"); - thread_add_timer(zrouter.master, lm_zclient_connect, zclient, - CONNECTION_DELAY, &zclient->t_connect); - return -1; - } - - /* make socket non-blocking */ - (void)set_nonblocking(zclient->sock); - - return 0; -} - -/** - * Function to initialize zclient in case this is not an actual - * label manager, but just a proxy to an external one. - * - * @param lm_zserv_path Path to zserv socket of external label manager - */ -static void lm_zclient_init(char *lm_zserv_path) -{ - if (lm_zserv_path) - frr_zclient_addr(&zclient_addr, &zclient_addr_len, - lm_zserv_path); - - /* Set default values. */ - zclient = zclient_new(zrouter.master, &zclient_options_default); - zclient->privs = &zserv_privs; - zclient->sock = -1; - zclient->t_connect = NULL; - lm_zclient_connect(NULL); -} - /** * Release label chunks from a client. * @@ -339,15 +109,16 @@ static void lm_zclient_init(char *lm_zserv_path) * @param instance Instance, to identify the owner * @return Number of chunks released */ -int release_daemon_label_chunks(struct zserv *client) +int release_daemon_label_chunks(uint8_t proto, unsigned short instance) { - uint8_t proto = client->proto; - uint16_t instance = client->instance; struct listnode *node; struct label_manager_chunk *lmc; int count = 0; int ret; + zlog_debug("%s: Releasing chunks for client proto %s, instance %d", + __func__, zebra_route_string(proto), instance); + for (ALL_LIST_ELEMENTS_RO(lbl_mgr.lc_list, node, lmc)) { if (lmc->proto == proto && lmc->instance == instance && lmc->keep == 0) { @@ -363,33 +134,51 @@ int release_daemon_label_chunks(struct zserv *client) return count; } +int lm_client_disconnect_cb(struct zserv *client) +{ + uint8_t proto = client->proto; + uint16_t instance = client->instance; + + hook_call(lm_client_disconnect, proto, instance); + return 0; +} + +void lm_hooks_register(void) +{ + hook_register(lm_client_connect, label_manager_connect); + hook_register(lm_client_disconnect, label_manager_disconnect); + hook_register(lm_get_chunk, label_manager_get_chunk); + hook_register(lm_release_chunk, release_label_chunk); +} +void lm_hooks_unregister(void) +{ + hook_unregister(lm_client_connect, label_manager_connect); + hook_unregister(lm_client_disconnect, label_manager_disconnect); + hook_unregister(lm_get_chunk, label_manager_get_chunk); + hook_unregister(lm_release_chunk, release_label_chunk); +} + /** * Init label manager (or proxy to an external one) */ -void label_manager_init(char *lm_zserv_path) +void label_manager_init(void) { - /* this is an actual label manager */ - if (!lm_zserv_path) { - zlog_debug("Initializing internal label manager"); - lm_is_external = false; - lbl_mgr.lc_list = list_new(); - lbl_mgr.lc_list->del = delete_label_chunk; - } else { /* it's acting just as a proxy */ - zlog_debug("Initializing external label manager at %s", - lm_zserv_path); - lm_is_external = true; - lm_zclient_init(lm_zserv_path); - } + lbl_mgr.lc_list = list_new(); + lbl_mgr.lc_list->del = delete_label_chunk; + hook_register(zserv_client_close, lm_client_disconnect_cb); - obuf = stream_new(ZEBRA_MAX_PACKET_SIZ); + /* register default hooks for the label manager actions */ + lm_hooks_register(); - hook_register(zserv_client_close, release_daemon_label_chunks); + /* notify any external module that we are done */ + hook_call(lm_cbs_inited); } /* alloc and fill a label chunk */ -static struct label_manager_chunk * -create_label_chunk(uint8_t proto, unsigned short instance, uint8_t keep, - uint32_t start, uint32_t end) +struct label_manager_chunk *create_label_chunk(uint8_t proto, + unsigned short instance, + uint8_t keep, uint32_t start, + uint32_t end) { /* alloc chunk, fill it and return it */ struct label_manager_chunk *lmc = @@ -405,7 +194,7 @@ create_label_chunk(uint8_t proto, unsigned short instance, uint8_t keep, } /* attempt to get a specific label chunk */ -struct label_manager_chunk * +static struct label_manager_chunk * assign_specific_label_chunk(uint8_t proto, unsigned short instance, uint8_t keep, uint32_t size, uint32_t base) { @@ -607,9 +396,59 @@ int release_label_chunk(uint8_t proto, unsigned short instance, uint32_t start, return ret; } +/* default functions to be called on hooks */ +static int label_manager_connect(uint8_t proto, uint16_t instance, + vrf_id_t vrf_id) +{ + /* + * Release previous labels of same protocol and instance. + * This is done in case it restarted from an unexpected shutdown. + */ + release_daemon_label_chunks(proto, instance); + return lm_client_connect_response(proto, instance, vrf_id, 0); +} +static int label_manager_disconnect(uint8_t proto, uint16_t instance) +{ + release_daemon_label_chunks(proto, instance); + return 0; +} +static int label_manager_get_chunk(struct label_manager_chunk **lmc, + uint8_t proto, uint16_t instance, + uint8_t keep, uint32_t size, uint32_t base, + vrf_id_t vrf_id) +{ + *lmc = assign_label_chunk(proto, instance, keep, size, base); + return lm_get_chunk_response(*lmc, proto, instance, vrf_id); +} + +/* Respond to a connect request */ +int lm_client_connect_response(uint8_t proto, uint16_t instance, + vrf_id_t vrf_id, uint8_t result) +{ + struct zserv *client = zserv_find_client(proto, instance); + if (!client) { + zlog_err("%s: could not find client for daemon %s instance %u", + __func__, zebra_route_string(proto), instance); + return 1; + } + return zsend_label_manager_connect_response(client, vrf_id, result); +} + +/* Respond to a get_chunk request */ +int lm_get_chunk_response(struct label_manager_chunk *lmc, uint8_t proto, + uint16_t instance, vrf_id_t vrf_id) +{ + struct zserv *client = zserv_find_client(proto, instance); + if (!client) { + zlog_err("%s: could not find client for daemon %s instance %u", + __func__, zebra_route_string(proto), instance); + return 1; + } + return zsend_assign_label_chunk_response(client, vrf_id, proto, + instance, lmc); +} void label_manager_close(void) { list_delete(&lbl_mgr.lc_list); - stream_free(obuf); } diff --git a/zebra/label_manager.h b/zebra/label_manager.h index f1b7d050cf..74e283e85e 100644 --- a/zebra/label_manager.h +++ b/zebra/label_manager.h @@ -28,6 +28,7 @@ #include "lib/linklist.h" #include "lib/thread.h" +#include "lib/hook.h" #include "zebra/zserv.h" @@ -57,6 +58,54 @@ struct label_manager_chunk { uint32_t end; /* Last label of the chunk */ }; +/* declare hooks for the basic API, so that it can be specialized or served + * externally. Also declare a hook when those functions have been registered, + * so that any external module wanting to replace those can react + */ + +DECLARE_HOOK(lm_client_connect, + (uint8_t proto, uint16_t instance, vrf_id_t vrf_id), + (proto, instance, vrf_id)); +DECLARE_HOOK(lm_client_disconnect, (uint8_t proto, uint16_t instance), + (proto, instance)); +DECLARE_HOOK(lm_get_chunk, + (struct label_manager_chunk * *lmc, uint8_t proto, + uint16_t instance, uint8_t keep, uint32_t size, uint32_t base, + vrf_id_t vrf_id), + (lmc, proto, instance, keep, size, base, vrf_id)); +DECLARE_HOOK(lm_release_chunk, + (uint8_t proto, uint16_t instance, uint32_t start, uint32_t end), + (proto, instance, start, end)); +DECLARE_HOOK(lm_cbs_inited, (), ()); + + +/* declare wrappers to be called in zapi_msg.c (as hooks must be called in + * source file where they were defined) + */ +void lm_client_connect_call(uint8_t proto, uint16_t instance, vrf_id_t vrf_id); +void lm_get_chunk_call(struct label_manager_chunk **lmc, uint8_t proto, + uint16_t instance, uint8_t keep, uint32_t size, + uint32_t base, vrf_id_t vrf_id); +void lm_release_chunk_call(uint8_t proto, uint16_t instance, uint32_t start, + uint32_t end); + +/* API for an external LM to return responses for requests */ +int lm_client_connect_response(uint8_t proto, uint16_t instance, + vrf_id_t vrf_id, uint8_t result); +int lm_get_chunk_response(struct label_manager_chunk *lmc, uint8_t proto, + uint16_t instance, vrf_id_t vrf_id); + +/* convenience function to allocate an lmc to be consumed by the above API */ +struct label_manager_chunk *create_label_chunk(uint8_t proto, + unsigned short instance, + uint8_t keep, uint32_t start, + uint32_t end); +void delete_label_chunk(void *val); + +/* register/unregister callbacks for hooks */ +void lm_hooks_register(void); +void lm_hooks_unregister(void); + /* * Main label manager struct * Holds a linked list of label chunks. @@ -65,18 +114,15 @@ struct label_manager { struct list *lc_list; }; -bool lm_is_external; - -int zread_relay_label_manager_request(int cmd, struct zserv *zserv, - struct stream *msg, vrf_id_t vrf_id); -void label_manager_init(char *lm_zserv_path); +void label_manager_init(void); struct label_manager_chunk *assign_label_chunk(uint8_t proto, unsigned short instance, uint8_t keep, uint32_t size, uint32_t base); int release_label_chunk(uint8_t proto, unsigned short instance, uint32_t start, uint32_t end); -int release_daemon_label_chunks(struct zserv *client); +int lm_client_disconnect_cb(struct zserv *client); +int release_daemon_label_chunks(uint8_t proto, unsigned short instance); void label_manager_close(void); #ifdef __cplusplus diff --git a/zebra/main.c b/zebra/main.c index 1947106750..84e83bc37e 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -92,7 +92,6 @@ struct option longopts[] = { {"keep_kernel", no_argument, NULL, 'k'}, {"socket", required_argument, NULL, 'z'}, {"ecmp", required_argument, NULL, 'e'}, - {"label_socket", no_argument, NULL, 'l'}, {"retain", no_argument, NULL, 'r'}, {"vrfdefaultname", required_argument, NULL, 'o'}, {"graceful_restart", required_argument, NULL, 'K'}, @@ -252,8 +251,6 @@ int main(int argc, char **argv) // int batch_mode = 0; char *zserv_path = NULL; char *vrf_default_name_configured = NULL; - /* Socket to external label manager */ - char *lblmgr_path = NULL; struct sockaddr_storage dummy; socklen_t dummylen; #if defined(HANDLE_ZAPI_FUZZING) @@ -270,7 +267,7 @@ int main(int argc, char **argv) frr_preinit(&zebra_di, argc, argv); frr_opt_add( - "baz:e:l:o:rK:" + "baz:e:o:rK:" #ifdef HAVE_NETLINK "s:n" #endif @@ -286,7 +283,6 @@ int main(int argc, char **argv) " -a, --allow_delete Allow other processes to delete zebra routes\n" " -z, --socket Set path of zebra socket\n" " -e, --ecmp Specify ECMP to use.\n" - " -l, --label_socket Socket to external label manager\n" " -r, --retain When program terminates, retain added route by zebra.\n" " -o, --vrfdefaultname Set default VRF name.\n" " -K, --graceful_restart Graceful restart at the kernel level, timer in seconds for expiration\n" @@ -341,9 +337,6 @@ int main(int argc, char **argv) exit(1); } break; - case 'l': - lblmgr_path = optarg; - break; case 'r': retain_mode = 1; break; @@ -451,7 +444,7 @@ int main(int argc, char **argv) zserv_start(zserv_path); /* Init label manager */ - label_manager_init(lblmgr_path); + label_manager_init(); /* RNH init */ zebra_rnh_init(); diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 198a47a21f..e018b9595c 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -57,7 +57,6 @@ #include "zebra/rtadv.h" #include "zebra/zebra_mpls.h" #include "zebra/zebra_mroute.h" -#include "zebra/label_manager.h" #include "zebra/zebra_vxlan.h" #include "zebra/rt.h" #include "zebra/zebra_pbr.h" @@ -928,10 +927,9 @@ 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, uint8_t proto, - uint16_t instance, - struct label_manager_chunk *lmc) +int zsend_assign_label_chunk_response(struct zserv *client, 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); @@ -959,9 +957,8 @@ static int zsend_assign_label_chunk_response(struct zserv *client, } /* Send response to a label manager connect request to client */ -static int zsend_label_manager_connect_response(struct zserv *client, - vrf_id_t vrf_id, - unsigned short result) +int zsend_label_manager_connect_response(struct zserv *client, vrf_id_t vrf_id, + unsigned short result) { int ret; struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); @@ -1897,27 +1894,16 @@ static void zread_label_manager_connect(struct zserv *client, flog_err(EC_ZEBRA_TM_WRONG_PROTO, "client %d has wrong protocol %s", client->sock, zebra_route_string(proto)); - if (client->is_synchronous) - zsend_label_manager_connect_response(client, vrf_id, 1); + zsend_label_manager_connect_response(client, vrf_id, 1); return; } - zlog_notice("client %d with vrf %u instance %u connected as %s", - client->sock, vrf_id, instance, zebra_route_string(proto)); + + /* recall proto and instance in this socket */ client->proto = proto; client->instance = instance; - /* - * Release previous labels of same protocol and instance. - * This is done in case it restarted from an unexpected shutdown. - */ - release_daemon_label_chunks(client); - - zlog_debug( - " Label Manager client connected: sock %d, proto %s, vrf %u instance %u", - client->sock, zebra_route_string(proto), vrf_id, instance); - /* send response back */ - if (client->is_synchronous) - zsend_label_manager_connect_response(client, vrf_id, 0); + /* call hook for connection using wrapper */ + lm_client_connect_call(proto, instance, vrf_id); stream_failure: return; @@ -1929,7 +1915,7 @@ static void zread_get_label_chunk(struct zserv *client, struct stream *msg, struct stream *s; uint8_t keep; uint32_t size, base; - struct label_manager_chunk *lmc; + struct label_manager_chunk *lmc = NULL; uint8_t proto; unsigned short instance; @@ -1943,7 +1929,9 @@ static void zread_get_label_chunk(struct zserv *client, struct stream *msg, STREAM_GETL(s, size); STREAM_GETL(s, base); - lmc = assign_label_chunk(proto, instance, keep, size, base); + /* call hook to get a chunk using wrapper */ + lm_get_chunk_call(&lmc, proto, instance, keep, size, base, vrf_id); + if (!lmc) flog_err( EC_ZEBRA_LM_CANNOT_ASSIGN_CHUNK, @@ -1953,8 +1941,6 @@ static void zread_get_label_chunk(struct zserv *client, struct stream *msg, zlog_debug("Assigned Label Chunk %u - %u to %s instance %u", lmc->start, lmc->end, zebra_route_string(proto), instance); - /* send response back */ - zsend_assign_label_chunk_response(client, vrf_id, proto, instance, lmc); stream_failure: return; @@ -1976,33 +1962,23 @@ static void zread_release_label_chunk(struct zserv *client, struct stream *msg) STREAM_GETL(s, start); STREAM_GETL(s, end); - release_label_chunk(proto, instance, start, end); + /* call hook to release a chunk using wrapper */ + lm_release_chunk_call(proto, instance, start, end); stream_failure: return; } + static void zread_label_manager_request(ZAPI_HANDLER_ARGS) { - /* to avoid sending other messages like ZERBA_INTERFACE_UP */ - client->is_synchronous = hdr->command == - ZEBRA_LABEL_MANAGER_CONNECT; - - /* external label manager */ - if (lm_is_external) - zread_relay_label_manager_request(hdr->command, client, msg, - zvrf_id(zvrf)); - /* this is a label manager */ + if (hdr->command == ZEBRA_LABEL_MANAGER_CONNECT + || hdr->command == ZEBRA_LABEL_MANAGER_CONNECT_ASYNC) + zread_label_manager_connect(client, msg, zvrf_id(zvrf)); else { - if (hdr->command == ZEBRA_LABEL_MANAGER_CONNECT || - hdr->command == ZEBRA_LABEL_MANAGER_CONNECT_ASYNC) - zread_label_manager_connect(client, msg, zvrf_id(zvrf)); - else { - if (hdr->command == ZEBRA_GET_LABEL_CHUNK) - zread_get_label_chunk(client, msg, - zvrf_id(zvrf)); - else if (hdr->command == ZEBRA_RELEASE_LABEL_CHUNK) - zread_release_label_chunk(client, msg); - } + if (hdr->command == ZEBRA_GET_LABEL_CHUNK) + zread_get_label_chunk(client, msg, zvrf_id(zvrf)); + else if (hdr->command == ZEBRA_RELEASE_LABEL_CHUNK) + zread_release_label_chunk(client, msg); } } diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h index d30fa2d0ef..884edfef04 100644 --- a/zebra/zapi_msg.h +++ b/zebra/zapi_msg.h @@ -29,6 +29,8 @@ #include "zebra/zserv.h" #include "zebra/zebra_pbr.h" #include "zebra/zebra_errors.h" +#include "zebra/label_manager.h" + #ifdef __cplusplus extern "C" { @@ -90,6 +92,14 @@ extern void zserv_nexthop_num_warn(const char *caller, const struct prefix *p, const unsigned int nexthop_num); extern void zsend_capabilities_all_clients(void); +extern int zsend_assign_label_chunk_response(struct zserv *client, + vrf_id_t vrf_id, uint8_t proto, + uint16_t instance, + struct label_manager_chunk *lmc); +extern int zsend_label_manager_connect_response(struct zserv *client, + vrf_id_t vrf_id, + unsigned short result); + #ifdef __cplusplus } diff --git a/zebra/zserv.c b/zebra/zserv.c index cb9ca6578b..70b4594813 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -535,28 +535,6 @@ static int zserv_process_messages(struct thread *thread) int zserv_send_message(struct zserv *client, struct stream *msg) { - /* - * This is a somewhat poorly named variable added with Zebra's portion - * of the label manager. That component does not use the regular - * zserv/zapi_msg interface for handling its messages, as the client - * itself runs in-process. Instead it uses synchronous writes on the - * zserv client's socket directly in the zread* handlers for its - * message types. Furthermore, it cannot handle the usual messages - * Zebra sends (such as those for interface changes) and so has added - * this flag and check here as a hack to suppress all messages that it - * does not explicitly know about. - * - * In any case this needs to be cleaned up at some point. - * - * See also: - * zread_label_manager_request - * zsend_label_manager_connect_response - * zsend_assign_label_chunk_response - * ... - */ - if (client->is_synchronous) - return 0; - pthread_mutex_lock(&client->obuf_mtx); { stream_fifo_push(client->obuf_fifo, msg); @@ -710,9 +688,6 @@ static struct zserv *zserv_client_create(int sock) } client->ridinfo = vrf_bitmap_init(); - /* by default, it's not a synchronous client */ - client->is_synchronous = 0; - /* Add this client to linked list. */ listnode_add(zrouter.client_list, client); diff --git a/zebra/zserv.h b/zebra/zserv.h index 34965618f2..708ff1e226 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -98,7 +98,6 @@ struct zserv { /* client's protocol */ uint8_t proto; uint16_t instance; - uint8_t is_synchronous; /* Statistics */ uint32_t redist_v4_add_cnt;