pimd: Add accidently missed code during upstreaming process

There was some code missed during the upstreaming process
due to code squash.  Identify and put into a commit
to keep code consistent and correct.

Signed-off-by: Satheesh Kumar K <sathk@cumulusnetworks.com>
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2020-02-19 09:52:17 -05:00
parent a054f6d73e
commit 17823cdd2c
12 changed files with 396 additions and 146 deletions

View File

@ -909,7 +909,7 @@ static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty)
static void pim_show_interfaces_single(struct pim_instance *pim,
struct vty *vty, const char *ifname,
bool uj)
bool mlag, bool uj)
{
struct in_addr ifaddr;
struct interface *ifp;
@ -952,6 +952,9 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
if (!pim_ifp)
continue;
if (mlag == true && pim_ifp->activeactive == false)
continue;
if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
continue;
@ -1380,7 +1383,7 @@ static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
}
static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
bool uj)
bool mlag, bool uj)
{
struct interface *ifp;
struct pim_interface *pim_ifp;
@ -1400,6 +1403,9 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
if (!pim_ifp)
continue;
if (mlag == true && pim_ifp->activeactive == false)
continue;
pim_nbrs = pim_ifp->pim_neighbor_list->count;
pim_ifchannels = pim_if_ifchannel_count(pim_ifp);
fhr = 0;
@ -4295,6 +4301,113 @@ DEFUN (show_ip_igmp_statistics,
return CMD_SUCCESS;
}
DEFUN (show_ip_pim_mlag_summary,
show_ip_pim_mlag_summary_cmd,
"show ip pim mlag summary [json]",
SHOW_STR
IP_STR
PIM_STR
"MLAG\n"
"status and stats\n"
JSON_STR)
{
bool uj = use_json(argc, argv);
char role_buf[MLAG_ROLE_STRSIZE];
char addr_buf[INET_ADDRSTRLEN];
if (uj) {
json_object *json = NULL;
json_object *json_stat = NULL;
json = json_object_new_object();
if (router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)
json_object_boolean_true_add(json, "mlagConnUp");
if (router->mlag_flags & PIM_MLAGF_PEER_CONN_UP)
json_object_boolean_true_add(json, "mlagPeerConnUp");
if (router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)
json_object_boolean_true_add(json, "mlagPeerZebraUp");
json_object_string_add(json, "mlagRole",
mlag_role2str(router->mlag_role,
role_buf, sizeof(role_buf)));
inet_ntop(AF_INET, &router->local_vtep_ip,
addr_buf, INET_ADDRSTRLEN);
json_object_string_add(json, "localVtepIp", addr_buf);
inet_ntop(AF_INET, &router->anycast_vtep_ip,
addr_buf, INET_ADDRSTRLEN);
json_object_string_add(json, "anycastVtepIp", addr_buf);
json_object_string_add(json, "peerlinkRif",
router->peerlink_rif);
json_stat = json_object_new_object();
json_object_int_add(json_stat, "mlagConnFlaps",
router->mlag_stats.mlagd_session_downs);
json_object_int_add(json_stat, "mlagPeerConnFlaps",
router->mlag_stats.peer_session_downs);
json_object_int_add(json_stat, "mlagPeerZebraFlaps",
router->mlag_stats.peer_zebra_downs);
json_object_int_add(json_stat, "mrouteAddRx",
router->mlag_stats.msg.mroute_add_rx);
json_object_int_add(json_stat, "mrouteAddTx",
router->mlag_stats.msg.mroute_add_tx);
json_object_int_add(json_stat, "mrouteDelRx",
router->mlag_stats.msg.mroute_del_rx);
json_object_int_add(json_stat, "mrouteDelTx",
router->mlag_stats.msg.mroute_del_tx);
json_object_int_add(json_stat, "mlagStatusUpdates",
router->mlag_stats.msg.mlag_status_updates);
json_object_int_add(json_stat, "peerZebraStatusUpdates",
router->mlag_stats.msg.peer_zebra_status_updates);
json_object_int_add(json_stat, "pimStatusUpdates",
router->mlag_stats.msg.pim_status_updates);
json_object_int_add(json_stat, "vxlanUpdates",
router->mlag_stats.msg.vxlan_updates);
json_object_object_add(json, "connStats", json_stat);
vty_out(vty, "%s\n", json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json);
return CMD_SUCCESS;
}
vty_out(vty, "MLAG daemon connection: %s\n",
(router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)
? "up" : "down");
vty_out(vty, "MLAG peer state: %s\n",
(router->mlag_flags & PIM_MLAGF_PEER_CONN_UP)
? "up" : "down");
vty_out(vty, "Zebra peer state: %s\n",
(router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)
? "up" : "down");
vty_out(vty, "MLAG role: %s\n",
mlag_role2str(router->mlag_role, role_buf, sizeof(role_buf)));
inet_ntop(AF_INET, &router->local_vtep_ip,
addr_buf, INET_ADDRSTRLEN);
vty_out(vty, "Local VTEP IP: %s\n", addr_buf);
inet_ntop(AF_INET, &router->anycast_vtep_ip,
addr_buf, INET_ADDRSTRLEN);
vty_out(vty, "Anycast VTEP IP: %s\n", addr_buf);
vty_out(vty, "Peerlink: %s\n", router->peerlink_rif);
vty_out(vty, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
router->mlag_stats.mlagd_session_downs,
router->mlag_stats.peer_session_downs,
router->mlag_stats.peer_zebra_downs);
vty_out(vty, "Message Statistics:\n");
vty_out(vty, " mroute adds: rx: %d, tx: %d\n",
router->mlag_stats.msg.mroute_add_rx,
router->mlag_stats.msg.mroute_add_tx);
vty_out(vty, " mroute dels: rx: %d, tx: %d\n",
router->mlag_stats.msg.mroute_del_rx,
router->mlag_stats.msg.mroute_del_tx);
vty_out(vty, " peer zebra status updates: %d\n",
router->mlag_stats.msg.peer_zebra_status_updates);
vty_out(vty, " PIM status updates: %d\n",
router->mlag_stats.msg.pim_status_updates);
vty_out(vty, " VxLAN updates: %d\n",
router->mlag_stats.msg.vxlan_updates);
return CMD_SUCCESS;
}
DEFUN (show_ip_pim_assert,
show_ip_pim_assert_cmd,
"show ip pim [vrf NAME] assert",
@ -4377,10 +4490,11 @@ DEFUN (show_ip_pim_assert_winner_metric,
DEFUN (show_ip_pim_interface,
show_ip_pim_interface_cmd,
"show ip pim [vrf NAME] interface [detail|WORD] [json]",
"show ip pim [mlag] [vrf NAME] interface [detail|WORD] [json]",
SHOW_STR
IP_STR
PIM_STR
"MLAG\n"
VRF_CMD_HELP_STR
"PIM interface information\n"
"Detailed output\n"
@ -4390,36 +4504,47 @@ DEFUN (show_ip_pim_interface,
int idx = 2;
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
bool uj = use_json(argc, argv);
bool mlag = false;
if (!vrf)
return CMD_WARNING;
if (argv_find(argv, argc, "mlag", &idx))
mlag = true;
if (argv_find(argv, argc, "WORD", &idx)
|| argv_find(argv, argc, "detail", &idx))
pim_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
pim_show_interfaces_single(vrf->info, vty, argv[idx]->arg, mlag,
uj);
else
pim_show_interfaces(vrf->info, vty, uj);
pim_show_interfaces(vrf->info, vty, mlag, uj);
return CMD_SUCCESS;
}
DEFUN (show_ip_pim_interface_vrf_all,
show_ip_pim_interface_vrf_all_cmd,
"show ip pim vrf all interface [detail|WORD] [json]",
"show ip pim [mlag] vrf all interface [detail|WORD] [json]",
SHOW_STR
IP_STR
PIM_STR
"MLAG\n"
VRF_CMD_HELP_STR
"PIM interface information\n"
"Detailed output\n"
"interface name\n"
JSON_STR)
{
int idx = 6;
int idx = 2;
bool uj = use_json(argc, argv);
struct vrf *vrf;
bool first = true;
bool mlag = false;
if (argv_find(argv, argc, "mlag", &idx))
mlag = true;
idx = 6;
if (uj)
vty_out(vty, "{ ");
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
@ -4433,9 +4558,9 @@ DEFUN (show_ip_pim_interface_vrf_all,
if (argv_find(argv, argc, "WORD", &idx)
|| argv_find(argv, argc, "detail", &idx))
pim_show_interfaces_single(vrf->info, vty,
argv[idx]->arg, uj);
argv[idx]->arg, mlag, uj);
else
pim_show_interfaces(vrf->info, vty, uj);
pim_show_interfaces(vrf->info, vty, mlag, uj);
}
if (uj)
vty_out(vty, "}\n");
@ -4625,113 +4750,6 @@ DEFUN (show_ip_pim_local_membership,
return CMD_SUCCESS;
}
DEFUN (show_ip_pim_mlag_summary,
show_ip_pim_mlag_summary_cmd,
"show ip pim mlag summary [json]",
SHOW_STR
IP_STR
PIM_STR
"MLAG\n"
"status and stats\n"
JSON_STR)
{
bool uj = use_json(argc, argv);
char role_buf[MLAG_ROLE_STRSIZE];
char addr_buf[INET_ADDRSTRLEN];
if (uj) {
json_object *json = NULL;
json_object *json_stat = NULL;
json = json_object_new_object();
if (router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)
json_object_boolean_true_add(json, "mlagConnUp");
if (router->mlag_flags & PIM_MLAGF_PEER_CONN_UP)
json_object_boolean_true_add(json, "mlagPeerConnUp");
if (router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)
json_object_boolean_true_add(json, "mlagPeerZebraUp");
json_object_string_add(json, "mlagRole",
mlag_role2str(router->mlag_role,
role_buf, sizeof(role_buf)));
inet_ntop(AF_INET, &router->local_vtep_ip,
addr_buf, INET_ADDRSTRLEN);
json_object_string_add(json, "localVtepIp", addr_buf);
inet_ntop(AF_INET, &router->anycast_vtep_ip,
addr_buf, INET_ADDRSTRLEN);
json_object_string_add(json, "anycastVtepIp", addr_buf);
json_object_string_add(json, "peerlinkRif",
router->peerlink_rif);
json_stat = json_object_new_object();
json_object_int_add(json_stat, "mlagConnFlaps",
router->mlag_stats.mlagd_session_downs);
json_object_int_add(json_stat, "mlagPeerConnFlaps",
router->mlag_stats.peer_session_downs);
json_object_int_add(json_stat, "mlagPeerZebraFlaps",
router->mlag_stats.peer_zebra_downs);
json_object_int_add(json_stat, "mrouteAddRx",
router->mlag_stats.msg.mroute_add_rx);
json_object_int_add(json_stat, "mrouteAddTx",
router->mlag_stats.msg.mroute_add_tx);
json_object_int_add(json_stat, "mrouteDelRx",
router->mlag_stats.msg.mroute_del_rx);
json_object_int_add(json_stat, "mrouteDelTx",
router->mlag_stats.msg.mroute_del_tx);
json_object_int_add(json_stat, "mlagStatusUpdates",
router->mlag_stats.msg.mlag_status_updates);
json_object_int_add(json_stat, "peerZebraStatusUpdates",
router->mlag_stats.msg.peer_zebra_status_updates);
json_object_int_add(json_stat, "pimStatusUpdates",
router->mlag_stats.msg.pim_status_updates);
json_object_int_add(json_stat, "vxlanUpdates",
router->mlag_stats.msg.vxlan_updates);
json_object_object_add(json, "connStats", json_stat);
vty_out(vty, "%s\n", json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json);
return CMD_SUCCESS;
}
vty_out(vty, "MLAG daemon connection: %s\n",
(router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)
? "up" : "down");
vty_out(vty, "MLAG peer state: %s\n",
(router->mlag_flags & PIM_MLAGF_PEER_CONN_UP)
? "up" : "down");
vty_out(vty, "Zebra peer state: %s\n",
(router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)
? "up" : "down");
vty_out(vty, "MLAG role: %s\n",
mlag_role2str(router->mlag_role, role_buf, sizeof(role_buf)));
inet_ntop(AF_INET, &router->local_vtep_ip,
addr_buf, INET_ADDRSTRLEN);
vty_out(vty, "Local VTEP IP: %s\n", addr_buf);
inet_ntop(AF_INET, &router->anycast_vtep_ip,
addr_buf, INET_ADDRSTRLEN);
vty_out(vty, "Anycast VTEP IP: %s\n", addr_buf);
vty_out(vty, "Peerlink: %s\n", router->peerlink_rif);
vty_out(vty, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
router->mlag_stats.mlagd_session_downs,
router->mlag_stats.peer_session_downs,
router->mlag_stats.peer_zebra_downs);
vty_out(vty, "Message Statistics:\n");
vty_out(vty, " mroute adds: rx: %d, tx: %d\n",
router->mlag_stats.msg.mroute_add_rx,
router->mlag_stats.msg.mroute_add_tx);
vty_out(vty, " mroute dels: rx: %d, tx: %d\n",
router->mlag_stats.msg.mroute_del_rx,
router->mlag_stats.msg.mroute_del_tx);
vty_out(vty, " peer zebra status updates: %d\n",
router->mlag_stats.msg.peer_zebra_status_updates);
vty_out(vty, " PIM status updates: %d\n",
router->mlag_stats.msg.pim_status_updates);
vty_out(vty, " VxLAN updates: %d\n",
router->mlag_stats.msg.vxlan_updates);
return CMD_SUCCESS;
}
static void pim_show_mlag_up_entry_detail(struct vrf *vrf,
struct vty *vty, struct pim_upstream *up,
char *src_str, char *grp_str, json_object *json)
@ -8035,13 +8053,13 @@ DEFPY_HIDDEN (pim_test_sg_keepalive,
return CMD_SUCCESS;
}
DEFPY_HIDDEN (interface_ip_pim_activeactive,
interface_ip_pim_activeactive_cmd,
"[no$no] ip pim active-active",
NO_STR
IP_STR
PIM_STR
"Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
DEFPY (interface_ip_pim_activeactive,
interface_ip_pim_activeactive_cmd,
"[no$no] ip pim active-active",
NO_STR
IP_STR
PIM_STR
"Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct pim_interface *pim_ifp;
@ -8051,6 +8069,11 @@ DEFPY_HIDDEN (interface_ip_pim_activeactive,
return CMD_WARNING_CONFIG_FAILED;
}
if (PIM_DEBUG_MLAG)
zlog_debug("%sConfiguring PIM active-active on Interface: %s",
no ? "Un-":" ", ifp->name);
pim_ifp = ifp->info;
if (no)
pim_if_unconfigure_mlag_dualactive(pim_ifp);

View File

@ -1073,6 +1073,9 @@ int pim_ifchannel_local_membership_add(struct interface *ifp,
}
}
/* vxlan term mroutes use ipmr-lo as local member to
* pull down multicast vxlan tunnel traffic
*/
up_flags = is_vxlan ? PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM :
PIM_UPSTREAM_FLAG_MASK_SRC_IGMP;
ch = pim_ifchannel_add(ifp, sg, 0, up_flags);

View File

@ -312,14 +312,6 @@ static void pim_mlag_up_peer_del_all(void)
list_delete(&temp);
}
static int pim_mlag_signal_zpthread(void)
{
/* XXX - This is a temporary stub; the MLAG thread code is planned for
* a separate commit
*/
return (0);
}
/* Send upstream entry to the local MLAG daemon (which will subsequently
* send it to the peer MLAG switch).
*/
@ -872,7 +864,7 @@ static int pim_mlag_deregister_handler(struct thread *thread)
void pim_mlag_deregister(void)
{
/* if somebody still interested in the MLAG channel skip de-reg */
if (router->pim_mlag_intf_cnt)
if (router->pim_mlag_intf_cnt || pim_vxlan_do_mlag_reg())
return;
/* not registered; nothing do */
@ -890,10 +882,6 @@ void pim_if_configure_mlag_dualactive(struct pim_interface *pim_ifp)
if (!pim_ifp || !pim_ifp->pim || pim_ifp->activeactive == true)
return;
if (PIM_DEBUG_MLAG)
zlog_debug("%s: Configuring active-active on Interface: %s",
__func__, "NULL");
pim_ifp->activeactive = true;
if (pim_ifp->pim)
pim_ifp->pim->inst_mlag_intf_cnt++;
@ -919,10 +907,6 @@ void pim_if_unconfigure_mlag_dualactive(struct pim_interface *pim_ifp)
if (!pim_ifp || !pim_ifp->pim || pim_ifp->activeactive == false)
return;
if (PIM_DEBUG_MLAG)
zlog_debug("%s: UnConfiguring active-active on Interface: %s",
__func__, "NULL");
pim_ifp->activeactive = false;
pim_ifp->pim->inst_mlag_intf_cnt--;
@ -939,6 +923,7 @@ void pim_if_unconfigure_mlag_dualactive(struct pim_interface *pim_ifp)
* De-register to Zebra
*/
pim_mlag_deregister();
pim_mlag_param_reset();
}
}

View File

@ -37,6 +37,12 @@ extern void pim_mlag_deregister(void);
extern int pim_zebra_mlag_process_up(void);
extern int pim_zebra_mlag_process_down(void);
extern int pim_zebra_mlag_handle_msg(struct stream *msg, int len);
/* pm_zpthread.c */
extern int pim_mlag_signal_zpthread(void);
extern void pim_zpthread_init(void);
extern void pim_zpthread_terminate(void);
extern void pim_mlag_up_local_add(struct pim_instance *pim,
struct pim_upstream *upstream);
extern void pim_mlag_up_local_del(struct pim_instance *pim,

View File

@ -33,9 +33,6 @@
#include "pim_time.h"
#include "pim_vxlan.h"
// struct list *pim_channel_oil_list = NULL;
// struct hash *pim_channel_oil_hash = NULL;
static void pim_channel_update_mute(struct channel_oil *c_oil);
char *pim_channel_oil_dump(struct channel_oil *c_oil, char *buf, size_t size)
@ -174,7 +171,7 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
}
struct channel_oil *pim_channel_oil_del(struct channel_oil *c_oil,
const char *name)
const char *name)
{
if (PIM_DEBUG_MROUTE) {
struct prefix_sg sg = {.src = c_oil->oil.mfcc_mcastgrp,

View File

@ -130,7 +130,7 @@ void pim_channel_oil_change_iif(struct pim_instance *pim,
struct channel_oil *c_oil, int input_vif_index,
const char *name);
struct channel_oil *pim_channel_oil_del(struct channel_oil *c_oil,
const char *name);
const char *name);
int pim_channel_add_oif(struct channel_oil *c_oil, struct interface *oif,
uint32_t proto_mask, const char *caller);
@ -146,6 +146,6 @@ void pim_channel_update_oif_mute(struct channel_oil *c_oil,
void pim_channel_oil_upstream_deref(struct channel_oil *c_oil);
void pim_channel_del_inherited_oif(struct channel_oil *c_oil,
struct interface *oif, const char *caller);
struct interface *oif, const char *caller);
#endif /* PIM_OIL_H */

View File

@ -117,6 +117,11 @@ int pim_debug_config_write(struct vty *vty)
++writes;
}
if (PIM_DEBUG_MLAG) {
vty_out(vty, "debug pim mlag\n");
++writes;
}
if (PIM_DEBUG_BSM) {
vty_out(vty, "debug pim bsm\n");
++writes;

225
pimd/pim_zpthread.c Normal file
View File

@ -0,0 +1,225 @@
/*
* PIM for Quagga
* Copyright (C) 2008 Everton da Silva Marques
*
* This program 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 of the License, or
* (at your option) any later version.
*
* This program 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 this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
#include <lib/log.h>
#include <lib/lib_errors.h>
#include "pimd.h"
#include "pim_mlag.h"
#include "pim_zebra.h"
extern struct zclient *zclient;
#define PIM_MLAG_POST_LIMIT 100
int32_t mlag_bulk_cnt;
static void pim_mlag_zebra_fill_header(enum mlag_msg_type msg_type)
{
uint32_t fill_msg_type = msg_type;
uint16_t data_len;
uint16_t msg_cnt = 1;
if (msg_type == MLAG_MSG_NONE)
return;
switch (msg_type) {
case MLAG_REGISTER:
case MLAG_DEREGISTER:
data_len = sizeof(struct mlag_msg);
break;
case MLAG_MROUTE_ADD:
data_len = sizeof(struct mlag_mroute_add);
fill_msg_type = MLAG_MROUTE_ADD_BULK;
break;
case MLAG_MROUTE_DEL:
data_len = sizeof(struct mlag_mroute_del);
fill_msg_type = MLAG_MROUTE_DEL_BULK;
break;
default:
data_len = 0;
break;
}
stream_reset(router->mlag_stream);
/* ADD Hedaer */
stream_putl(router->mlag_stream, fill_msg_type);
/*
* In case of Bulk actual size & msg_cnt will be updated
* just before writing onto zebra
*/
stream_putw(router->mlag_stream, data_len);
stream_putw(router->mlag_stream, msg_cnt);
if (PIM_DEBUG_MLAG)
zlog_debug(":%s: msg_type: %d/%d len %d",
__func__, msg_type, fill_msg_type, data_len);
}
static void pim_mlag_zebra_flush_buffer(void)
{
uint32_t msg_type;
/* Stream had bulk messages update the Hedaer */
if (mlag_bulk_cnt > 1) {
/*
* No need to reset the pointer, below api reads from data[0]
*/
STREAM_GETL(router->mlag_stream, msg_type);
if (msg_type == MLAG_MROUTE_ADD_BULK) {
stream_putw_at(
router->mlag_stream, 4,
(mlag_bulk_cnt * sizeof(struct mlag_mroute_add)));
stream_putw_at(router->mlag_stream, 6, mlag_bulk_cnt);
} else if (msg_type == MLAG_MROUTE_DEL_BULK) {
stream_putw_at(
router->mlag_stream, 4,
(mlag_bulk_cnt * sizeof(struct mlag_mroute_del)));
stream_putw_at(router->mlag_stream, 6, mlag_bulk_cnt);
} else {
flog_err(EC_LIB_ZAPI_ENCODE,
"unknown bulk message type %d bulk_count %d",
msg_type, mlag_bulk_cnt);
stream_reset(router->mlag_stream);
mlag_bulk_cnt = 0;
return;
}
}
zclient_send_mlag_data(zclient, router->mlag_stream);
stream_failure:
stream_reset(router->mlag_stream);
mlag_bulk_cnt = 0;
}
/*
* Only ROUTE add & Delete will be bulked.
* Buffer will be flushed, when
* 1) there were no messages in the queue
* 2) Curr_msg_type != prev_msg_type
*/
static void pim_mlag_zebra_check_for_buffer_flush(uint32_t curr_msg_type,
uint32_t prev_msg_type)
{
/* First Message, keep bulking */
if (prev_msg_type == MLAG_MSG_NONE) {
mlag_bulk_cnt = 1;
return;
}
/*msg type is route add & delete, keep bulking */
if (curr_msg_type == prev_msg_type
&& (curr_msg_type == MLAG_MROUTE_ADD
|| curr_msg_type == MLAG_MROUTE_DEL)) {
mlag_bulk_cnt++;
return;
}
pim_mlag_zebra_flush_buffer();
}
/*
* Thsi thread reads the clients data from the Gloabl queue and encodes with
* protobuf and pass on to the MLAG socket.
*/
static int pim_mlag_zthread_handler(struct thread *event)
{
struct stream *read_s;
uint32_t wr_count = 0;
uint32_t prev_msg_type = MLAG_MSG_NONE;
uint32_t curr_msg_type = MLAG_MSG_NONE;
router->zpthread_mlag_write = NULL;
wr_count = stream_fifo_count_safe(router->mlag_fifo);
if (PIM_DEBUG_MLAG)
zlog_debug(":%s: Processing MLAG write, %d messages in queue",
__func__, wr_count);
if (wr_count == 0)
return 0;
for (wr_count = 0; wr_count < PIM_MLAG_POST_LIMIT; wr_count++) {
/* FIFO is empty,wait for teh message to be add */
if (stream_fifo_count_safe(router->mlag_fifo) == 0)
break;
read_s = stream_fifo_pop_safe(router->mlag_fifo);
if (!read_s) {
zlog_debug(":%s: Got a NULL Messages, some thing wrong",
__func__);
break;
}
STREAM_GETL(read_s, curr_msg_type);
/*
* Check for Buffer Overflow,
* MLAG Can't process more than 'PIM_MLAG_BUF_LIMIT' bytes
*/
if (router->mlag_stream->endp + read_s->endp + ZEBRA_HEADER_SIZE
> MLAG_BUF_LIMIT)
pim_mlag_zebra_flush_buffer();
pim_mlag_zebra_check_for_buffer_flush(curr_msg_type,
prev_msg_type);
/*
* First message to Buffer, fill the Header
*/
if (router->mlag_stream->endp == 0)
pim_mlag_zebra_fill_header(curr_msg_type);
/*
* add the data now
*/
stream_put(router->mlag_stream, read_s->data + read_s->getp,
read_s->endp - read_s->getp);
stream_free(read_s);
prev_msg_type = curr_msg_type;
}
stream_failure:
/*
* we are here , because
* 1. Queue might be empty
* 2. we crossed the max Q Read limit
* In any acse flush the buffer towards zebra
*/
pim_mlag_zebra_flush_buffer();
if (wr_count >= PIM_MLAG_POST_LIMIT)
pim_mlag_signal_zpthread();
return 0;
}
int pim_mlag_signal_zpthread(void)
{
if (router->master) {
if (PIM_DEBUG_MLAG)
zlog_debug(":%s: Scheduling PIM MLAG write Thread",
__func__);
thread_add_event(router->master, pim_mlag_zthread_handler, NULL,
0, &router->zpthread_mlag_write);
}
return (0);
}

View File

@ -102,6 +102,8 @@ void pim_router_init(void)
router->packet_process = PIM_DEFAULT_PACKET_PROCESS;
router->register_probe_time = PIM_REGISTER_PROBE_TIME_DEFAULT;
router->vrf_id = VRF_DEFAULT;
router->pim_mlag_intf_cnt = 0;
router->connected_to_mlag = false;
}
void pim_router_terminate(void)

View File

@ -63,6 +63,7 @@ pimd_libpim_a_SOURCES = \
pimd/pim_zebra.c \
pimd/pim_zlookup.c \
pimd/pim_vxlan.c \
pimd/pim_zpthread.c \
pimd/pimd.c \
# end

View File

@ -46,6 +46,7 @@ extern uint32_t mlag_rd_buf_offset;
static inline void zebra_mlag_reset_read_buffer(void)
{
memset(mlag_wr_buffer, 0, ZEBRA_MLAG_BUF_LIMIT);
mlag_rd_buf_offset = 0;
}

View File

@ -78,6 +78,8 @@ static int zebra_mlag_read(struct thread *thread)
uint32_t h_msglen;
uint32_t tot_len, curr_len = mlag_rd_buf_offset;
zrouter.mlag_info.t_read = NULL;
/*
* Received message in sock_stream looks like below
* | len-1 (4 Bytes) | payload-1 (len-1) |