diff options
author | Quentin Young <qlyoung@cumulusnetworks.com> | 2019-10-14 19:15:09 +0200 |
---|---|---|
committer | Quentin Young <qlyoung@cumulusnetworks.com> | 2019-10-14 19:15:09 +0200 |
commit | 6a597223d3bb63602bcdb9aa840702f1850cadcc (patch) | |
tree | 9f9aa64d9787973e9f67a0fcc84b90f2a3820af6 /zebra | |
parent | Merge pull request #5141 from opensourcerouting/bfdd-fixes-bundle (diff) | |
download | frr-6a597223d3bb63602bcdb9aa840702f1850cadcc.tar.xz frr-6a597223d3bb63602bcdb9aa840702f1850cadcc.zip |
Revert "Merge pull request #4885 from satheeshkarra/pim_mlag"
This reverts commit d563896dada99f3474d428f928786cbfde936fee, reversing
changes made to 09ea1a40386f02a13cdb0462cc55af0d03f0c277.
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/subdir.am | 5 | ||||
-rw-r--r-- | zebra/zapi_msg.c | 3 | ||||
-rw-r--r-- | zebra/zebra_mlag.c | 1367 | ||||
-rw-r--r-- | zebra/zebra_mlag.h | 49 | ||||
-rw-r--r-- | zebra/zebra_mlag_private.c | 302 | ||||
-rw-r--r-- | zebra/zebra_mlag_private.h | 40 | ||||
-rw-r--r-- | zebra/zebra_router.h | 30 | ||||
-rw-r--r-- | zebra/zserv.h | 7 |
8 files changed, 19 insertions, 1784 deletions
diff --git a/zebra/subdir.am b/zebra/subdir.am index 859c8c083..25040a271 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -38,9 +38,6 @@ man8 += $(MANBUILD)/zebra.8 endif zebra_zebra_LDADD = lib/libfrr.la $(LIBCAP) -if HAVE_PROTOBUF -zebra_zebra_LDADD += mlag/libmlag_pb.la $(PROTOBUF_C_LIBS) -endif zebra_zebra_SOURCES = \ zebra/connected.c \ zebra/debug.c \ @@ -69,7 +66,6 @@ zebra_zebra_SOURCES = \ zebra/rule_netlink.c \ zebra/rule_socket.c \ zebra/zebra_mlag.c \ - zebra/zebra_mlag_private.c \ zebra/zebra_l2.c \ zebra/zebra_memory.c \ zebra/zebra_dplane.c \ @@ -134,7 +130,6 @@ noinst_HEADERS += \ zebra/rtadv.h \ zebra/rule_netlink.h \ zebra/zebra_mlag.h \ - zebra/zebra_mlag_private.h \ zebra/zebra_fpm_private.h \ zebra/zebra_l2.h \ zebra/zebra_dplane.h \ diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 582003290..b0488b755 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -2551,9 +2551,6 @@ void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = { [ZEBRA_IPTABLE_DELETE] = zread_iptable, [ZEBRA_VXLAN_FLOOD_CONTROL] = zebra_vxlan_flood_control, [ZEBRA_VXLAN_SG_REPLAY] = zebra_vxlan_sg_replay, - [ZEBRA_MLAG_CLIENT_REGISTER] = zebra_mlag_client_register, - [ZEBRA_MLAG_CLIENT_UNREGISTER] = zebra_mlag_client_unregister, - [ZEBRA_MLAG_FORWARD_MSG] = zebra_mlag_forward_client_msg, }; #if defined(HANDLE_ZAPI_FUZZING) diff --git a/zebra/zebra_mlag.c b/zebra/zebra_mlag.c index 633ebe95c..5012cc2a4 100644 --- a/zebra/zebra_mlag.c +++ b/zebra/zebra_mlag.c @@ -1,5 +1,5 @@ /* Zebra Mlag Code. - * Copyright (C) 2019 Cumulus Networks, Inc. + * Copyright (C) 2018 Cumulus Networks, Inc. * Donald Sharp * * This file is part of FRR. @@ -23,13 +23,9 @@ #include "command.h" #include "hook.h" -#include "frr_pthread.h" -#include "mlag.h" #include "zebra/zebra_mlag.h" -#include "zebra/zebra_mlag_private.h" #include "zebra/zebra_router.h" -#include "zebra/zebra_memory.h" #include "zebra/zapi_msg.h" #include "zebra/debug.h" @@ -37,551 +33,6 @@ #include "zebra/zebra_mlag_clippy.c" #endif -#define ZEBRA_MLAG_METADATA_LEN 4 -#define ZEBRA_MLAG_MSG_BCAST 0xFFFFFFFF -#define MAXCH_LEN 80 - -uint8_t mlag_wr_buffer[ZEBRA_MLAG_BUF_LIMIT]; -uint8_t mlag_rd_buffer[ZEBRA_MLAG_BUF_LIMIT]; -uint32_t mlag_rd_buf_offset; - -static bool test_mlag_in_progress; - -static int zebra_mlag_signal_write_thread(void); -static int zebra_mlag_terminate_pthread(struct thread *event); -static int zebra_mlag_post_data_from_main_thread(struct thread *thread); -static void zebra_mlag_publish_process_state(struct zserv *client, - zebra_message_types_t msg_type); - -/**********************MLAG Interaction***************************************/ - -/* - * API to post the Registartion to MLAGD - * MLAG will not process any messages with out the registration - */ -void zebra_mlag_send_register(void) -{ - struct stream *s = NULL; - - s = stream_new(sizeof(struct mlag_msg)); - if (!s) - return; - - stream_putl(s, MLAG_REGISTER); - stream_putw(s, MLAG_MSG_NULL_PAYLOAD); - stream_putw(s, MLAG_MSG_NO_BATCH); - stream_fifo_push_safe(zrouter.mlag_info.mlag_fifo, s); - zebra_mlag_signal_write_thread(); - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: Enqueued MLAG Register to MLAG Thread ", - __func__); -} - -/* - * API to post the De-Registartion to MLAGD - * MLAG will not process any messages after the de-registration - */ -void zebra_mlag_send_deregister(void) -{ - struct stream *s = NULL; - - s = stream_new(sizeof(struct mlag_msg)); - if (!s) - return; - - stream_putl(s, MLAG_DEREGISTER); - stream_putw(s, MLAG_MSG_NULL_PAYLOAD); - stream_putw(s, MLAG_MSG_NO_BATCH); - stream_fifo_push_safe(zrouter.mlag_info.mlag_fifo, s); - zebra_mlag_signal_write_thread(); - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: Enqueued MLAG De-Register to MLAG Thread ", - __func__); -} - -/* - * API To handle MLAG Received data - * Decodes teh data using protobuf and enqueue to main thread - * main thread publish this to clients based on client subscrption - */ -void zebra_mlag_process_mlag_data(uint8_t *data, uint32_t len) -{ - struct stream *s = NULL; - struct stream *s1 = NULL; - int msg_type = 0; - - s = stream_new(ZEBRA_MAX_PACKET_SIZ); - if (s) - msg_type = zebra_mlag_protobuf_decode_message(&s, data, len); - - if (msg_type <= 0) { - /* Something went wrong in decoding */ - stream_free(s); - zlog_err("%s: failed to process mlag data-%d, %u", __func__, - msg_type, len); - return; - } - - /* - * additional four bytes are for mesasge type - */ - s1 = stream_new(stream_get_endp(s) + ZEBRA_MLAG_METADATA_LEN); - stream_putl(s1, msg_type); - stream_put(s1, s->data, stream_get_endp(s)); - thread_add_event(zrouter.master, zebra_mlag_post_data_from_main_thread, - s1, 0, NULL); - stream_free(s); -} - -/**********************End of MLAG Interaction********************************/ - -/************************MLAG Thread Processing*******************************/ - -/* - * after posting every 1000 packets, MLAG Thread wll be yielded to give CPU - * for other threads - */ -#define ZEBRA_MLAG_POST_LIMIT 100 - -/* - * Thsi thread reads the clients data from the Gloabl queue and encodes with - * protobuf and pass on to the MLAG socket. - */ -static int zebra_mlag_thread_handler(struct thread *event) -{ - struct stream *s; - uint32_t wr_count = 0; - uint32_t msg_type = 0; - uint32_t max_count = 0; - int len = 0; - - wr_count = stream_fifo_count_safe(zrouter.mlag_info.mlag_fifo); - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug(":%s: Processing MLAG write, %d messages in queue", - __func__, wr_count); - - pthread_mutex_lock(&zrouter.mlag_info.mlag_th_mtx); - zrouter.mlag_info.t_write = NULL; - pthread_mutex_unlock(&zrouter.mlag_info.mlag_th_mtx); - - max_count = MIN(wr_count, ZEBRA_MLAG_POST_LIMIT); - - for (wr_count = 0; wr_count < max_count; wr_count++) { - s = stream_fifo_pop_safe(zrouter.mlag_info.mlag_fifo); - if (!s) { - zlog_debug(":%s: Got a NULL Messages, some thing wrong", - __func__); - break; - } - - /* - * Encode the data now - */ - len = zebra_mlag_protobuf_encode_client_data(s, &msg_type); - - /* - * write to MCLAGD - */ - if (len > 0) { - zebra_mlag_private_write_data(mlag_wr_buffer, len); - - /* - * If mesasge type is De-register, send a signal to main - * thread, sothat necessary cleanup will be done by main - * thread. - */ - if (msg_type == MLAG_DEREGISTER) { - thread_add_event(zrouter.master, - zebra_mlag_terminate_pthread, - NULL, 0, NULL); - } - } - - stream_free(s); - } - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug(":%s: Posted %d messages to MLAGD", __func__, - wr_count); - /* - * Currently there is only message write task is enqueued to this - * thread, yielding was added for future purpose, sothat this thread can - * server other tasks also and in case FIFO is empty, this task will be - * schedule when main thread adds some messages - */ - if (wr_count >= ZEBRA_MLAG_POST_LIMIT) - zebra_mlag_signal_write_thread(); - return 0; -} - -/* - * API to handle teh process state. - * In case of Down, Zebra keep monitoring the MLAG state. - * all the state Notifications will be published to clients - */ -void zebra_mlag_handle_process_state(enum zebra_mlag_state state) -{ - if (state == MLAG_UP) { - zrouter.mlag_info.connected = true; - zebra_mlag_publish_process_state(NULL, ZEBRA_MLAG_PROCESS_UP); - zebra_mlag_send_register(); - } else if (state == MLAG_DOWN) { - zrouter.mlag_info.connected = false; - zebra_mlag_publish_process_state(NULL, ZEBRA_MLAG_PROCESS_DOWN); - zebra_mlag_private_monitor_state(); - } -} - -/***********************End of MLAG Thread processing*************************/ - -/*************************Multi-entratnt Api's********************************/ - -/* - * Provider api to signal that work/events are available - * for the Zebra MLAG Write pthread. - * This API is called from 2 pthreads.. - * 1) by main thread when client posts a MLAG Message - * 2) by MLAG Thread, in case of yield - * though this api, is called from two threads we don't need any locking - * because Thread task enqueue is thread safe means internally it had - * necessary protection - */ -static int zebra_mlag_signal_write_thread(void) -{ - pthread_mutex_lock(&zrouter.mlag_info.mlag_th_mtx); - if (zrouter.mlag_info.zebra_pth_mlag) { - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug(":%s: Scheduling MLAG write", __func__); - thread_add_event(zrouter.mlag_info.th_master, - zebra_mlag_thread_handler, NULL, 0, - &zrouter.mlag_info.t_write); - } - pthread_mutex_unlock(&zrouter.mlag_info.mlag_th_mtx); - return 0; -} - -/* - * API will be used to publish the MLAG state to interested clients - * In case client is passed, state is posted only for that client, - * otherwise to all interested clients - * this api can be called from two threads. - * 1) from main thread: when client is passed - * 2) from MLAG Thread: when client is NULL - * - * In second case, to avoid global data access data will be post to Main - * thread, so that actual posting to cleints will happen from Main thread. - */ -static void zebra_mlag_publish_process_state(struct zserv *client, - zebra_message_types_t msg_type) -{ - struct stream *s = NULL; - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: Publishing MLAG process state:%s to %s Client", - __func__, - (msg_type == ZEBRA_MLAG_PROCESS_UP) ? "UP" : "DOWN", - (client) ? "one" : "all"); - - if (client) { - s = stream_new(ZEBRA_HEADER_SIZE); - zclient_create_header(s, msg_type, VRF_DEFAULT); - zserv_send_message(client, s); - return; - } - - - /* - * additional four bytes are for mesasge type - */ - s = stream_new(ZEBRA_HEADER_SIZE + ZEBRA_MLAG_METADATA_LEN); - stream_putl(s, ZEBRA_MLAG_MSG_BCAST); - zclient_create_header(s, msg_type, VRF_DEFAULT); - thread_add_event(zrouter.master, zebra_mlag_post_data_from_main_thread, - s, 0, NULL); -} - -/**************************End of Multi-entrant Apis**************************/ - -/***********************Zebra Main thread processing**************************/ - -/* - * To avoid data corruption, messages will be post to clients only from - * main thread, beacuse for that access was needed for clients list. - * so instaed of forcing the locks, messages will be posted from main thread. - */ -static int zebra_mlag_post_data_from_main_thread(struct thread *thread) -{ - struct stream *s = THREAD_ARG(thread); - struct stream *zebra_s = NULL; - struct listnode *node; - struct zserv *client; - uint32_t msg_type = 0; - uint32_t msg_len = 0; - - if (!s) - return -1; - - STREAM_GETL(s, msg_type); - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug( - "%s: Posting MLAG data for msg_type:0x%x to interested cleints", - __func__, msg_type); - - msg_len = s->endp - ZEBRA_MLAG_METADATA_LEN; - for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) { - if (client->mlag_updates_interested == true) { - if (msg_type != ZEBRA_MLAG_MSG_BCAST - && !CHECK_FLAG(client->mlag_reg_mask1, - (1 << msg_type))) { - continue; - } - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug( - "%s: Posting MLAG data of length-%d to client:%d ", - __func__, msg_len, client->proto); - - zebra_s = stream_new(msg_len); - STREAM_GET(zebra_s->data, s, msg_len); - zebra_s->endp = msg_len; - stream_putw_at(zebra_s, 0, msg_len); - - /* - * This stream will be enqueued to client_obuf, it will - * be freed after posting to client socket. - */ - zserv_send_message(client, zebra_s); - zebra_s = NULL; - } - } - - stream_free(s); - return 0; -stream_failure: - stream_free(s); - if (zebra_s) - stream_free(zebra_s); - return 0; -} - -/* - * Start the MLAG Thread, this will be used to write client data on to - * MLAG Process and to read the data from MLAG and post to cleints. - * when all clients are un-registered, this Thread will be - * suspended. - */ -static void zebra_mlag_spawn_pthread(void) -{ - /* Start MLAG write pthread */ - - struct frr_pthread_attr pattr = {.start = - frr_pthread_attr_default.start, - .stop = frr_pthread_attr_default.stop}; - - zrouter.mlag_info.zebra_pth_mlag = - frr_pthread_new(&pattr, "Zebra MLAG thread", "Zebra MLAG"); - - zrouter.mlag_info.th_master = zrouter.mlag_info.zebra_pth_mlag->master; - - - /* Enqueue an initial event to the Newly spawn MLAG pthread */ - zebra_mlag_signal_write_thread(); - - frr_pthread_run(zrouter.mlag_info.zebra_pth_mlag, NULL); -} - -/* - * all clients are un-registered for MLAG Updates, terminate the - * MLAG write thread - */ -static int zebra_mlag_terminate_pthread(struct thread *event) -{ - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("Zebra MLAG write thread terminate calleid"); - - if (zrouter.mlag_info.clients_interested_cnt) { - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug( - "Zebra MLAG: still some clients are interested"); - return 0; - } - - frr_pthread_stop(zrouter.mlag_info.zebra_pth_mlag, NULL); - - /* Destroy pthread */ - frr_pthread_destroy(zrouter.mlag_info.zebra_pth_mlag); - zrouter.mlag_info.zebra_pth_mlag = NULL; - zrouter.mlag_info.th_master = NULL; - zrouter.mlag_info.t_read = NULL; - zrouter.mlag_info.t_write = NULL; - - /* - * Send Notification to clean private data - */ - zebra_mlag_private_cleanup_data(); - return 0; -} - -/* - * API to register zebra client for MLAG Updates - */ -void zebra_mlag_client_register(ZAPI_HANDLER_ARGS) -{ - struct stream *s; - uint32_t reg_mask = 0; - int rc = 0; - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("Received MLAG Registration from client-proto:%d", - client->proto); - - - /* Get input stream. */ - s = msg; - - /* Get data. */ - STREAM_GETL(s, reg_mask); - - if (client->mlag_updates_interested == true) { - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug( - "Client is registered, existing mask: 0x%x, new mask: 0x%x", - client->mlag_reg_mask1, reg_mask); - if (client->mlag_reg_mask1 != reg_mask) - client->mlag_reg_mask1 = reg_mask; - /* - * Client might missed MLAG-UP Notification, post-it again - */ - zebra_mlag_publish_process_state(client, ZEBRA_MLAG_PROCESS_UP); - return; - } - - - client->mlag_updates_interested = true; - client->mlag_reg_mask1 = reg_mask; - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("Registering for MLAG Upadtes with mask: 0x%x, ", - client->mlag_reg_mask1); - - zrouter.mlag_info.clients_interested_cnt++; - - if (zrouter.mlag_info.clients_interested_cnt == 1) { - /* - * First-client for MLAG Updates,open the communication channel - * with MLAG - */ - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug( - "First client, opening the channel with MLAG"); - - zebra_mlag_spawn_pthread(); - rc = zebra_mlag_private_open_channel(); - if (rc < 0) { - /* - * For some reason, zebra not able to open the - * comm-channel with MLAG, so post MLAG-DOWN to client. - * later when the channel is open, zebra will send - * MLAG-UP - */ - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug( - "Fail to open channel with MLAG,rc:%d, post Proto-down", - rc); - } - } - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("Client Registered successfully for MLAG Updates"); - - if (zrouter.mlag_info.connected == true) - zebra_mlag_publish_process_state(client, ZEBRA_MLAG_PROCESS_UP); -stream_failure: - return; -} - -/* - * API to un-register for MLAG Updates - */ -void zebra_mlag_client_unregister(ZAPI_HANDLER_ARGS) -{ - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("Received MLAG De-Registration from client-proto:%d", - client->proto); - - if (client->mlag_updates_interested == false) - /* Unexpected */ - return; - - client->mlag_updates_interested = false; - client->mlag_reg_mask1 = 0; - zrouter.mlag_info.clients_interested_cnt--; - - if (zrouter.mlag_info.clients_interested_cnt == 0) { - /* - * No-client is interested for MLAG Updates,close the - * communication channel with MLAG - */ - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("Last client for MLAG, close the channel "); - - /* - * Clean up flow: - * ============= - * 1) main thread calls socket close which posts De-register - * to MLAG write thread - * 2) after MLAG write thread posts De-register it sends a - * signal back to main thread to do the thread cleanup - * this was mainly to make sure De-register is posted to MCLAGD. - */ - zebra_mlag_private_close_channel(); - } - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug( - "Client De-Registered successfully for MLAG Updates"); -} - -/* - * Does following things. - * 1) allocated new local stream, and copies teh client data and enqueue - * to MLAG Thread - * 2) MLAG Thread after dequeing, encode the client data using protobuf - * and write on to MLAG - */ -void zebra_mlag_forward_client_msg(ZAPI_HANDLER_ARGS) -{ - struct stream *zebra_s; - struct stream *mlag_s; - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("Received Client MLAG Data from client-proto:%d", - client->proto); - - /* Get input stream. */ - zebra_s = msg; - mlag_s = stream_new(zebra_s->endp); - if (!mlag_s) - return; - - /* - * Client data is | Zebra Header + MLAG Data | - * we need to enqueue only the MLAG data, skipping Zebra Header - */ - stream_put(mlag_s, zebra_s->data + zebra_s->getp, - zebra_s->endp - zebra_s->getp); - stream_fifo_push_safe(zrouter.mlag_info.mlag_fifo, mlag_s); - zebra_mlag_signal_write_thread(); - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: Enqueued Client:%d data to MLAG Thread ", - __func__, client->proto); -} - -/***********************End of Zebra Main thread processing*************/ - enum mlag_role zebra_mlag_get_role(void) { return zrouter.mlag_info.role; @@ -594,7 +45,7 @@ DEFUN_HIDDEN (show_mlag, ZEBRA_STR "The mlag role on this machine\n") { - char buf[MAXCH_LEN]; + char buf[80]; vty_out(vty, "MLag is configured to: %s\n", mlag_role2str(zrouter.mlag_info.role, buf, sizeof(buf))); @@ -602,201 +53,18 @@ DEFUN_HIDDEN (show_mlag, return CMD_SUCCESS; } -static void test_mlag_post_mroute_add(void) -{ - struct stream *s = NULL; - char vrf_temp[20]; - char intf_temp[20]; - - s = stream_new(ZEBRA_MAX_PACKET_SIZ); - if (!s) - return; - - memset(vrf_temp, 0, 20); - memset(intf_temp, 0, 20); - - strlcpy(vrf_temp, "test", 20); - strlcpy(intf_temp, "br0.11", 20); - - stream_putl(s, MLAG_MROUTE_ADD); - stream_putw(s, sizeof(struct mlag_mroute_add)); - stream_putw(s, MLAG_MSG_NO_BATCH); - - /* payload*/ - stream_put(s, vrf_temp, VRF_NAMSIZ); - stream_putl(s, 0x01010101); /*source_ip*/ - stream_putl(s, 0xE4000001); /*group_ip*/ - stream_putl(s, 10); /*cost_to_rp*/ - stream_putl(s, 5); /*vni_id */ - stream_putc(s, 1); /*am_i_dr */ - stream_putc(s, 1); /*dual_active */ - stream_putl(s, 0x1004); /*vrf_id*/ - stream_put(s, intf_temp, INTERFACE_NAMSIZ); - stream_fifo_push_safe(zrouter.mlag_info.mlag_fifo, s); - zebra_mlag_signal_write_thread(); - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: Enqueued MLAG Mroute-add to MLAG Thread ", - __func__); -} - -static void test_mlag_post_mroute_del(void) -{ - struct stream *s = NULL; - char vrf_temp[20]; - char intf_temp[20]; - - - s = stream_new(ZEBRA_MAX_PACKET_SIZ); - if (!s) - return; - - memset(vrf_temp, 0, 20); - memset(intf_temp, 0, 20); - - strlcpy(vrf_temp, "test", 20); - strlcpy(intf_temp, "br0.11", 20); - - stream_putl(s, MLAG_MROUTE_DEL); - stream_putw(s, sizeof(struct mlag_mroute_del)); - stream_putw(s, MLAG_MSG_NO_BATCH); - - /* payload*/ - stream_put(s, vrf_temp, VRF_NAMSIZ); - stream_putl(s, 0x01010101); /*source_ip*/ - stream_putl(s, 0xE4000001); /*group_ip*/ - stream_putl(s, 5); /*vni_id */ - stream_putl(s, 0x1004); /*vrf_id*/ - stream_put(s, intf_temp, INTERFACE_NAMSIZ); - stream_fifo_push_safe(zrouter.mlag_info.mlag_fifo, s); - zebra_mlag_signal_write_thread(); - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: Enqueued MLAG Mroute-Del to MLAG Thread ", - __func__); -} - -static void test_mlag_post_mroute_bulk_add(void) -{ - struct stream *s = NULL; - char vrf_temp[20]; - char intf_temp[20]; - - s = stream_new(ZEBRA_MAX_PACKET_SIZ); - if (!s) - return; - - memset(vrf_temp, 0, 20); - memset(intf_temp, 0, 20); - - strlcpy(vrf_temp, "test", 20); - strlcpy(intf_temp, "br0.11", 20); - - stream_putl(s, MLAG_MROUTE_ADD_BULK); - stream_putw(s, 3 * sizeof(struct mlag_mroute_add)); - stream_putw(s, 3); - - /* payload-1*/ - stream_put(s, vrf_temp, VRF_NAMSIZ); - stream_putl(s, 0x01010101); /*source_ip*/ - stream_putl(s, 0xE4000001); /*group_ip*/ - stream_putl(s, 10); /*cost_to_rp*/ - stream_putl(s, 5); /*vni_id */ - stream_putc(s, 1); /*am_i_dr */ - stream_putc(s, 1); /*dual_active */ - stream_putl(s, 0x1004); /*vrf_id*/ - stream_put(s, intf_temp, INTERFACE_NAMSIZ); - - /* payload-2*/ - stream_put(s, vrf_temp, VRF_NAMSIZ); - stream_putl(s, 0x0); /*source_ip*/ - stream_putl(s, 0xE9000001); /*group_ip*/ - stream_putl(s, 10); /*cost_to_rp*/ - stream_putl(s, 5); /*vni_id */ - stream_putc(s, 1); /*am_i_dr */ - stream_putc(s, 1); /*dual_active */ - stream_putl(s, 0x1004); /*vrf_id*/ - stream_put(s, intf_temp, INTERFACE_NAMSIZ); - - /* payload-3*/ - stream_put(s, vrf_temp, VRF_NAMSIZ); - stream_putl(s, 0x01010101); /*source_ip*/ - stream_putl(s, 0xE5000001); /*group_ip*/ - stream_putl(s, 10); /*cost_to_rp*/ - stream_putl(s, 5); /*vni_id */ - stream_putc(s, 1); /*am_i_dr */ - stream_putc(s, 1); /*dual_active */ - stream_putl(s, 0x1004); /*vrf_id*/ - stream_put(s, intf_temp, INTERFACE_NAMSIZ); - stream_fifo_push_safe(zrouter.mlag_info.mlag_fifo, s); - zebra_mlag_signal_write_thread(); - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: Enqueued MLAG Mroute-Bulk to MLAG Thread ", - __func__); -} - -static void test_mlag_post_mroute_bulk_del(void) -{ - struct stream *s = NULL; - char vrf_temp[20]; - char intf_temp[20]; - - s = stream_new(ZEBRA_MAX_PACKET_SIZ); - if (!s) - return; - - memset(vrf_temp, 0, 20); - memset(intf_temp, 0, 20); - - strlcpy(vrf_temp, "test", 20); - strlcpy(intf_temp, "br0.11", 20); - - stream_putl(s, MLAG_MROUTE_DEL_BULK); - stream_putw(s, 2 * sizeof(struct mlag_mroute_del)); - stream_putw(s, 2); - - /* payload-1*/ - stream_put(s, vrf_temp, VRF_NAMSIZ); - stream_putl(s, 0x01010101); /*source_ip*/ - stream_putl(s, 0xE4000001); /*group_ip*/ - stream_putl(s, 5); /*vni_id */ - stream_putl(s, 0x1004); /*vrf_id*/ - stream_put(s, intf_temp, INTERFACE_NAMSIZ); - - /* payload-2*/ - stream_put(s, vrf_temp, VRF_NAMSIZ); - stream_putl(s, 0x0); /*source_ip*/ - stream_putl(s, 0xE9000001); /*group_ip*/ - stream_putl(s, 5); /*vni_id */ - stream_putl(s, 0x1004); /*vrf_id*/ - stream_put(s, intf_temp, INTERFACE_NAMSIZ); - - /* payload-3*/ - stream_put(s, vrf_temp, VRF_NAMSIZ); - stream_putl(s, 0x01010101); /*source_ip*/ - stream_putl(s, 0xE5000001); /*group_ip*/ - stream_putl(s, 5); /*vni_id */ - stream_putl(s, 0x1004); /*vrf_id*/ - stream_put(s, intf_temp, INTERFACE_NAMSIZ); - stream_fifo_push_safe(zrouter.mlag_info.mlag_fifo, s); - zebra_mlag_signal_write_thread(); - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: Enqueued MLAG Mroute-Bulk to MLAG Thread ", - __func__); -} - -DEFPY(test_mlag, test_mlag_cmd, - "test zebra mlag <none$none|primary$primary|secondary$secondary>", - "Test code\n" ZEBRA_STR - "Modify the Mlag state\n" - "Mlag is not setup on the machine\n" - "Mlag is setup to be primary\n" - "Mlag is setup to be the secondary\n") +DEFPY_HIDDEN (test_mlag, + test_mlag_cmd, + "test zebra mlag <none$none|primary$primary|secondary$secondary>", + "Test code\n" + ZEBRA_STR + "Modify the Mlag state\n" + "Mlag is not setup on the machine\n" + "Mlag is setup to be primary\n" + "Mlag is setup to be the secondary\n") { enum mlag_role orig = zrouter.mlag_info.role; - char buf1[MAXCH_LEN], buf2[MAXCH_LEN]; + char buf1[80], buf2[80]; if (none) zrouter.mlag_info.role = MLAG_ROLE_NONE; @@ -810,72 +78,8 @@ DEFPY(test_mlag, test_mlag_cmd, mlag_role2str(orig, buf1, sizeof(buf1)), mlag_role2str(orig, buf2, sizeof(buf2))); - if (orig != zrouter.mlag_info.role) { + if (orig != zrouter.mlag_info.role) zsend_capabilities_all_clients(); - if (zrouter.mlag_info.role != MLAG_ROLE_NONE) { - if (zrouter.mlag_info.clients_interested_cnt == 0 - && test_mlag_in_progress == false) { - if (zrouter.mlag_info.zebra_pth_mlag == NULL) - zebra_mlag_spawn_pthread(); - zrouter.mlag_info.clients_interested_cnt++; - test_mlag_in_progress = true; - zebra_mlag_private_open_channel(); - } - } else { - if (test_mlag_in_progress == true) { - test_mlag_in_progress = false; - zrouter.mlag_info.clients_interested_cnt--; - zebra_mlag_private_close_channel(); - } - } - } - - return CMD_SUCCESS; -} - -DEFPY(test_mlag_route, test_mlag_route_cmd, - "test zebra mlag route <add$add|del$del>", - "Test code\n" ZEBRA_STR - "Modify the Mlag state\n" - "Post Route Action to Mlag\n" - "Posting Route-add\n" - "Posting Route-del\n") -{ - - if (zrouter.mlag_info.connected == false) { - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("Test: Not connected to MLAG"); - return CMD_SUCCESS; - } - - if (add) - test_mlag_post_mroute_add(); - if (del) - test_mlag_post_mroute_del(); - - return CMD_SUCCESS; -} - -DEFPY(test_mlag_route_bulk, test_mlag_route_bulk_cmd, - "test zebra mlag route bulk <add$add|del$del>", - "Test code\n" ZEBRA_STR - "Modify the Mlag state\n" - "Post Route Action to Mlag\n" - "Posting Route-bulk\n" - "Posting Route-add\n" - "Posting Route-del\n") -{ - - if (zrouter.mlag_info.connected == false) { - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("Test: Not connected to MLAG"); - return CMD_SUCCESS; - } - - if (add) - test_mlag_post_mroute_bulk_add(); - if (del) - test_mlag_post_mroute_bulk_del(); return CMD_SUCCESS; } @@ -884,553 +88,8 @@ void zebra_mlag_init(void) { install_element(VIEW_NODE, &show_mlag_cmd); install_element(ENABLE_NODE, &test_mlag_cmd); - install_element(ENABLE_NODE, &test_mlag_route_cmd); - install_element(ENABLE_NODE, &test_mlag_route_bulk_cmd); - - /* - * Intialiaze teh MLAG Global variableis - * write thread will be craeted during actual registration with MCLAG - */ - zrouter.mlag_info.clients_interested_cnt = 0; - zrouter.mlag_info.connected = false; - zrouter.mlag_info.timer_running = false; - zrouter.mlag_info.mlag_fifo = stream_fifo_new(); - zrouter.mlag_info.zebra_pth_mlag = NULL; - zrouter.mlag_info.th_master = NULL; - zrouter.mlag_info.t_read = NULL; - zrouter.mlag_info.t_write = NULL; - test_mlag_in_progress = false; - zebra_mlag_reset_read_buffer(); - pthread_mutex_init(&zrouter.mlag_info.mlag_th_mtx, NULL); } void zebra_mlag_terminate(void) { } - - -/* - * - * ProtoBuf Encoding APIs - */ - -#ifdef HAVE_PROTOBUF - -DEFINE_MTYPE_STATIC(ZEBRA, MLAG_PBUF, "ZEBRA MLAG PROTOBUF") - -int zebra_mlag_protobuf_encode_client_data(struct stream *s, uint32_t *msg_type) -{ - ZebraMlagHeader hdr = ZEBRA_MLAG__HEADER__INIT; - struct mlag_msg mlag_msg; - uint8_t tmp_buf[ZEBRA_MLAG_BUF_LIMIT]; - int len = 0; - int n_len = 0; - int rc = 0; - char buf[MAXCH_LEN]; - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: Entering..", __func__); - - rc = zebra_mlag_lib_decode_mlag_hdr(s, &mlag_msg); - if (rc) - return rc; - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: Decoded msg length:%d..", __func__, - mlag_msg.data_len); - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: Mlag ProtoBuf encoding of message:%s", __func__, - zebra_mlag_lib_msgid_to_str(mlag_msg.msg_type, buf, - sizeof(buf))); - *msg_type = mlag_msg.msg_type; - switch (mlag_msg.msg_type) { - case MLAG_MROUTE_ADD: { - struct mlag_mroute_add msg; - ZebraMlagMrouteAdd pay_load = ZEBRA_MLAG_MROUTE_ADD__INIT; - uint32_t vrf_name_len = 0; - - rc = zebra_mlag_lib_decode_mroute_add(s, &msg); - if (rc) - return rc; - vrf_name_len = strlen(msg.vrf_name) + 1; - pay_load.vrf_name = XMALLOC(MTYPE_MLAG_PBUF, vrf_name_len); - strlcpy(pay_load.vrf_name, msg.vrf_name, vrf_name_len); - pay_load.source_ip = msg.source_ip; - pay_load.group_ip = msg.group_ip; - pay_load.cost_to_rp = msg.cost_to_rp; - pay_load.owner_id = msg.owner_id; - pay_load.am_i_dr = msg.am_i_dr; - pay_load.am_i_dual_active = msg.am_i_dual_active; - pay_load.vrf_id = msg.vrf_id; - - if (msg.owner_id == MLAG_OWNER_INTERFACE) { - vrf_name_len = strlen(msg.intf_name) + 1; - pay_load.intf_name = - XMALLOC(MTYPE_MLAG_PBUF, vrf_name_len); - strlcpy(pay_load.intf_name, msg.intf_name, - vrf_name_len); - } - - len = zebra_mlag_mroute_add__pack(&pay_load, tmp_buf); - XFREE(MTYPE_MLAG_PBUF, pay_load.vrf_name); - if (msg.owner_id == MLAG_OWNER_INTERFACE) - XFREE(MTYPE_MLAG_PBUF, pay_load.intf_name); - } break; - case MLAG_MROUTE_DEL: { - struct mlag_mroute_del msg; - ZebraMlagMrouteDel pay_load = ZEBRA_MLAG_MROUTE_DEL__INIT; - uint32_t vrf_name_len = 0; - - rc = zebra_mlag_lib_decode_mroute_del(s, &msg); - if (rc) - return rc; - vrf_name_len = strlen(msg.vrf_name) + 1; - pay_load.vrf_name = XMALLOC(MTYPE_MLAG_PBUF, vrf_name_len); - strlcpy(pay_load.vrf_name, msg.vrf_name, vrf_name_len); - pay_load.source_ip = msg.source_ip; - pay_load.group_ip = msg.group_ip; - pay_load.owner_id = msg.owner_id; - pay_load.vrf_id = msg.vrf_id; - - if (msg.owner_id == MLAG_OWNER_INTERFACE) { - vrf_name_len = strlen(msg.intf_name) + 1; - pay_load.intf_name = - XMALLOC(MTYPE_MLAG_PBUF, vrf_name_len); - strlcpy(pay_load.intf_name, msg.intf_name, - vrf_name_len); - } - - len = zebra_mlag_mroute_del__pack(&pay_load, tmp_buf); - XFREE(MTYPE_MLAG_PBUF, pay_load.vrf_name); - if (msg.owner_id == MLAG_OWNER_INTERFACE) - XFREE(MTYPE_MLAG_PBUF, pay_load.intf_name); - } break; - case MLAG_MROUTE_ADD_BULK: { - struct mlag_mroute_add msg; - ZebraMlagMrouteAddBulk Bulk_msg = - ZEBRA_MLAG_MROUTE_ADD_BULK__INIT; - ZebraMlagMrouteAdd **pay_load = NULL; - int i = 0; - bool cleanup = false; - - Bulk_msg.n_mroute_add = mlag_msg.msg_cnt; - pay_load = XMALLOC(MTYPE_MLAG_PBUF, - sizeof(ZebraMlagMrouteAdd *) - * Bulk_msg.n_mroute_add); - - for (i = 0; i < mlag_msg.msg_cnt; i++) { - - uint32_t vrf_name_len = 0; - - rc = zebra_mlag_lib_decode_mroute_add(s, &msg); - if (rc) { - cleanup = true; - break; - } - pay_load[i] = XMALLOC(MTYPE_MLAG_PBUF, - sizeof(ZebraMlagMrouteAdd)); - zebra_mlag_mroute_add__init(pay_load[i]); - - vrf_name_len = strlen(msg.vrf_name) + 1; - pay_load[i]->vrf_name = - XMALLOC(MTYPE_MLAG_PBUF, vrf_name_len); - strlcpy(pay_load[i]->vrf_name, msg.vrf_name, - vrf_name_len); - pay_load[i]->source_ip = msg.source_ip; - pay_load[i]->group_ip = msg.group_ip; - pay_load[i]->cost_to_rp = msg.cost_to_rp; - pay_load[i]->owner_id = msg.owner_id; - pay_load[i]->am_i_dr = msg.am_i_dr; - pay_load[i]->am_i_dual_active = msg.am_i_dual_active; - pay_load[i]->vrf_id = msg.vrf_id; - if (msg.owner_id == MLAG_OWNER_INTERFACE) { - vrf_name_len = strlen(msg.intf_name) + 1; - pay_load[i]->intf_name = - XMALLOC(MTYPE_MLAG_PBUF, vrf_name_len); - - strlcpy(pay_load[i]->intf_name, msg.intf_name, - vrf_name_len); - } - } - if (cleanup == false) { - Bulk_msg.mroute_add = pay_load; - len = zebra_mlag_mroute_add_bulk__pack(&Bulk_msg, - tmp_buf); - } - - for (i = 0; i < mlag_msg.msg_cnt; i++) { - if (pay_load[i]->vrf_name) - XFREE(MTYPE_MLAG_PBUF, pay_load[i]->vrf_name); - if (pay_load[i]->owner_id == MLAG_OWNER_INTERFACE - && pay_load[i]->intf_name) - XFREE(MTYPE_MLAG_PBUF, pay_load[i]->intf_name); - if (pay_load[i]) - XFREE(MTYPE_MLAG_PBUF, pay_load[i]); - } - XFREE(MTYPE_MLAG_PBUF, pay_load); - if (cleanup == true) - return -1; - } break; - case MLAG_MROUTE_DEL_BULK: { - struct mlag_mroute_del msg; - ZebraMlagMrouteDelBulk Bulk_msg = - ZEBRA_MLAG_MROUTE_DEL_BULK__INIT; - ZebraMlagMrouteDel **pay_load = NULL; - int i = 0; - bool cleanup = false; - - Bulk_msg.n_mroute_del = mlag_msg.msg_cnt; - pay_load = XMALLOC(MTYPE_MLAG_PBUF, - sizeof(ZebraMlagMrouteDel *) - * Bulk_msg.n_mroute_del); - - for (i = 0; i < mlag_msg.msg_cnt; i++) { - - uint32_t vrf_name_len = 0; - - rc = zebra_mlag_lib_decode_mroute_del(s, &msg); - if (rc) { - cleanup = true; - break; - } - - pay_load[i] = XMALLOC(MTYPE_MLAG_PBUF, - sizeof(ZebraMlagMrouteDel)); - zebra_mlag_mroute_del__init(pay_load[i]); - - vrf_name_len = strlen(msg.vrf_name) + 1; - pay_load[i]->vrf_name = - XMALLOC(MTYPE_MLAG_PBUF, vrf_name_len); - - strlcpy(pay_load[i]->vrf_name, msg.vrf_name, - vrf_name_len); - pay_load[i]->source_ip = msg.source_ip; - pay_load[i]->group_ip = msg.group_ip; - pay_load[i]->owner_id = msg.owner_id; - pay_load[i]->vrf_id = msg.vrf_id; - if (msg.owner_id == MLAG_OWNER_INTERFACE) { - vrf_name_len = strlen(msg.intf_name) + 1; - pay_load[i]->intf_name = - XMALLOC(MTYPE_MLAG_PBUF, vrf_name_len); - - strlcpy(pay_load[i]->intf_name, msg.intf_name, - vrf_name_len); - } - } - if (cleanup == false) { - Bulk_msg.mroute_del = pay_load; - len = zebra_mlag_mroute_del_bulk__pack(&Bulk_msg, - tmp_buf); - } - - for (i = 0; i < mlag_msg.msg_cnt; i++) { - if (pay_load[i]->vrf_name) - XFREE(MTYPE_MLAG_PBUF, pay_load[i]->vrf_name); - if (pay_load[i]->owner_id == MLAG_OWNER_INTERFACE - && pay_load[i]->intf_name) - XFREE(MTYPE_MLAG_PBUF, pay_load[i]->intf_name); - if (pay_load[i]) - XFREE(MTYPE_MLAG_PBUF, pay_load[i]); - } - XFREE(MTYPE_MLAG_PBUF, pay_load); - if (cleanup == true) - return -1; - } break; - default: - break; - } - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: length of Mlag ProtoBuf encoded message:%s, %d", - __func__, - zebra_mlag_lib_msgid_to_str(mlag_msg.msg_type, buf, - sizeof(buf)), - len); - hdr.type = (ZebraMlagHeader__MessageType)mlag_msg.msg_type; - if (len != 0) { - hdr.data.len = len; - hdr.data.data = XMALLOC(MTYPE_MLAG_PBUF, len); - memcpy(hdr.data.data, tmp_buf, len); - } - - /* - * ProtoBuf Infra will not support to demarc the pointers whem multiple - * mesasges are posted inside a single Buffer. - * 2 -sloutions exist to solve this - * 1. add Unenoced length at the beginning of every message, this will - * be used to point to next mesasge in the buffer - * 2. another solution is defining all messages insides another message - * But this will permit only 32 messages. this can be extended with - * multiple levels. - * for simplicity we are going with solution-1. - */ - len = zebra_mlag__header__pack(&hdr, - (mlag_wr_buffer + ZEBRA_MLAG_LEN_SIZE)); - n_len = htonl(len); - memcpy(mlag_wr_buffer, &n_len, ZEBRA_MLAG_LEN_SIZE); - len += ZEBRA_MLAG_LEN_SIZE; - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug( - "%s: length of Mlag ProtoBuf message:%s with Header %d", - __func__, - zebra_mlag_lib_msgid_to_str(mlag_msg.msg_type, buf, - sizeof(buf)), - len); - if (hdr.data.data) - XFREE(MTYPE_MLAG_PBUF, hdr.data.data); - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: Exiting..", __func__); - return len; -} - -int zebra_mlag_protobuf_decode_message(struct stream **s, uint8_t *data, - uint32_t len) -{ - uint32_t msg_type; - ZebraMlagHeader *hdr = NULL; - char buf[MAXCH_LEN]; - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: Entering..", __func__); - hdr = zebra_mlag__header__unpack(NULL, len, data); - if (hdr == NULL) - return -1; - - /* - * ADD The MLAG Header - */ - zclient_create_header(*s, ZEBRA_MLAG_FORWARD_MSG, VRF_DEFAULT); - - msg_type = hdr->type; - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: Mlag ProtoBuf decoding of message:%s", __func__, - zebra_mlag_lib_msgid_to_str(msg_type, buf, - sizeof(buf))); - - /* - * Internal MLAG Message-types & MLAG.proto message types should - * always match, otherwise there can be decoding errors - * To avoid exposing clients with Protobuf flags, using internal - * message-types - */ - stream_putl(*s, hdr->type); - - if (hdr->data.len == 0) { - /* NULL Payload */ - stream_putw(*s, MLAG_MSG_NULL_PAYLOAD); - /* No Batching */ - stream_putw(*s, MLAG_MSG_NO_BATCH); - } else { - switch (msg_type) { - case ZEBRA_MLAG__HEADER__MESSAGE_TYPE__ZEBRA_MLAG_STATUS_UPDATE: { - ZebraMlagStatusUpdate *msg = NULL; - - msg = zebra_mlag_status_update__unpack( - NULL, hdr->data.len, hdr->data.data); - if (msg == NULL) { - zebra_mlag__header__free_unpacked(hdr, NULL); - return -1; - } - /* Payload len */ - stream_putw(*s, sizeof(struct mlag_status)); - /* No Batching */ - stream_putw(*s, MLAG_MSG_NO_BATCH); - /* Actual Data */ - stream_put(*s, msg->peerlink, INTERFACE_NAMSIZ); - stream_putl(*s, msg->my_role); - stream_putl(*s, msg->peer_state); - zebra_mlag_status_update__free_unpacked(msg, NULL); - } break; - case ZEBRA_MLAG__HEADER__MESSAGE_TYPE__ZEBRA_MLAG_VXLAN_UPDATE: { - ZebraMlagVxlanUpdate *msg = NULL; - - msg = zebra_mlag_vxlan_update__unpack( - NULL, hdr->data.len, hdr->data.data); - if (msg == NULL) { - zebra_mlag__header__free_unpacked(hdr, NULL); - return -1; - } - /* Payload len */ - stream_putw(*s, sizeof(struct mlag_vxlan)); - /* No Batching */ - stream_putw(*s, MLAG_MSG_NO_BATCH); - /* Actual Data */ - stream_putl(*s, msg->anycast_ip); - stream_putl(*s, msg->local_ip); - zebra_mlag_vxlan_update__free_unpacked(msg, NULL); - } break; - case ZEBRA_MLAG__HEADER__MESSAGE_TYPE__ZEBRA_MLAG_MROUTE_ADD: { - ZebraMlagMrouteAdd *msg = NULL; - - msg = zebra_mlag_mroute_add__unpack(NULL, hdr->data.len, - hdr->data.data); - if (msg == NULL) { - zebra_mlag__header__free_unpacked(hdr, NULL); - return -1; - } - /* Payload len */ - stream_putw(*s, sizeof(struct mlag_mroute_add)); - /* No Batching */ - stream_putw(*s, MLAG_MSG_NO_BATCH); - /* Actual Data */ - stream_put(*s, msg->vrf_name, VRF_NAMSIZ); - - stream_putl(*s, msg->source_ip); - stream_putl(*s, msg->group_ip); - stream_putl(*s, msg->cost_to_rp); - stream_putl(*s, msg->owner_id); - stream_putc(*s, msg->am_i_dr); - stream_putc(*s, msg->am_i_dual_active); - stream_putl(*s, msg->vrf_id); - if (msg->owner_id == MLAG_OWNER_INTERFACE) - stream_put(*s, msg->intf_name, - INTERFACE_NAMSIZ); - else - stream_put(*s, NULL, INTERFACE_NAMSIZ); - zebra_mlag_mroute_add__free_unpacked(msg, NULL); - } break; - case ZEBRA_MLAG__HEADER__MESSAGE_TYPE__ZEBRA_MLAG_MROUTE_DEL: { - ZebraMlagMrouteDel *msg = NULL; - - msg = zebra_mlag_mroute_del__unpack(NULL, hdr->data.len, - hdr->data.data); - if (msg == NULL) { - zebra_mlag__header__free_unpacked(hdr, NULL); - return -1; - } - /* Payload len */ - stream_putw(*s, sizeof(struct mlag_mroute_del)); - /* No Batching */ - stream_putw(*s, MLAG_MSG_NO_BATCH); - /* Actual Data */ - stream_put(*s, msg->vrf_name, VRF_NAMSIZ); - - stream_putl(*s, msg->source_ip); - stream_putl(*s, msg->group_ip); - stream_putl(*s, msg->group_ip); - stream_putl(*s, msg->owner_id); - stream_putl(*s, msg->vrf_id); - if (msg->owner_id == MLAG_OWNER_INTERFACE) - stream_put(*s, msg->intf_name, - INTERFACE_NAMSIZ); - else - stream_put(*s, NULL, INTERFACE_NAMSIZ); - zebra_mlag_mroute_del__free_unpacked(msg, NULL); - } break; - case ZEBRA_MLAG__HEADER__MESSAGE_TYPE__ZEBRA_MLAG_MROUTE_ADD_BULK: { - ZebraMlagMrouteAddBulk *Bulk_msg = NULL; - ZebraMlagMrouteAdd *msg = NULL; - size_t i = 0; - - Bulk_msg = zebra_mlag_mroute_add_bulk__unpack( - NULL, hdr->data.len, hdr->data.data); - if (Bulk_msg == NULL) { - zebra_mlag__header__free_unpacked(hdr, NULL); - return -1; - } - /* Payload len */ - stream_putw(*s, (Bulk_msg->n_mroute_add - * sizeof(struct mlag_mroute_add))); - /* No. of msgs in Batch */ - stream_putw(*s, Bulk_msg->n_mroute_add); - - /* Actual Data */ - for (i = 0; i < Bulk_msg->n_mroute_add; i++) { - - msg = Bulk_msg->mroute_add[i]; - - stream_put(*s, msg->vrf_name, VRF_NAMSIZ); - stream_putl(*s, msg->source_ip); - stream_putl(*s, msg->group_ip); - stream_putl(*s, msg->cost_to_rp); - stream_putl(*s, msg->owner_id); - stream_putc(*s, msg->am_i_dr); - stream_putc(*s, msg->am_i_dual_active); - stream_putl(*s, msg->vrf_id); - if (msg->owner_id == MLAG_OWNER_INTERFACE) - stream_put(*s, msg->intf_name, - INTERFACE_NAMSIZ); - else - stream_put(*s, NULL, INTERFACE_NAMSIZ); - } - zebra_mlag_mroute_add_bulk__free_unpacked(Bulk_msg, - NULL); - } break; - case ZEBRA_MLAG__HEADER__MESSAGE_TYPE__ZEBRA_MLAG_MROUTE_DEL_BULK: { - ZebraMlagMrouteDelBulk *Bulk_msg = NULL; - ZebraMlagMrouteDel *msg = NULL; - size_t i = 0; - - Bulk_msg = zebra_mlag_mroute_del_bulk__unpack( - NULL, hdr->data.len, hdr->data.data); - if (Bulk_msg == NULL) { - zebra_mlag__header__free_unpacked(hdr, NULL); - return -1; - } - /* Payload len */ - stream_putw(*s, (Bulk_msg->n_mroute_del - * sizeof(struct mlag_mroute_del))); - /* No. of msgs in Batch */ - stream_putw(*s, Bulk_msg->n_mroute_del); - - /* Actual Data */ - for (i = 0; i < Bulk_msg->n_mroute_del; i++) { - - msg = Bulk_msg->mroute_del[i]; - - stream_put(*s, msg->vrf_name, VRF_NAMSIZ); - stream_putl(*s, msg->source_ip); - stream_putl(*s, msg->group_ip); - stream_putl(*s, msg->owner_id); - stream_putl(*s, msg->vrf_id); - if (msg->owner_id == MLAG_OWNER_INTERFACE) - stream_put(*s, msg->intf_name, - INTERFACE_NAMSIZ); - else - stream_put(*s, NULL, INTERFACE_NAMSIZ); - } - zebra_mlag_mroute_del_bulk__free_unpacked(Bulk_msg, - NULL); - } break; - case ZEBRA_MLAG__HEADER__MESSAGE_TYPE__ZEBRA_MLAG_ZEBRA_STATUS_UPDATE: { - ZebraMlagZebraStatusUpdate *msg = NULL; - - msg = zebra_mlag_zebra_status_update__unpack( - NULL, hdr->data.len, hdr->data.data); - if (msg == NULL) { - zebra_mlag__header__free_unpacked(hdr, NULL); - return -1; - } - /* Payload len */ - stream_putw(*s, sizeof(struct mlag_frr_status)); - /* No Batching */ - stream_putw(*s, MLAG_MSG_NO_BATCH); - /* Actual Data */ - stream_putl(*s, msg->peer_frrstate); - zebra_mlag_zebra_status_update__free_unpacked(msg, - NULL); - } break; - default: - break; - } - } - zebra_mlag__header__free_unpacked(hdr, NULL); - return msg_type; -} - -#else -int zebra_mlag_protobuf_encode_client_data(struct stream *s, uint32_t *msg_type) -{ - return 0; -} - -int zebra_mlag_protobuf_decode_message(struct stream **s, uint8_t *data, - uint32_t len) -{ - return 0; -} -#endif diff --git a/zebra/zebra_mlag.h b/zebra/zebra_mlag.h index 015c94bf5..90a5a41fa 100644 --- a/zebra/zebra_mlag.h +++ b/zebra/zebra_mlag.h @@ -1,5 +1,5 @@ /* Zebra mlag header. - * Copyright (C) 2019 Cumulus Networks, Inc. + * Copyright (C) 2018 Cumulus Networks, Inc. * Donald Sharp * * This file is part of FRR. @@ -23,55 +23,18 @@ #define __ZEBRA_MLAG_H__ #include "mlag.h" -#include "zclient.h" -#include "zebra/zserv.h" -#ifdef HAVE_PROTOBUF -#include "mlag/mlag.pb-c.h" +#ifdef __cplusplus +extern "C" { #endif -#define ZEBRA_MLAG_BUF_LIMIT 2048 -#define ZEBRA_MLAG_LEN_SIZE 4 - -extern uint8_t mlag_wr_buffer[ZEBRA_MLAG_BUF_LIMIT]; -extern uint8_t mlag_rd_buffer[ZEBRA_MLAG_BUF_LIMIT]; -extern uint32_t mlag_rd_buf_offset; - -static inline void zebra_mlag_reset_read_buffer(void) -{ - mlag_rd_buf_offset = 0; -} - -enum zebra_mlag_state { - MLAG_UP = 1, - MLAG_DOWN = 2, -}; - void zebra_mlag_init(void); void zebra_mlag_terminate(void); enum mlag_role zebra_mlag_get_role(void); -void zebra_mlag_client_register(ZAPI_HANDLER_ARGS); - -void zebra_mlag_client_unregister(ZAPI_HANDLER_ARGS); - -void zebra_mlag_forward_client_msg(ZAPI_HANDLER_ARGS); - -void zebra_mlag_send_register(void); - -void zebra_mlag_send_deregister(void); - -void zebra_mlag_handle_process_state(enum zebra_mlag_state state); - -void zebra_mlag_process_mlag_data(uint8_t *data, uint32_t len); - -/* - * ProtoBuffer Api's - */ -int zebra_mlag_protobuf_encode_client_data(struct stream *s, - uint32_t *msg_type); -int zebra_mlag_protobuf_decode_message(struct stream **s, uint8_t *data, - uint32_t len); +#ifdef __cplusplus +} +#endif #endif diff --git a/zebra/zebra_mlag_private.c b/zebra/zebra_mlag_private.c deleted file mode 100644 index 896e78ca0..000000000 --- a/zebra/zebra_mlag_private.c +++ /dev/null @@ -1,302 +0,0 @@ -/* Zebra Mlag Code. - * Copyright (C) 2019 Cumulus Networks, Inc. - * Donald Sharp - * - * This file is part of FRR. - * - * FRR is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * FRR is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with FRR; see the file COPYING. If not, write to the Free - * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ -#include "zebra.h" - -#include "hook.h" -#include "module.h" -#include "thread.h" -#include "libfrr.h" -#include "version.h" -#include "network.h" - -#include "lib/stream.h" - -#include "zebra/debug.h" -#include "zebra/zebra_router.h" -#include "zebra/zebra_mlag.h" -#include "zebra/zebra_mlag_private.h" - -#include <sys/un.h> - - -/* - * This file will have platform specific apis to communicate with MCLAG. - * - */ - -#ifdef HAVE_CUMULUS - -static struct thread_master *zmlag_master; -static int mlag_socket; - -static int zebra_mlag_connect(struct thread *thread); -static int zebra_mlag_read(struct thread *thread); - -/* - * Write teh data to MLAGD - */ -int zebra_mlag_private_write_data(uint8_t *data, uint32_t len) -{ - int rc = 0; - - if (IS_ZEBRA_DEBUG_MLAG) { - zlog_debug("%s: Writing %d length Data to clag", __func__, len); - zlog_hexdump(data, len); - } - rc = write(mlag_socket, data, len); - return rc; -} - -static void zebra_mlag_sched_read(void) -{ - pthread_mutex_lock(&zrouter.mlag_info.mlag_th_mtx); - thread_add_read(zmlag_master, zebra_mlag_read, NULL, mlag_socket, - &zrouter.mlag_info.t_read); - pthread_mutex_unlock(&zrouter.mlag_info.mlag_th_mtx); -} - -static int zebra_mlag_read(struct thread *thread) -{ - uint32_t *msglen; - uint32_t h_msglen; - uint32_t tot_len, curr_len = mlag_rd_buf_offset; - - pthread_mutex_lock(&zrouter.mlag_info.mlag_th_mtx); - zrouter.mlag_info.t_read = NULL; - pthread_mutex_unlock(&zrouter.mlag_info.mlag_th_mtx); - - /* - * Received message in sock_stream looks like below - * | len-1 (4 Bytes) | payload-1 (len-1) | - * len-2 (4 Bytes) | payload-2 (len-2) | .. - * - * Idea is read one message completely, then process, until message is - * read completely, keep on reading from the socket - */ - if (curr_len < ZEBRA_MLAG_LEN_SIZE) { - ssize_t data_len; - - data_len = read(mlag_socket, mlag_rd_buffer + curr_len, - ZEBRA_MLAG_LEN_SIZE - curr_len); - if (data_len == 0 || data_len == -1) { - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("MLAG connection closed socket : %d", - mlag_socket); - close(mlag_socket); - zebra_mlag_handle_process_state(MLAG_DOWN); - return -1; - } - if (data_len != (ssize_t)ZEBRA_MLAG_LEN_SIZE - curr_len) { - /* Try again later */ - zebra_mlag_sched_read(); - return 0; - } - curr_len = ZEBRA_MLAG_LEN_SIZE; - } - - /* Get the actual packet length */ - msglen = (uint32_t *)mlag_rd_buffer; - h_msglen = ntohl(*msglen); - - /* This will be the actual length of the packet */ - tot_len = h_msglen + ZEBRA_MLAG_LEN_SIZE; - - if (curr_len < tot_len) { - ssize_t data_len; - - data_len = read(mlag_socket, mlag_rd_buffer + curr_len, - tot_len - curr_len); - if (data_len == 0 || data_len == -1) { - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("MLAG connection closed socket : %d", - mlag_socket); - close(mlag_socket); - zebra_mlag_handle_process_state(MLAG_DOWN); - return -1; - } - if (data_len != (ssize_t)tot_len - curr_len) { - /* Try again later */ - zebra_mlag_sched_read(); - return 0; - } - } - - if (IS_ZEBRA_DEBUG_MLAG) { - zlog_debug("Received a MLAG Message from socket: %d, len:%u ", - mlag_socket, tot_len); - zlog_hexdump(mlag_rd_buffer, tot_len); - } - - tot_len -= ZEBRA_MLAG_LEN_SIZE; - - /* Process the packet */ - zebra_mlag_process_mlag_data(mlag_rd_buffer + ZEBRA_MLAG_LEN_SIZE, - tot_len); - - /* Register read thread. */ - zebra_mlag_reset_read_buffer(); - zebra_mlag_sched_read(); - return 0; -} - -static int zebra_mlag_connect(struct thread *thread) -{ - struct sockaddr_un svr; - struct ucred ucred; - socklen_t len = 0; - - /* Reset the Timer-running flag */ - zrouter.mlag_info.timer_running = false; - - zrouter.mlag_info.t_read = NULL; - memset(&svr, 0, sizeof(svr)); - svr.sun_family = AF_UNIX; -#define MLAG_SOCK_NAME "/var/run/clag-zebra.socket" - strlcpy(svr.sun_path, MLAG_SOCK_NAME, sizeof(MLAG_SOCK_NAME) + 1); - - mlag_socket = socket(svr.sun_family, SOCK_STREAM, 0); - if (mlag_socket < 0) - return -1; - - if (connect(mlag_socket, (struct sockaddr *)&svr, sizeof(svr)) == -1) { - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug( - "Unable to connect to %s try again in 10 secs", - svr.sun_path); - close(mlag_socket); - zrouter.mlag_info.timer_running = true; - thread_add_timer(zmlag_master, zebra_mlag_connect, NULL, 10, - &zrouter.mlag_info.t_read); - return 0; - } - len = sizeof(struct ucred); - ucred.pid = getpid(); - - set_nonblocking(mlag_socket); - setsockopt(mlag_socket, SOL_SOCKET, SO_PEERCRED, &ucred, len); - - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: Connection with MLAG is established ", - __func__); - - thread_add_read(zmlag_master, zebra_mlag_read, NULL, mlag_socket, - &zrouter.mlag_info.t_read); - /* - * Connection is established with MLAGD, post to clients - */ - zebra_mlag_handle_process_state(MLAG_UP); - return 0; -} - -/* - * Currently we are doing polling later we will look for better options - */ -void zebra_mlag_private_monitor_state(void) -{ - thread_add_event(zmlag_master, zebra_mlag_connect, NULL, 0, - &zrouter.mlag_info.t_read); -} - -int zebra_mlag_private_open_channel(void) -{ - zmlag_master = zrouter.mlag_info.th_master; - - if (zrouter.mlag_info.connected == true) { - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: Zebra already connected to MLAGD", - __func__); - return 0; - } - - if (zrouter.mlag_info.timer_running == true) { - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug( - "%s: Connection retry is in progress for MLAGD", - __func__); - return 0; - } - - if (zrouter.mlag_info.clients_interested_cnt) { - /* - * Connect only if any clients are showing interest - */ - thread_add_event(zmlag_master, zebra_mlag_connect, NULL, 0, - &zrouter.mlag_info.t_read); - } - return 0; -} - -int zebra_mlag_private_close_channel(void) -{ - if (zmlag_master == NULL) - return -1; - - if (zrouter.mlag_info.clients_interested_cnt) { - if (IS_ZEBRA_DEBUG_MLAG) - zlog_debug("%s: still %d clients are connected, skip", - __func__, - zrouter.mlag_info.clients_interested_cnt); - return -1; - } - - /* - * Post the De-register to MLAG, so that it can do necesasry cleanup - */ - zebra_mlag_send_deregister(); - - return 0; -} - -void zebra_mlag_private_cleanup_data(void) -{ - zmlag_master = NULL; - zrouter.mlag_info.connected = false; - zrouter.mlag_info.timer_running = false; - - close(mlag_socket); -} - -#else /*HAVE_CUMULUS */ - -int zebra_mlag_private_write_data(uint8_t *data, uint32_t len) -{ - return 0; -} - -void zebra_mlag_private_monitor_state(void) -{ -} - -int zebra_mlag_private_open_channel(void) -{ - return 0; -} - -int zebra_mlag_private_close_channel(void) -{ - return 0; -} - -void zebra_mlag_private_cleanup_data(void) -{ -} -#endif /*HAVE_CUMULUS*/ diff --git a/zebra/zebra_mlag_private.h b/zebra/zebra_mlag_private.h deleted file mode 100644 index 2ae7e3932..000000000 --- a/zebra/zebra_mlag_private.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Zebra mlag header. - * Copyright (C) 2019 Cumulus Networks, Inc. - * Donald Sharp - * - * This file is part of FRR. - * - * FRR is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * FRR is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with FRR; see the file COPYING. If not, write to the Free - * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ -#ifndef __ZEBRA_MLAG_PRIVATE_H__ -#define __ZEBRA_MLAG_PRIVATE_H__ - - -/* - * all the platform specific API's - */ - -int zebra_mlag_private_open_channel(void); - -int zebra_mlag_private_close_channel(void); - -void zebra_mlag_private_monitor_state(void); - -int zebra_mlag_private_write_data(uint8_t *data, uint32_t len); - -void zebra_mlag_private_cleanup_data(void); - -#endif diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h index 1f8056198..25a7adac1 100644 --- a/zebra/zebra_router.h +++ b/zebra/zebra_router.h @@ -71,36 +71,6 @@ struct zebra_mlag_info { /* The system mac being used */ struct ethaddr mac; - /* - * Zebra will open the communication channel with MLAGD only if any - * clients are interested and it is controlled dynamically based on - * client registers & un-registers. - */ - uint32_t clients_interested_cnt; - - /* coomunication channel with MLAGD is established */ - bool connected; - - /* connection retry timer is running */ - bool timer_running; - - /* Holds the client data(unencoded) that need to be pushed to MCLAGD*/ - struct stream_fifo *mlag_fifo; - - /* - * A new Kernel thread will be created to post the data to MCLAGD. - * where as, read will be performed from the zebra main thread, because - * read involves accessing client registartion data structures. - */ - struct frr_pthread *zebra_pth_mlag; - - /* MLAG Thread context 'master' */ - struct thread_master *th_master; - - /* Threads for read/write. */ - struct thread *t_read; - struct thread *t_write; - pthread_mutex_t mlag_th_mtx; }; struct zebra_router { diff --git a/zebra/zserv.h b/zebra/zserv.h index ccc8d92aa..708ff1e22 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -99,13 +99,6 @@ struct zserv { uint8_t proto; uint16_t instance; - /* - * Interested for MLAG Updates, and also stores the client - * interested message mask - */ - bool mlag_updates_interested; - uint32_t mlag_reg_mask1; - /* Statistics */ uint32_t redist_v4_add_cnt; uint32_t redist_v4_del_cnt; |