summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/mlag.h21
-rw-r--r--lib/zclient.c33
-rw-r--r--lib/zclient.h9
-rw-r--r--pimd/pim_cmd.c21
-rw-r--r--pimd/pim_cmd.h1
-rw-r--r--pimd/pim_instance.c5
-rw-r--r--pimd/pim_instance.h14
-rw-r--r--pimd/pim_main.c2
-rw-r--r--pimd/pim_mlag.c187
-rw-r--r--pimd/pim_mlag.h42
-rw-r--r--pimd/pim_zebra.c2
-rw-r--r--pimd/pimd.h4
-rw-r--r--pimd/subdir.am2
13 files changed, 340 insertions, 3 deletions
diff --git a/lib/mlag.h b/lib/mlag.h
index 2b904d44f4..d461fdc44e 100644
--- a/lib/mlag.h
+++ b/lib/mlag.h
@@ -26,12 +26,33 @@
extern "C" {
#endif
+#define MLAG_BUF_LIMIT 2048
+
enum mlag_role {
MLAG_ROLE_NONE,
MLAG_ROLE_PRIMARY,
MLAG_ROLE_SECONDARY
};
+/*
+ * This message definition should match mlag.proto
+ * Beacuse mesasge registartion is based on this
+ */
+enum mlag_msg_type {
+ MLAG_MSG_NONE = 0,
+ MLAG_REGISTER = 1,
+ MLAG_DEREGISTER = 2,
+ MLAG_STATUS_UPDATE = 3,
+ MLAG_MROUTE_ADD = 4,
+ MLAG_MROUTE_DEL = 5,
+ MLAG_DUMP = 6,
+ MLAG_MROUTE_ADD_BULK = 7,
+ MLAG_MROUTE_DEL_BULK = 8,
+ MLAG_PIM_CFG_DUMP = 10,
+ MLAG_VXLAN_UPDATE = 11,
+ MLAG_PEER_FRR_STATUS = 12,
+};
+
extern char *mlag_role2str(enum mlag_role role, char *buf, size_t size);
#ifdef __cplusplus
diff --git a/lib/zclient.c b/lib/zclient.c
index f809704f86..a51e35fd98 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -2536,6 +2536,39 @@ stream_failure:
return;
}
+void zclient_send_mlag_register(struct zclient *client, uint32_t bit_map)
+{
+ struct stream *s;
+
+ s = client->obuf;
+ stream_reset(s);
+
+ zclient_create_header(s, ZEBRA_MLAG_CLIENT_REGISTER, VRF_DEFAULT);
+ stream_putl(s, bit_map);
+
+ stream_putw_at(s, 0, stream_get_endp(s));
+ zclient_send_message(client);
+}
+
+void zclient_send_mlag_deregister(struct zclient *client)
+{
+ zebra_message_send(client, ZEBRA_MLAG_CLIENT_UNREGISTER, VRF_DEFAULT);
+}
+
+void zclient_send_mlag_data(struct zclient *client, struct stream *client_s)
+{
+ struct stream *s;
+
+ s = client->obuf;
+ stream_reset(s);
+
+ zclient_create_header(s, ZEBRA_MLAG_FORWARD_MSG, VRF_DEFAULT);
+ stream_put(s, client_s->data, client_s->endp);
+
+ stream_putw_at(s, 0, stream_get_endp(s));
+ zclient_send_message(client);
+}
+
/* Zebra client message read function. */
static int zclient_read(struct thread *thread)
{
diff --git a/lib/zclient.h b/lib/zclient.h
index 81e454d192..1735495fcc 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -177,6 +177,9 @@ typedef enum {
ZEBRA_VXLAN_SG_ADD,
ZEBRA_VXLAN_SG_DEL,
ZEBRA_VXLAN_SG_REPLAY,
+ ZEBRA_MLAG_CLIENT_REGISTER,
+ ZEBRA_MLAG_CLIENT_UNREGISTER,
+ ZEBRA_MLAG_FORWARD_MSG,
} zebra_message_types_t;
struct redist_proto {
@@ -670,5 +673,11 @@ static inline void zapi_route_set_blackhole(struct zapi_route *api,
SET_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP);
};
+extern void zclient_send_mlag_register(struct zclient *client,
+ uint32_t bit_map);
+extern void zclient_send_mlag_deregister(struct zclient *client);
+
+extern void zclient_send_mlag_data(struct zclient *client,
+ struct stream *client_s);
#endif /* _ZEBRA_ZCLIENT_H */
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 28b4af9457..2c2b1c9586 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -61,6 +61,7 @@
#include "pim_nht.h"
#include "pim_bfd.h"
#include "pim_vxlan.h"
+#include "pim_mlag.h"
#include "bfd.h"
#include "pim_bsm.h"
@@ -7462,9 +7463,9 @@ DEFPY_HIDDEN (interface_ip_pim_activeactive,
pim_ifp = ifp->info;
if (no)
- pim_ifp->activeactive = false;
+ pim_if_unconfigure_mlag_dualactive(pim_ifp);
else
- pim_ifp->activeactive = true;
+ pim_if_configure_mlag_dualactive(pim_ifp);
return CMD_SUCCESS;
}
@@ -8382,6 +8383,20 @@ DEFUN (no_debug_pim_zebra,
return CMD_SUCCESS;
}
+DEFUN(debug_pim_mlag, debug_pim_mlag_cmd, "debug pim mlag",
+ DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
+{
+ PIM_DO_DEBUG_MLAG;
+ return CMD_SUCCESS;
+}
+
+DEFUN(no_debug_pim_mlag, no_debug_pim_mlag_cmd, "no debug pim mlag",
+ NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
+{
+ PIM_DONT_DEBUG_MLAG;
+ return CMD_SUCCESS;
+}
+
DEFUN (debug_pim_vxlan,
debug_pim_vxlan_cmd,
"debug pim vxlan",
@@ -10408,6 +10423,8 @@ void pim_cmd_init(void)
install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
install_element(ENABLE_NODE, &no_debug_pim_zebra_cmd);
+ install_element(ENABLE_NODE, &debug_pim_mlag_cmd);
+ install_element(ENABLE_NODE, &no_debug_pim_mlag_cmd);
install_element(ENABLE_NODE, &debug_pim_vxlan_cmd);
install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd);
install_element(ENABLE_NODE, &debug_msdp_cmd);
diff --git a/pimd/pim_cmd.h b/pimd/pim_cmd.h
index f5bb316a7a..9f05bc74e5 100644
--- a/pimd/pim_cmd.h
+++ b/pimd/pim_cmd.h
@@ -54,6 +54,7 @@
#define DEBUG_PIM_PACKETDUMP_RECV_STR "Dump received packets\n"
#define DEBUG_PIM_TRACE_STR "PIM internal daemon activity\n"
#define DEBUG_PIM_ZEBRA_STR "ZEBRA protocol activity\n"
+#define DEBUG_PIM_MLAG_STR "PIM Mlag activity\n"
#define DEBUG_PIM_VXLAN_STR "PIM VxLAN events\n"
#define DEBUG_SSMPINGD_STR "ssmpingd activity\n"
#define CLEAR_IP_IGMP_STR "IGMP clear commands\n"
diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c
index 6848d2dabb..955ad14b01 100644
--- a/pimd/pim_instance.c
+++ b/pimd/pim_instance.c
@@ -34,6 +34,7 @@
#include "pim_ssmpingd.h"
#include "pim_vty.h"
#include "pim_bsm.h"
+#include "pim_mlag.h"
static void pim_instance_terminate(struct pim_instance *pim)
{
@@ -47,6 +48,8 @@ static void pim_instance_terminate(struct pim_instance *pim)
if (pim->static_routes)
list_delete(&pim->static_routes);
+ pim_instance_mlag_terminate(pim);
+
pim_upstream_terminate(pim);
pim_rp_free(pim);
@@ -115,6 +118,8 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf)
pim_upstream_init(pim);
+ pim_instance_mlag_init(pim);
+
pim->last_route_change_time = -1;
return pim;
}
diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h
index 06d41c4b53..dd3ac8fcb0 100644
--- a/pimd/pim_instance.h
+++ b/pimd/pim_instance.h
@@ -64,6 +64,17 @@ struct pim_router {
vrf_id_t vrf_id;
enum mlag_role role;
+ uint32_t pim_mlag_intf_cnt;
+ /* if true we have registered with MLAG */
+ bool mlag_process_register;
+ /* if true local MLAG process reported that it is connected
+ * with the peer MLAG process
+ */
+ bool connected_to_mlag;
+ /* Holds the client data(unencoded) that need to be pushed to MCLAGD*/
+ struct stream_fifo *mlag_fifo;
+ struct stream *mlag_stream;
+ struct thread *zpthread_mlag_write;
};
/* Per VRF PIM DB */
@@ -122,6 +133,9 @@ struct pim_instance {
bool ecmp_enable;
bool ecmp_rebalance_enable;
+ /* No. of Dual active I/fs in pim_instance */
+ uint32_t inst_mlag_intf_cnt;
+
/* Bsm related */
struct bsm_scope global_scope;
uint64_t bsm_rcvd;
diff --git a/pimd/pim_main.c b/pimd/pim_main.c
index 5a8991c4c0..c57151b900 100644
--- a/pimd/pim_main.c
+++ b/pimd/pim_main.c
@@ -47,6 +47,7 @@
#include "pim_msdp.h"
#include "pim_iface.h"
#include "pim_bfd.h"
+#include "pim_mlag.h"
#include "pim_errors.h"
extern struct host host;
@@ -129,6 +130,7 @@ int main(int argc, char **argv, char **envp)
*/
pim_zebra_init();
pim_bfd_init();
+ pim_mlag_init();
frr_config_fork();
diff --git a/pimd/pim_mlag.c b/pimd/pim_mlag.c
new file mode 100644
index 0000000000..eaec0c716a
--- /dev/null
+++ b/pimd/pim_mlag.c
@@ -0,0 +1,187 @@
+/* PIM Mlag Code.
+ * Copyright (C) 2018 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 "pimd.h"
+#include "pim_mlag.h"
+
+extern struct zclient *zclient;
+
+static int pim_mlag_register_handler(struct thread *thread)
+{
+ uint32_t bit_mask = 0;
+
+ if (!zclient)
+ return -1;
+
+ SET_FLAG(bit_mask, (1 << MLAG_STATUS_UPDATE));
+ SET_FLAG(bit_mask, (1 << MLAG_MROUTE_ADD));
+ SET_FLAG(bit_mask, (1 << MLAG_MROUTE_DEL));
+ SET_FLAG(bit_mask, (1 << MLAG_DUMP));
+ SET_FLAG(bit_mask, (1 << MLAG_MROUTE_ADD_BULK));
+ SET_FLAG(bit_mask, (1 << MLAG_MROUTE_DEL_BULK));
+ SET_FLAG(bit_mask, (1 << MLAG_PIM_CFG_DUMP));
+ SET_FLAG(bit_mask, (1 << MLAG_VXLAN_UPDATE));
+ SET_FLAG(bit_mask, (1 << MLAG_PEER_FRR_STATUS));
+
+ if (PIM_DEBUG_MLAG)
+ zlog_debug("%s: Posting Client Register to MLAG mask:0x%x",
+ __func__, bit_mask);
+
+ zclient_send_mlag_register(zclient, bit_mask);
+ return 0;
+}
+
+void pim_mlag_register(void)
+{
+ if (router->mlag_process_register)
+ return;
+
+ router->mlag_process_register = true;
+
+ thread_add_event(router->master, pim_mlag_register_handler, NULL, 0,
+ NULL);
+}
+
+static int pim_mlag_deregister_handler(struct thread *thread)
+{
+ if (!zclient)
+ return -1;
+
+ if (PIM_DEBUG_MLAG)
+ zlog_debug("%s: Posting Client De-Register to MLAG from PIM",
+ __func__);
+ router->connected_to_mlag = false;
+ zclient_send_mlag_deregister(zclient);
+ return 0;
+}
+
+void pim_mlag_deregister(void)
+{
+ /* if somebody still interested in the MLAG channel skip de-reg */
+ if (router->pim_mlag_intf_cnt)
+ return;
+
+ /* not registered; nothing do */
+ if (!router->mlag_process_register)
+ return;
+
+ router->mlag_process_register = false;
+
+ thread_add_event(router->master, pim_mlag_deregister_handler, NULL, 0,
+ NULL);
+}
+
+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++;
+
+ router->pim_mlag_intf_cnt++;
+ if (PIM_DEBUG_MLAG)
+ zlog_debug(
+ "%s: Total MLAG configured Interfaces on router: %d, Inst:%d",
+ __func__, router->pim_mlag_intf_cnt,
+ pim_ifp->pim->inst_mlag_intf_cnt);
+
+ if (router->pim_mlag_intf_cnt == 1) {
+ /*
+ * atleast one Interface is configured for MLAG, send register
+ * to Zebra for receiving MLAG Updates
+ */
+ pim_mlag_register();
+ }
+}
+
+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;
+ if (pim_ifp->pim)
+ pim_ifp->pim->inst_mlag_intf_cnt--;
+
+ router->pim_mlag_intf_cnt--;
+ if (PIM_DEBUG_MLAG)
+ zlog_debug(
+ "%s: Total MLAG configured Interfaces on router: %d, Inst:%d",
+ __func__, router->pim_mlag_intf_cnt,
+ pim_ifp->pim->inst_mlag_intf_cnt);
+
+ if (router->pim_mlag_intf_cnt == 0) {
+ /*
+ * all the Interfaces are MLAG un-configured, post MLAG
+ * De-register to Zebra
+ */
+ pim_mlag_deregister();
+ }
+}
+
+
+void pim_instance_mlag_init(struct pim_instance *pim)
+{
+ if (!pim)
+ return;
+
+ pim->inst_mlag_intf_cnt = 0;
+}
+
+
+void pim_instance_mlag_terminate(struct pim_instance *pim)
+{
+ struct interface *ifp;
+
+ if (!pim)
+ return;
+
+ FOR_ALL_INTERFACES (pim->vrf, ifp) {
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (!pim_ifp || pim_ifp->activeactive == false)
+ continue;
+
+ pim_if_unconfigure_mlag_dualactive(pim_ifp);
+ }
+ pim->inst_mlag_intf_cnt = 0;
+}
+
+void pim_mlag_init(void)
+{
+ router->pim_mlag_intf_cnt = 0;
+ router->connected_to_mlag = false;
+ router->mlag_fifo = stream_fifo_new();
+ router->zpthread_mlag_write = NULL;
+ router->mlag_stream = stream_new(MLAG_BUF_LIMIT);
+}
diff --git a/pimd/pim_mlag.h b/pimd/pim_mlag.h
new file mode 100644
index 0000000000..03fbfccb42
--- /dev/null
+++ b/pimd/pim_mlag.h
@@ -0,0 +1,42 @@
+/* PIM mlag header.
+ * Copyright (C) 2018 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 __PIM_MLAG_H__
+#define __PIM_MLAG_H__
+
+#include "mlag.h"
+#include "pim_iface.h"
+
+extern void pim_mlag_init(void);
+
+extern void pim_instance_mlag_init(struct pim_instance *pim);
+
+extern void pim_instance_mlag_terminate(struct pim_instance *pim);
+
+extern void pim_if_configure_mlag_dualactive(struct pim_interface *pim_ifp);
+
+extern void pim_if_unconfigure_mlag_dualactive(struct pim_interface *pim_ifp);
+
+extern void pim_mlag_register(void);
+
+extern void pim_mlag_deregister(void);
+
+#endif
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index b0db23f54a..e9cfc7e520 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -50,7 +50,7 @@
#undef PIM_DEBUG_IFADDR_DUMP
#define PIM_DEBUG_IFADDR_DUMP
-static struct zclient *zclient = NULL;
+struct zclient *zclient;
/* Router-id update message from zebra. */
diff --git a/pimd/pimd.h b/pimd/pimd.h
index 3b83d3b6c7..b7e6d916a8 100644
--- a/pimd/pimd.h
+++ b/pimd/pimd.h
@@ -115,6 +115,7 @@
#define PIM_MASK_MTRACE (1 << 25)
#define PIM_MASK_VXLAN (1 << 26)
#define PIM_MASK_BSM_PROC (1 << 27)
+#define PIM_MASK_MLAG (1 << 28)
/* Remember 32 bits!!! */
/* PIM error codes */
@@ -171,6 +172,7 @@ extern uint8_t qpim_ecmp_rebalance_enable;
#define PIM_DEBUG_IGMP_TRACE_DETAIL \
(router->debugs & (PIM_MASK_IGMP_TRACE_DETAIL | PIM_MASK_IGMP_TRACE))
#define PIM_DEBUG_ZEBRA (router->debugs & PIM_MASK_ZEBRA)
+#define PIM_DEBUG_MLAG (router->debugs & PIM_MASK_MLAG)
#define PIM_DEBUG_SSMPINGD (router->debugs & PIM_MASK_SSMPINGD)
#define PIM_DEBUG_MROUTE (router->debugs & PIM_MASK_MROUTE)
#define PIM_DEBUG_MROUTE_DETAIL \
@@ -217,6 +219,7 @@ extern uint8_t qpim_ecmp_rebalance_enable;
#define PIM_DO_DEBUG_IGMP_TRACE_DETAIL \
(router->debugs |= PIM_MASK_IGMP_TRACE_DETAIL)
#define PIM_DO_DEBUG_ZEBRA (router->debugs |= PIM_MASK_ZEBRA)
+#define PIM_DO_DEBUG_MLAG (router->debugs |= PIM_MASK_MLAG)
#define PIM_DO_DEBUG_SSMPINGD (router->debugs |= PIM_MASK_SSMPINGD)
#define PIM_DO_DEBUG_MROUTE (router->debugs |= PIM_MASK_MROUTE)
#define PIM_DO_DEBUG_MROUTE_DETAIL (router->debugs |= PIM_MASK_MROUTE_DETAIL)
@@ -248,6 +251,7 @@ extern uint8_t qpim_ecmp_rebalance_enable;
#define PIM_DONT_DEBUG_IGMP_TRACE_DETAIL \
(router->debugs &= ~PIM_MASK_IGMP_TRACE_DETAIL)
#define PIM_DONT_DEBUG_ZEBRA (router->debugs &= ~PIM_MASK_ZEBRA)
+#define PIM_DONT_DEBUG_MLAG (router->debugs &= ~PIM_MASK_MLAG)
#define PIM_DONT_DEBUG_SSMPINGD (router->debugs &= ~PIM_MASK_SSMPINGD)
#define PIM_DONT_DEBUG_MROUTE (router->debugs &= ~PIM_MASK_MROUTE)
#define PIM_DONT_DEBUG_MROUTE_DETAIL (router->debugs &= ~PIM_MASK_MROUTE_DETAIL)
diff --git a/pimd/subdir.am b/pimd/subdir.am
index 240b62804f..5407e566a5 100644
--- a/pimd/subdir.am
+++ b/pimd/subdir.am
@@ -62,6 +62,7 @@ pimd_libpim_a_SOURCES = \
pimd/pim_zebra.c \
pimd/pim_zlookup.c \
pimd/pim_vxlan.c \
+ pimd/pim_mlag.c \
pimd/pimd.c \
# end
@@ -114,6 +115,7 @@ noinst_HEADERS += \
pimd/pim_zebra.h \
pimd/pim_zlookup.h \
pimd/pim_vxlan.h \
+ pimd/pim_mlag.h \
pimd/pim_vxlan_instance.h \
pimd/pimd.h \
pimd/mtracebis_netlink.h \