]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd, lib: adding support for MLAG Message processing at PIM
authorSatheesh Kumar K <sathk@cumulusnetworks.com>
Tue, 12 Nov 2019 08:17:13 +0000 (00:17 -0800)
committerSatheesh Kumar K <sathk@cumulusnetworks.com>
Thu, 14 Nov 2019 04:43:15 +0000 (20:43 -0800)
This includes:
1. Defining message formats
2. Stream Decoding after receiving the message at PIM
3. Handling MLAG UP & Down Notifications

Signed-off-by: Satheesh Kumar K <sathk@cumulusnetworks.com>
lib/mlag.c
lib/mlag.h
lib/zclient.c
lib/zclient.h
pimd/pim_mlag.c
pimd/pim_mlag.h
pimd/pim_zebra.c

index acdc66292495e58a3f7ffadd8ca993d98016fb54..7aac571da679a50224fb28f39e1ddab006dc5b66 100644 (file)
@@ -39,3 +39,133 @@ char *mlag_role2str(enum mlag_role role, char *buf, size_t size)
 
        return buf;
 }
+
+char *zebra_mlag_lib_msgid_to_str(enum mlag_msg_type msg_type, char *buf,
+                                 size_t size)
+{
+       switch (msg_type) {
+       case MLAG_REGISTER:
+               snprintf(buf, size, "Register");
+               break;
+       case MLAG_DEREGISTER:
+               snprintf(buf, size, "De-Register");
+               break;
+       case MLAG_MROUTE_ADD:
+               snprintf(buf, size, "Mroute add");
+               break;
+       case MLAG_MROUTE_DEL:
+               snprintf(buf, size, "Mroute del");
+               break;
+       case MLAG_DUMP:
+               snprintf(buf, size, "Mlag Replay");
+               break;
+       case MLAG_MROUTE_ADD_BULK:
+               snprintf(buf, size, "Mroute Add Batch");
+               break;
+       case MLAG_MROUTE_DEL_BULK:
+               snprintf(buf, size, "Mroute Del Batch");
+               break;
+       case MLAG_STATUS_UPDATE:
+               snprintf(buf, size, "Mlag Status");
+               break;
+       case MLAG_VXLAN_UPDATE:
+               snprintf(buf, size, "Mlag vxlan update");
+               break;
+       case MLAG_PEER_FRR_STATUS:
+               snprintf(buf, size, "Mlag Peer FRR Status");
+               break;
+       default:
+               snprintf(buf, size, "Unknown %d", msg_type);
+               break;
+       }
+       return buf;
+}
+
+
+int zebra_mlag_lib_decode_mlag_hdr(struct stream *s, struct mlag_msg *msg)
+{
+       if (s == NULL || msg == NULL)
+               return -1;
+
+       STREAM_GETL(s, msg->msg_type);
+       STREAM_GETW(s, msg->data_len);
+       STREAM_GETW(s, msg->msg_cnt);
+       return 0;
+stream_failure:
+       return -1;
+}
+
+int zebra_mlag_lib_decode_mroute_add(struct stream *s,
+                                    struct mlag_mroute_add *msg)
+{
+       if (s == NULL || msg == NULL)
+               return -1;
+
+       STREAM_GET(msg->vrf_name, s, VRF_NAMSIZ);
+       STREAM_GETL(s, msg->source_ip);
+       STREAM_GETL(s, msg->group_ip);
+       STREAM_GETL(s, msg->cost_to_rp);
+       STREAM_GETL(s, msg->owner_id);
+       STREAM_GETC(s, msg->am_i_dr);
+       STREAM_GETC(s, msg->am_i_dual_active);
+       STREAM_GETL(s, msg->vrf_id);
+       STREAM_GET(msg->intf_name, s, INTERFACE_NAMSIZ);
+       return 0;
+stream_failure:
+       return -1;
+}
+
+int zebra_mlag_lib_decode_mroute_del(struct stream *s,
+                                    struct mlag_mroute_del *msg)
+{
+       if (s == NULL || msg == NULL)
+               return -1;
+
+       STREAM_GET(msg->vrf_name, s, VRF_NAMSIZ);
+       STREAM_GETL(s, msg->source_ip);
+       STREAM_GETL(s, msg->group_ip);
+       STREAM_GETL(s, msg->owner_id);
+       STREAM_GETL(s, msg->vrf_id);
+       STREAM_GET(msg->intf_name, s, INTERFACE_NAMSIZ);
+       return 0;
+stream_failure:
+       return -1;
+}
+
+int zebra_mlag_lib_decode_mlag_status(struct stream *s, struct mlag_status *msg)
+{
+       if (s == NULL || msg == NULL)
+               return -1;
+
+       STREAM_GET(msg->peerlink_rif, s, INTERFACE_NAMSIZ);
+       STREAM_GETL(s, msg->my_role);
+       STREAM_GETL(s, msg->peer_state);
+       return 0;
+stream_failure:
+       return -1;
+}
+
+int zebra_mlag_lib_decode_vxlan_update(struct stream *s, struct mlag_vxlan *msg)
+{
+       if (s == NULL || msg == NULL)
+               return -1;
+
+       STREAM_GETL(s, msg->anycast_ip);
+       STREAM_GETL(s, msg->local_ip);
+       return 0;
+
+stream_failure:
+       return -1;
+}
+
+int zebra_mlag_lib_decode_frr_status(struct stream *s,
+                                    struct mlag_frr_status *msg)
+{
+       if (s == NULL || msg == NULL)
+               return -1;
+
+       STREAM_GETL(s, msg->frr_state);
+       return 0;
+stream_failure:
+       return -1;
+}
index d461fdc44e99944ad95cf9dfc2da2c372a2dc6a3..942d4be3b66ae73811918d17078bb6913e607e45 100644 (file)
 extern "C" {
 #endif
 
+#include "lib/if.h"
+#include "lib/vrf.h"
+#include "lib/stream.h"
+
 #define MLAG_BUF_LIMIT 2048
 
 enum mlag_role {
@@ -34,9 +38,26 @@ enum mlag_role {
        MLAG_ROLE_SECONDARY
 };
 
+enum mlag_state {
+       MLAG_STATE_DOWN,
+       MLAG_STATE_RUNNING,
+};
+
+enum mlag_frr_state {
+       MLAG_FRR_STATE_NONE,
+       MLAG_FRR_STATE_DOWN,
+       MLAG_FRR_STATE_UP,
+};
+
+enum mlag_owner {
+       MLAG_OWNER_NONE,
+       MLAG_OWNER_INTERFACE,
+       MLAG_OWNER_VXLAN,
+};
+
 /*
  * This message definition should match mlag.proto
- * Beacuse mesasge registartion is based on this
+ * Because message registration is based on this
  */
 enum mlag_msg_type {
        MLAG_MSG_NONE = 0,
@@ -53,8 +74,67 @@ enum mlag_msg_type {
        MLAG_PEER_FRR_STATUS = 12,
 };
 
-extern char *mlag_role2str(enum mlag_role role, char *buf, size_t size);
+struct mlag_frr_status {
+       enum mlag_frr_state frr_state;
+};
+
+struct mlag_status {
+       char peerlink_rif[INTERFACE_NAMSIZ];
+       enum mlag_role my_role;
+       enum mlag_state peer_state;
+};
 
+#define MLAG_ROLE_STRSIZE 16
+
+struct mlag_vxlan {
+       uint32_t anycast_ip;
+       uint32_t local_ip;
+};
+
+struct mlag_mroute_add {
+       char vrf_name[VRF_NAMSIZ];
+       uint32_t source_ip;
+       uint32_t group_ip;
+       uint32_t cost_to_rp;
+       enum mlag_owner owner_id;
+       bool am_i_dr;
+       bool am_i_dual_active;
+       vrf_id_t vrf_id;
+       char intf_name[INTERFACE_NAMSIZ];
+};
+
+struct mlag_mroute_del {
+       char vrf_name[VRF_NAMSIZ];
+       uint32_t source_ip;
+       uint32_t group_ip;
+       enum mlag_owner owner_id;
+       vrf_id_t vrf_id;
+       char intf_name[INTERFACE_NAMSIZ];
+};
+
+struct mlag_msg {
+       enum mlag_msg_type msg_type;
+       uint16_t data_len;
+       uint16_t msg_cnt;
+       uint8_t data[0];
+}__attribute__((packed));
+
+
+extern char *mlag_role2str(enum mlag_role role, char *buf, size_t size);
+extern char *zebra_mlag_lib_msgid_to_str(enum mlag_msg_type msg_type, char *buf,
+                                        size_t size);
+extern int zebra_mlag_lib_decode_mlag_hdr(struct stream *s,
+                                         struct mlag_msg *msg);
+extern int zebra_mlag_lib_decode_mroute_add(struct stream *s,
+                                           struct mlag_mroute_add *msg);
+extern int zebra_mlag_lib_decode_mroute_del(struct stream *s,
+                                           struct mlag_mroute_del *msg);
+extern int zebra_mlag_lib_decode_mlag_status(struct stream *s,
+                                            struct mlag_status *msg);
+extern int zebra_mlag_lib_decode_vxlan_update(struct stream *s,
+                                             struct mlag_vxlan *msg);
+extern int zebra_mlag_lib_decode_frr_status(struct stream *s,
+                                           struct mlag_frr_status *msg);
 #ifdef __cplusplus
 }
 #endif
index 1540fafb5d91169cde568939fbfd6e6436f5fedc..7a62e408eae7f161145da6a9c907b0a9bf7d23df 100644 (file)
@@ -2754,6 +2754,24 @@ void zclient_send_mlag_data(struct zclient *client, struct stream *client_s)
        zclient_send_message(client);
 }
 
+static void zclient_mlag_process_up(ZAPI_CALLBACK_ARGS)
+{
+       if (zclient->mlag_process_up)
+               (*zclient->mlag_process_up)();
+}
+
+static void zclient_mlag_process_down(ZAPI_CALLBACK_ARGS)
+{
+       if (zclient->mlag_process_down)
+               (*zclient->mlag_process_down)();
+}
+
+static void zclient_mlag_handle_msg(ZAPI_CALLBACK_ARGS)
+{
+       if (zclient->mlag_handle_msg)
+               (*zclient->mlag_handle_msg)(zclient->ibuf, length);
+}
+
 /* Zebra client message read function. */
 static int zclient_read(struct thread *thread)
 {
@@ -3048,6 +3066,15 @@ static int zclient_read(struct thread *thread)
                        (*zclient->vxlan_sg_del)(command, zclient, length,
                                                    vrf_id);
                break;
+       case ZEBRA_MLAG_PROCESS_UP:
+               zclient_mlag_process_up(command, zclient, length, vrf_id);
+               break;
+       case ZEBRA_MLAG_PROCESS_DOWN:
+               zclient_mlag_process_down(command, zclient, length, vrf_id);
+               break;
+       case ZEBRA_MLAG_FORWARD_MSG:
+               zclient_mlag_handle_msg(command, zclient, length, vrf_id);
+               break;
        default:
                break;
        }
index 6cb09a6ac7e5b69ffd6903aaa47ce47e322ec9dd..ebf3e6450f00192f536501ce4c7e1f072ad28d97 100644 (file)
@@ -178,6 +178,8 @@ typedef enum {
        ZEBRA_VXLAN_SG_ADD,
        ZEBRA_VXLAN_SG_DEL,
        ZEBRA_VXLAN_SG_REPLAY,
+       ZEBRA_MLAG_PROCESS_UP,
+       ZEBRA_MLAG_PROCESS_DOWN,
        ZEBRA_MLAG_CLIENT_REGISTER,
        ZEBRA_MLAG_CLIENT_UNREGISTER,
        ZEBRA_MLAG_FORWARD_MSG,
@@ -275,6 +277,9 @@ struct zclient {
        int (*iptable_notify_owner)(ZAPI_CALLBACK_ARGS);
        int (*vxlan_sg_add)(ZAPI_CALLBACK_ARGS);
        int (*vxlan_sg_del)(ZAPI_CALLBACK_ARGS);
+       int (*mlag_process_up)(void);
+       int (*mlag_process_down)(void);
+       int (*mlag_handle_msg)(struct stream *msg, int len);
 };
 
 /* Zebra API message flag. */
index 5e5da2900221c8d890a45797df9cab9eb47c1afc..740373bc4000a9f58d237204bb4c6a79c119bf48 100644 (file)
 
 extern struct zclient *zclient;
 
+
+/********************API to process PIM MLAG Data ************************/
+
+static void pim_mlag_process_mlagd_state_change(struct mlag_status msg)
+{
+       char buf[MLAG_ROLE_STRSIZE];
+
+       if (PIM_DEBUG_MLAG)
+               zlog_debug("%s: msg dump: my_role: %s, peer_state: %s",
+                          __func__,
+                          mlag_role2str(msg.my_role, buf, sizeof(buf)),
+                          (msg.peer_state == MLAG_STATE_RUNNING ? "RUNNING"
+                                                                : "DOWN"));
+}
+
+static void pim_mlag_process_peer_frr_state_change(struct mlag_frr_status msg)
+{
+       if (PIM_DEBUG_MLAG)
+               zlog_debug(
+                       "%s: msg dump: peer_frr_state: %s", __func__,
+                       (msg.frr_state == MLAG_FRR_STATE_UP ? "UP" : "DOWN"));
+}
+
+static void pim_mlag_process_vxlan_update(struct mlag_vxlan *msg)
+{
+}
+
+static void pim_mlag_process_mroute_add(struct mlag_mroute_add msg)
+{
+       if (PIM_DEBUG_MLAG) {
+               zlog_debug(
+                       "%s: msg dump: vrf_name: %s, s.ip: 0x%x, g.ip: 0x%x cost: %u",
+                       __func__, msg.vrf_name, msg.source_ip, msg.group_ip,
+                       msg.cost_to_rp);
+               zlog_debug(
+                       "owner_id: %d, DR: %d, Dual active: %d, vrf_id: 0x%x intf_name: %s",
+                       msg.owner_id, msg.am_i_dr, msg.am_i_dual_active,
+                       msg.vrf_id, msg.intf_name);
+       }
+}
+
+static void pim_mlag_process_mroute_del(struct mlag_mroute_del msg)
+{
+       if (PIM_DEBUG_MLAG) {
+               zlog_debug(
+                       "%s: msg dump: vrf_name: %s, s.ip: 0x%x, g.ip: 0x%x ",
+                       __func__, msg.vrf_name, msg.source_ip, msg.group_ip);
+               zlog_debug("owner_id: %d, vrf_id: 0x%x intf_name: %s",
+                          msg.owner_id, msg.vrf_id, msg.intf_name);
+       }
+}
+
+
+int pim_zebra_mlag_handle_msg(struct stream *s, int len)
+{
+       struct mlag_msg mlag_msg;
+       char buf[ZLOG_FILTER_LENGTH_MAX];
+       int rc = 0;
+
+       rc = zebra_mlag_lib_decode_mlag_hdr(s, &mlag_msg);
+       if (rc)
+               return (rc);
+
+       if (PIM_DEBUG_MLAG)
+               zlog_debug("%s: Received msg type: %s length: %d, bulk_cnt: %d",
+                          __func__,
+                          zebra_mlag_lib_msgid_to_str(mlag_msg.msg_type, buf,
+                                                      sizeof(buf)),
+                          mlag_msg.data_len, mlag_msg.msg_cnt);
+
+       switch (mlag_msg.msg_type) {
+       case MLAG_STATUS_UPDATE: {
+               struct mlag_status msg;
+
+               rc = zebra_mlag_lib_decode_mlag_status(s, &msg);
+               if (rc)
+                       return (rc);
+               pim_mlag_process_mlagd_state_change(msg);
+       } break;
+       case MLAG_PEER_FRR_STATUS: {
+               struct mlag_frr_status msg;
+
+               rc = zebra_mlag_lib_decode_frr_status(s, &msg);
+               if (rc)
+                       return (rc);
+               pim_mlag_process_peer_frr_state_change(msg);
+       } break;
+       case MLAG_VXLAN_UPDATE: {
+               struct mlag_vxlan msg;
+
+               rc = zebra_mlag_lib_decode_vxlan_update(s, &msg);
+               if (rc)
+                       return rc;
+               pim_mlag_process_vxlan_update(&msg);
+       } break;
+       case MLAG_MROUTE_ADD: {
+               struct mlag_mroute_add msg;
+
+               rc = zebra_mlag_lib_decode_mroute_add(s, &msg);
+               if (rc)
+                       return (rc);
+               pim_mlag_process_mroute_add(msg);
+       } break;
+       case MLAG_MROUTE_DEL: {
+               struct mlag_mroute_del msg;
+
+               rc = zebra_mlag_lib_decode_mroute_del(s, &msg);
+               if (rc)
+                       return (rc);
+               pim_mlag_process_mroute_del(msg);
+       } break;
+       case MLAG_MROUTE_ADD_BULK: {
+               struct mlag_mroute_add msg;
+               int i = 0;
+
+               for (i = 0; i < mlag_msg.msg_cnt; i++) {
+
+                       rc = zebra_mlag_lib_decode_mroute_add(s, &msg);
+                       if (rc)
+                               return (rc);
+                       pim_mlag_process_mroute_add(msg);
+               }
+       } break;
+       case MLAG_MROUTE_DEL_BULK: {
+               struct mlag_mroute_del msg;
+               int i = 0;
+
+               for (i = 0; i < mlag_msg.msg_cnt; i++) {
+
+                       rc = zebra_mlag_lib_decode_mroute_del(s, &msg);
+                       if (rc)
+                               return (rc);
+                       pim_mlag_process_mroute_del(msg);
+               }
+       } break;
+       default:
+               break;
+       }
+       return 0;
+}
+
+/****************End of PIM Mesasge processing handler********************/
+
+int pim_zebra_mlag_process_up(void)
+{
+       if (PIM_DEBUG_MLAG)
+               zlog_debug("%s: Received Process-Up from Mlag", __func__);
+
+       return 0;
+}
+
+int pim_zebra_mlag_process_down(void)
+{
+       if (PIM_DEBUG_MLAG)
+               zlog_debug("%s: Received Process-Down from Mlag", __func__);
+
+       return 0;
+}
+
 static int pim_mlag_register_handler(struct thread *thread)
 {
        uint32_t bit_mask = 0;
@@ -132,8 +291,7 @@ void pim_if_unconfigure_mlag_dualactive(struct pim_interface *pim_ifp)
                           __func__, "NULL");
 
        pim_ifp->activeactive = false;
-       if (pim_ifp->pim)
-               pim_ifp->pim->inst_mlag_intf_cnt--;
+       pim_ifp->pim->inst_mlag_intf_cnt--;
 
        router->pim_mlag_intf_cnt--;
        if (PIM_DEBUG_MLAG)
index b1c3fce4c860cef932b36d967fd19a97c8f23c33..e86fdae78f1c2cf1dbf3b86d7e55c185ba77ef21 100644 (file)
@@ -34,4 +34,7 @@ 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);
+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);
 #endif
index ede37ec53e8dbc080d51b18f324d81476e1de67c..0806e313456af52dc89e4584c9db6e184b153da5 100644 (file)
@@ -46,6 +46,7 @@
 #include "pim_nht.h"
 #include "pim_ssm.h"
 #include "pim_vxlan.h"
+#include "pim_mlag.h"
 
 #undef PIM_DEBUG_IFADDR_DUMP
 #define PIM_DEBUG_IFADDR_DUMP
@@ -587,6 +588,9 @@ void pim_zebra_init(void)
        zclient->nexthop_update = pim_parse_nexthop_update;
        zclient->vxlan_sg_add = pim_zebra_vxlan_sg_proc;
        zclient->vxlan_sg_del = pim_zebra_vxlan_sg_proc;
+       zclient->mlag_process_up = pim_zebra_mlag_process_up;
+       zclient->mlag_process_down = pim_zebra_mlag_process_down;
+       zclient->mlag_handle_msg = pim_zebra_mlag_handle_msg;
 
        zclient_init(zclient, ZEBRA_ROUTE_PIM, 0, &pimd_privs);
        if (PIM_DEBUG_PIM_TRACE) {