summaryrefslogtreecommitdiffstats
path: root/zebra/zebra_mlag.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_mlag.c')
-rw-r--r--zebra/zebra_mlag.c565
1 files changed, 536 insertions, 29 deletions
diff --git a/zebra/zebra_mlag.c b/zebra/zebra_mlag.c
index 4d1b7712c..1cbe54b17 100644
--- a/zebra/zebra_mlag.c
+++ b/zebra/zebra_mlag.c
@@ -108,7 +108,7 @@ void zebra_mlag_process_mlag_data(uint8_t *data, uint32_t len)
int msg_type = 0;
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
- msg_type = zebra_mlag_protobuf_decode_message(&s, data, len);
+ msg_type = zebra_mlag_protobuf_decode_message(s, data, len);
if (msg_type <= 0) {
/* Something went wrong in decoding */
@@ -148,6 +148,7 @@ static int zebra_mlag_client_msg_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);
@@ -155,12 +156,9 @@ static int zebra_mlag_client_msg_handler(struct thread *event)
zlog_debug(":%s: Processing MLAG write, %d messages in queue",
__func__, wr_count);
- zrouter.mlag_info.t_write = NULL;
- for (wr_count = 0; wr_count < ZEBRA_MLAG_POST_LIMIT; wr_count++) {
- /* FIFO is empty,wait for teh message to be add */
- if (stream_fifo_count_safe(zrouter.mlag_info.mlag_fifo) == 0)
- break;
+ 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",
@@ -168,7 +166,6 @@ static int zebra_mlag_client_msg_handler(struct thread *event)
break;
}
- zebra_mlag_reset_write_buffer();
/*
* Encode the data now
*/
@@ -177,17 +174,19 @@ static int zebra_mlag_client_msg_handler(struct thread *event)
/*
* write to MCLAGD
*/
- if (len > 0)
+ if (len > 0) {
zebra_mlag_private_write_data(mlag_wr_buffer, len);
- /*
- * If message type is De-register, send a signal to main thread,
- * so that 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);
+ /*
+ * If message type is De-register, send a signal to main
+ * thread, so that 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);
@@ -241,12 +240,15 @@ void zebra_mlag_handle_process_state(enum zebra_mlag_state state)
*/
static int zebra_mlag_signal_write_thread(void)
{
- 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_client_msg_handler, NULL, 0,
- &zrouter.mlag_info.t_write);
+ frr_with_mutex (&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_client_msg_handler, NULL, 0,
+ &zrouter.mlag_info.t_write);
+ }
}
return 0;
}
@@ -375,7 +377,7 @@ static void zebra_mlag_spawn_pthread(void)
zrouter.mlag_info.th_master = zrouter.mlag_info.zebra_pth_mlag->master;
- /* Enqueue an initial event for the dataplane pthread */
+ /* 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);
@@ -583,7 +585,7 @@ DEFUN_HIDDEN (show_mlag,
ZEBRA_STR
"The mlag role on this machine\n")
{
- char buf[80];
+ char buf[MLAG_ROLE_STRSIZE];
vty_out(vty, "MLag is configured to: %s\n",
mlag_role2str(zrouter.mlag_info.role, buf, sizeof(buf)));
@@ -600,7 +602,7 @@ DEFPY(test_mlag, test_mlag_cmd,
"Mlag is setup to be the secondary\n")
{
enum mlag_role orig = zrouter.mlag_info.role;
- char buf1[80], buf2[80];
+ char buf1[MLAG_ROLE_STRSIZE], buf2[MLAG_ROLE_STRSIZE];
if (none)
zrouter.mlag_info.role = MLAG_ROLE_NONE;
@@ -619,8 +621,12 @@ DEFPY(test_mlag, test_mlag_cmd,
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();
+ frr_with_mutex (
+ &zrouter.mlag_info.mlag_th_mtx) {
+ 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();
@@ -655,8 +661,8 @@ void zebra_mlag_init(void)
zrouter.mlag_info.t_read = NULL;
zrouter.mlag_info.t_write = NULL;
test_mlag_in_progress = false;
- zebra_mlag_reset_write_buffer();
zebra_mlag_reset_read_buffer();
+ pthread_mutex_init(&zrouter.mlag_info.mlag_th_mtx, NULL);
}
void zebra_mlag_terminate(void)
@@ -669,13 +675,514 @@ 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[ZLOG_FILTER_LENGTH_MAX];
+
+ 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;
+ bool cleanup = false;
+
+ Bulk_msg.n_mroute_add = mlag_msg.msg_cnt;
+ pay_load = XMALLOC(MTYPE_MLAG_PBUF, sizeof(ZebraMlagMrouteAdd *)
+ * mlag_msg.msg_cnt);
+
+ 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;
+ bool cleanup = false;
+
+ Bulk_msg.n_mroute_del = mlag_msg.msg_cnt;
+ pay_load = XMALLOC(MTYPE_MLAG_PBUF, sizeof(ZebraMlagMrouteDel *)
+ * mlag_msg.msg_cnt);
+
+ 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) {
+ 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)
+ 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
+ * messages are posted inside a single Buffer.
+ * 2 -solutions exist to solve this
+ * 1. add Unenoced length at the beginning of every message, this will
+ * be used to point to next message 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);
+
+ return len;
+}
+
+int zebra_mlag_protobuf_decode_message(struct stream *s, uint8_t *data,
+ uint32_t len)
+{
+ uint32_t msg_type;
+ ZebraMlagHeader *hdr;
+ char buf[80];
+
+ 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, 80));
+
+ /*
+ * 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;
+
+ 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;
+
+ 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,
+int zebra_mlag_protobuf_decode_message(struct stream *s, uint8_t *data,
uint32_t len)
{
return 0;
}
+#endif