forked from Mirror/frr
Revert "Merge pull request #4885 from satheeshkarra/pim_mlag"
This reverts commitd563896dad
, reversing changes made to09ea1a4038
.
This commit is contained in:
parent
e34e314eb6
commit
6a597223d3
|
@ -125,7 +125,6 @@ include doc/manpages/subdir.am
|
||||||
include doc/developer/subdir.am
|
include doc/developer/subdir.am
|
||||||
include include/subdir.am
|
include include/subdir.am
|
||||||
include lib/subdir.am
|
include lib/subdir.am
|
||||||
include mlag/subdir.am
|
|
||||||
include zebra/subdir.am
|
include zebra/subdir.am
|
||||||
include watchfrr/subdir.am
|
include watchfrr/subdir.am
|
||||||
include qpb/subdir.am
|
include qpb/subdir.am
|
||||||
|
|
130
lib/mlag.c
130
lib/mlag.c
|
@ -39,133 +39,3 @@ char *mlag_role2str(enum mlag_role role, char *buf, size_t size)
|
||||||
|
|
||||||
return buf;
|
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;
|
|
||||||
}
|
|
||||||
|
|
105
lib/mlag.h
105
lib/mlag.h
|
@ -26,118 +26,13 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "lib/if.h"
|
|
||||||
#include "lib/vrf.h"
|
|
||||||
#include "lib/stream.h"
|
|
||||||
|
|
||||||
#define MLAG_MSG_NULL_PAYLOAD 0
|
|
||||||
#define MLAG_MSG_NO_BATCH 1
|
|
||||||
#define MLAG_BUF_LIMIT 2048
|
|
||||||
|
|
||||||
enum mlag_role {
|
enum mlag_role {
|
||||||
MLAG_ROLE_NONE,
|
MLAG_ROLE_NONE,
|
||||||
MLAG_ROLE_PRIMARY,
|
MLAG_ROLE_PRIMARY,
|
||||||
MLAG_ROLE_SECONDARY
|
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
|
|
||||||
* Because message registration 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,
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
uint8_t am_i_dr;
|
|
||||||
uint8_t am_i_dual_active;
|
|
||||||
uint32_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;
|
|
||||||
uint32_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];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
extern char *mlag_role2str(enum mlag_role role, char *buf, size_t size);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -2717,63 +2717,6 @@ stream_failure:
|
||||||
return;
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void zclient_mlag_process_up(int command, struct zclient *zclient,
|
|
||||||
zebra_size_t length, vrf_id_t vrf_id)
|
|
||||||
{
|
|
||||||
if (zclient->mlag_process_up)
|
|
||||||
(*zclient->mlag_process_up)();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void zclient_mlag_process_down(int command, struct zclient *zclient,
|
|
||||||
zebra_size_t length, vrf_id_t vrf_id)
|
|
||||||
{
|
|
||||||
if (zclient->mlag_process_down)
|
|
||||||
(*zclient->mlag_process_down)();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void zclient_mlag_handle_msg(int command, struct zclient *zclient,
|
|
||||||
zebra_size_t length, vrf_id_t vrf_id)
|
|
||||||
{
|
|
||||||
if (zclient->mlag_handle_msg)
|
|
||||||
(*zclient->mlag_handle_msg)(zclient->ibuf, length);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Zebra client message read function. */
|
/* Zebra client message read function. */
|
||||||
static int zclient_read(struct thread *thread)
|
static int zclient_read(struct thread *thread)
|
||||||
{
|
{
|
||||||
|
@ -3068,15 +3011,6 @@ static int zclient_read(struct thread *thread)
|
||||||
(*zclient->vxlan_sg_del)(command, zclient, length,
|
(*zclient->vxlan_sg_del)(command, zclient, length,
|
||||||
vrf_id);
|
vrf_id);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,11 +178,6 @@ typedef enum {
|
||||||
ZEBRA_VXLAN_SG_ADD,
|
ZEBRA_VXLAN_SG_ADD,
|
||||||
ZEBRA_VXLAN_SG_DEL,
|
ZEBRA_VXLAN_SG_DEL,
|
||||||
ZEBRA_VXLAN_SG_REPLAY,
|
ZEBRA_VXLAN_SG_REPLAY,
|
||||||
ZEBRA_MLAG_PROCESS_UP,
|
|
||||||
ZEBRA_MLAG_PROCESS_DOWN,
|
|
||||||
ZEBRA_MLAG_CLIENT_REGISTER,
|
|
||||||
ZEBRA_MLAG_CLIENT_UNREGISTER,
|
|
||||||
ZEBRA_MLAG_FORWARD_MSG,
|
|
||||||
} zebra_message_types_t;
|
} zebra_message_types_t;
|
||||||
|
|
||||||
struct redist_proto {
|
struct redist_proto {
|
||||||
|
@ -277,9 +272,6 @@ struct zclient {
|
||||||
int (*iptable_notify_owner)(ZAPI_CALLBACK_ARGS);
|
int (*iptable_notify_owner)(ZAPI_CALLBACK_ARGS);
|
||||||
int (*vxlan_sg_add)(ZAPI_CALLBACK_ARGS);
|
int (*vxlan_sg_add)(ZAPI_CALLBACK_ARGS);
|
||||||
int (*vxlan_sg_del)(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. */
|
/* Zebra API message flag. */
|
||||||
|
@ -701,11 +693,5 @@ static inline void zapi_route_set_blackhole(struct zapi_route *api,
|
||||||
SET_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP);
|
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 */
|
#endif /* _ZEBRA_ZCLIENT_H */
|
||||||
|
|
186
mlag/mlag.proto
186
mlag/mlag.proto
|
@ -1,186 +0,0 @@
|
||||||
// See README.txt for information and build instructions.
|
|
||||||
//
|
|
||||||
// Note: START and END tags are used in comments to define sections used in
|
|
||||||
// tutorials. They are not part of the syntax for Protocol Buffers.
|
|
||||||
//
|
|
||||||
// To get an in-depth walkthrough of this file and the related examples, see:
|
|
||||||
// https://developers.google.com/protocol-buffers/docs/tutorials
|
|
||||||
|
|
||||||
// [START declaration]
|
|
||||||
syntax = "proto3";
|
|
||||||
//package tutorial;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This Contains the Mesadge structurtes used for PIM MLAG Active-Active support.
|
|
||||||
* Mainly there were two types of messages
|
|
||||||
*
|
|
||||||
* 1. Messages sent from PIM (Node-1) to PIM (Node-2)
|
|
||||||
* 2. Messages sent from MCLAGD to PIM (status Messages)
|
|
||||||
*
|
|
||||||
* ProtoBuf supports maximum 32 fileds, so to make it more generic message
|
|
||||||
* encoding is like below.
|
|
||||||
* __________________________________________
|
|
||||||
* | | |
|
|
||||||
* | Header | bytes |
|
|
||||||
* ___________________________________________
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Header carries Information about
|
|
||||||
* 1) what Message it is carrying
|
|
||||||
* 2) Bytes carries teh actual payload encoded with protobuf
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Limitations
|
|
||||||
*=============
|
|
||||||
* Since message-type is 32-bit, there were no real limitations on number of
|
|
||||||
* messages Infra can support, but each message can carry only 32 fileds.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// [START messages]
|
|
||||||
message ZebraMlag_Header {
|
|
||||||
enum MessageType {
|
|
||||||
ZEBRA_MLAG_NONE = 0; //Invalid message-type
|
|
||||||
ZEBRA_MLAG_REGISTER = 1;
|
|
||||||
ZEBRA_MLAG_DEREGISTER = 2;
|
|
||||||
ZEBRA_MLAG_STATUS_UPDATE = 3;
|
|
||||||
ZEBRA_MLAG_MROUTE_ADD = 4;
|
|
||||||
ZEBRA_MLAG_MROUTE_DEL = 5;
|
|
||||||
ZEBRA_MLAG_DUMP = 6;
|
|
||||||
ZEBRA_MLAG_MROUTE_ADD_BULK = 7;
|
|
||||||
ZEBRA_MLAG_MROUTE_DEL_BULK = 8;
|
|
||||||
ZEBRA_MLAG_PIM_CFG_DUMP = 10;
|
|
||||||
ZEBRA_MLAG_VXLAN_UPDATE = 11;
|
|
||||||
ZEBRA_MLAG_ZEBRA_STATUS_UPDATE = 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* tells what type of message this payload carries
|
|
||||||
*/
|
|
||||||
MessageType type = 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Length of payload
|
|
||||||
*/
|
|
||||||
uint32 len = 2;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Actual Encoded payload
|
|
||||||
*/
|
|
||||||
bytes data = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ZEBRA_MLAG_REGISTER & ZEBRA_MLAG_DEREGISTER
|
|
||||||
*
|
|
||||||
* After the MLAGD is up, First Zebra has to register to send any data,
|
|
||||||
* otherwise MLAGD will not accept any data from the client.
|
|
||||||
* De-register will be used for the Data cleanup at MLAGD
|
|
||||||
* These are NULL payload message currently
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ZEBRA_MLAG_STATUS_UPDATE
|
|
||||||
*
|
|
||||||
* This message will be posted by CLAGD(an external control plane manager
|
|
||||||
* which monitors MCLAG failures) to inform peerlink/CLAG Failure
|
|
||||||
* to zebra, after the failure Notification Node with primary role will
|
|
||||||
* forward the Traffic and Node with standby will drop the traffic
|
|
||||||
*/
|
|
||||||
|
|
||||||
message ZebraMlagStatusUpdate {
|
|
||||||
enum ClagState {
|
|
||||||
CLAG_STATE_DOWN = 0;
|
|
||||||
CLAG_STATE_RUNNING = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ClagRole {
|
|
||||||
CLAG_ROLE_NONE = 0;
|
|
||||||
CLAG_ROLE_PRIMAY = 1;
|
|
||||||
CLAG_ROLE_SECONDARY = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
string peerlink = 1;
|
|
||||||
ClagRole my_role = 2;
|
|
||||||
ClagState peer_state = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ZEBRA_MLAG_VXLAN_UPDATE
|
|
||||||
*
|
|
||||||
* This message will be posted by CLAGD(an external control plane Manager
|
|
||||||
* which is responsible for MCLAG) to inform zebra obout anycast/local
|
|
||||||
* ip updates.
|
|
||||||
*/
|
|
||||||
message ZebraMlagVxlanUpdate {
|
|
||||||
uint32 anycast_ip = 1;
|
|
||||||
uint32 local_ip = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ZebraMlagZebraStatusUpdate
|
|
||||||
*
|
|
||||||
* This message will be posted by CLAGD to advertise FRR state
|
|
||||||
* Change Information to peer
|
|
||||||
*/
|
|
||||||
|
|
||||||
message ZebraMlagZebraStatusUpdate{
|
|
||||||
enum FrrState {
|
|
||||||
FRR_STATE_NONE = 0;
|
|
||||||
FRR_STATE_DOWN = 1;
|
|
||||||
FRR_STATE_UP = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
FrrState peer_frrstate = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ZEBRA_MLAG_MROUTE_ADD & ZEBRA_MLAG_MROUTE_DEL
|
|
||||||
*
|
|
||||||
* These meesages will be sent from PIM (Node-1) to PIM (Node-2) to perform
|
|
||||||
* DF Election for each Mcast flow. Elected DF will forward the tarffic
|
|
||||||
* towards the host and loser will keep the OIL as empty, sothat only single
|
|
||||||
* copy will be sent to host
|
|
||||||
* This message will be posted with any chnage in the params.
|
|
||||||
*
|
|
||||||
* ZEBRA_MLAG_MROUTE_DEL is mainly to delete the record at MLAGD when the
|
|
||||||
* mcast flow is deleted.
|
|
||||||
* key for the MLAGD lookup is (vrf_id, source_ip & group_ip)
|
|
||||||
*/
|
|
||||||
|
|
||||||
message ZebraMlagMrouteAdd {
|
|
||||||
string vrf_name = 1;
|
|
||||||
uint32 source_ip = 2;
|
|
||||||
uint32 group_ip = 3;
|
|
||||||
/*
|
|
||||||
* This is the IGP Cost to reach Configured RP in case of (*,G) or
|
|
||||||
* Cost to the source in case of (S,G) entry
|
|
||||||
*/
|
|
||||||
uint32 cost_to_rp = 4;
|
|
||||||
uint32 owner_id = 5;
|
|
||||||
bool am_i_DR = 6;
|
|
||||||
bool am_i_Dual_active = 7;
|
|
||||||
uint32 vrf_id = 8;
|
|
||||||
string intf_name = 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ZebraMlagMrouteDel {
|
|
||||||
string vrf_name = 1;
|
|
||||||
uint32 source_ip = 2;
|
|
||||||
uint32 group_ip = 3;
|
|
||||||
uint32 owner_id = 4;
|
|
||||||
uint32 vrf_id = 5;
|
|
||||||
string intf_name = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ZebraMlagMrouteAddBulk {
|
|
||||||
repeated ZebraMlagMrouteAdd mroute_add = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ZebraMlagMrouteDelBulk {
|
|
||||||
repeated ZebraMlagMrouteDel mroute_del = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// [END messages]
|
|
|
@ -1,19 +0,0 @@
|
||||||
if HAVE_PROTOBUF
|
|
||||||
lib_LTLIBRARIES += mlag/libmlag_pb.la
|
|
||||||
endif
|
|
||||||
|
|
||||||
mlag_libmlag_pb_la_LDFLAGS = -version-info 0:0:0
|
|
||||||
mlag_libmlag_pb_la_CPPFLAGS = $(AM_CPPFLAGS) $(PROTOBUF_C_CFLAGS)
|
|
||||||
mlag_libmlag_pb_la_SOURCES = \
|
|
||||||
# end
|
|
||||||
|
|
||||||
nodist_mlag_libmlag_pb_la_SOURCES = \
|
|
||||||
mlag/mlag.pb-c.c \
|
|
||||||
# end
|
|
||||||
|
|
||||||
CLEANFILES += \
|
|
||||||
mlag/mlag.pb-c.c \
|
|
||||||
mlag/mlag.pb-c.h \
|
|
||||||
# end
|
|
||||||
|
|
||||||
EXTRA_DIST += mlag/mlag.proto
|
|
|
@ -61,7 +61,6 @@
|
||||||
#include "pim_nht.h"
|
#include "pim_nht.h"
|
||||||
#include "pim_bfd.h"
|
#include "pim_bfd.h"
|
||||||
#include "pim_vxlan.h"
|
#include "pim_vxlan.h"
|
||||||
#include "pim_mlag.h"
|
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
#include "pim_bsm.h"
|
#include "pim_bsm.h"
|
||||||
|
|
||||||
|
@ -7463,9 +7462,9 @@ DEFPY_HIDDEN (interface_ip_pim_activeactive,
|
||||||
|
|
||||||
pim_ifp = ifp->info;
|
pim_ifp = ifp->info;
|
||||||
if (no)
|
if (no)
|
||||||
pim_if_unconfigure_mlag_dualactive(pim_ifp);
|
pim_ifp->activeactive = false;
|
||||||
else
|
else
|
||||||
pim_if_configure_mlag_dualactive(pim_ifp);
|
pim_ifp->activeactive = true;
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -8383,20 +8382,6 @@ DEFUN (no_debug_pim_zebra,
|
||||||
return CMD_SUCCESS;
|
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,
|
DEFUN (debug_pim_vxlan,
|
||||||
debug_pim_vxlan_cmd,
|
debug_pim_vxlan_cmd,
|
||||||
"debug pim vxlan",
|
"debug pim vxlan",
|
||||||
|
@ -10423,8 +10408,6 @@ void pim_cmd_init(void)
|
||||||
install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
|
install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
|
||||||
install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
|
install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
|
||||||
install_element(ENABLE_NODE, &no_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, &debug_pim_vxlan_cmd);
|
||||||
install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd);
|
install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd);
|
||||||
install_element(ENABLE_NODE, &debug_msdp_cmd);
|
install_element(ENABLE_NODE, &debug_msdp_cmd);
|
||||||
|
|
|
@ -54,7 +54,6 @@
|
||||||
#define DEBUG_PIM_PACKETDUMP_RECV_STR "Dump received packets\n"
|
#define DEBUG_PIM_PACKETDUMP_RECV_STR "Dump received packets\n"
|
||||||
#define DEBUG_PIM_TRACE_STR "PIM internal daemon activity\n"
|
#define DEBUG_PIM_TRACE_STR "PIM internal daemon activity\n"
|
||||||
#define DEBUG_PIM_ZEBRA_STR "ZEBRA protocol 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_PIM_VXLAN_STR "PIM VxLAN events\n"
|
||||||
#define DEBUG_SSMPINGD_STR "ssmpingd activity\n"
|
#define DEBUG_SSMPINGD_STR "ssmpingd activity\n"
|
||||||
#define CLEAR_IP_IGMP_STR "IGMP clear commands\n"
|
#define CLEAR_IP_IGMP_STR "IGMP clear commands\n"
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#include "pim_ssmpingd.h"
|
#include "pim_ssmpingd.h"
|
||||||
#include "pim_vty.h"
|
#include "pim_vty.h"
|
||||||
#include "pim_bsm.h"
|
#include "pim_bsm.h"
|
||||||
#include "pim_mlag.h"
|
|
||||||
|
|
||||||
static void pim_instance_terminate(struct pim_instance *pim)
|
static void pim_instance_terminate(struct pim_instance *pim)
|
||||||
{
|
{
|
||||||
|
@ -48,8 +47,6 @@ static void pim_instance_terminate(struct pim_instance *pim)
|
||||||
if (pim->static_routes)
|
if (pim->static_routes)
|
||||||
list_delete(&pim->static_routes);
|
list_delete(&pim->static_routes);
|
||||||
|
|
||||||
pim_instance_mlag_terminate(pim);
|
|
||||||
|
|
||||||
pim_upstream_terminate(pim);
|
pim_upstream_terminate(pim);
|
||||||
|
|
||||||
pim_rp_free(pim);
|
pim_rp_free(pim);
|
||||||
|
@ -118,8 +115,6 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf)
|
||||||
|
|
||||||
pim_upstream_init(pim);
|
pim_upstream_init(pim);
|
||||||
|
|
||||||
pim_instance_mlag_init(pim);
|
|
||||||
|
|
||||||
pim->last_route_change_time = -1;
|
pim->last_route_change_time = -1;
|
||||||
return pim;
|
return pim;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,17 +64,6 @@ struct pim_router {
|
||||||
vrf_id_t vrf_id;
|
vrf_id_t vrf_id;
|
||||||
|
|
||||||
enum mlag_role role;
|
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 */
|
/* Per VRF PIM DB */
|
||||||
|
@ -133,9 +122,6 @@ struct pim_instance {
|
||||||
|
|
||||||
bool ecmp_enable;
|
bool ecmp_enable;
|
||||||
bool ecmp_rebalance_enable;
|
bool ecmp_rebalance_enable;
|
||||||
/* No. of Dual active I/fs in pim_instance */
|
|
||||||
uint32_t inst_mlag_intf_cnt;
|
|
||||||
|
|
||||||
/* Bsm related */
|
/* Bsm related */
|
||||||
struct bsm_scope global_scope;
|
struct bsm_scope global_scope;
|
||||||
uint64_t bsm_rcvd;
|
uint64_t bsm_rcvd;
|
||||||
|
|
|
@ -47,7 +47,6 @@
|
||||||
#include "pim_msdp.h"
|
#include "pim_msdp.h"
|
||||||
#include "pim_iface.h"
|
#include "pim_iface.h"
|
||||||
#include "pim_bfd.h"
|
#include "pim_bfd.h"
|
||||||
#include "pim_mlag.h"
|
|
||||||
#include "pim_errors.h"
|
#include "pim_errors.h"
|
||||||
|
|
||||||
extern struct host host;
|
extern struct host host;
|
||||||
|
@ -132,7 +131,6 @@ int main(int argc, char **argv, char **envp)
|
||||||
pim_ifp_down, pim_ifp_destroy);
|
pim_ifp_down, pim_ifp_destroy);
|
||||||
pim_zebra_init();
|
pim_zebra_init();
|
||||||
pim_bfd_init();
|
pim_bfd_init();
|
||||||
pim_mlag_init();
|
|
||||||
|
|
||||||
frr_config_fork();
|
frr_config_fork();
|
||||||
|
|
||||||
|
|
344
pimd/pim_mlag.c
344
pimd/pim_mlag.c
|
@ -1,344 +0,0 @@
|
||||||
/* PIM 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 "pimd.h"
|
|
||||||
#include "pim_mlag.h"
|
|
||||||
|
|
||||||
extern struct zclient *zclient;
|
|
||||||
|
|
||||||
|
|
||||||
/********************API to process PIM MLAG Data ************************/
|
|
||||||
|
|
||||||
static void pim_mlag_process_mlagd_state_change(struct mlag_status msg)
|
|
||||||
{
|
|
||||||
char buf[80];
|
|
||||||
|
|
||||||
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[80];
|
|
||||||
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, 80),
|
|
||||||
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;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
/* PIM 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 __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);
|
|
||||||
|
|
||||||
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
|
|
|
@ -46,12 +46,11 @@
|
||||||
#include "pim_nht.h"
|
#include "pim_nht.h"
|
||||||
#include "pim_ssm.h"
|
#include "pim_ssm.h"
|
||||||
#include "pim_vxlan.h"
|
#include "pim_vxlan.h"
|
||||||
#include "pim_mlag.h"
|
|
||||||
|
|
||||||
#undef PIM_DEBUG_IFADDR_DUMP
|
#undef PIM_DEBUG_IFADDR_DUMP
|
||||||
#define PIM_DEBUG_IFADDR_DUMP
|
#define PIM_DEBUG_IFADDR_DUMP
|
||||||
|
|
||||||
struct zclient *zclient;
|
static struct zclient *zclient = NULL;
|
||||||
|
|
||||||
|
|
||||||
/* Router-id update message from zebra. */
|
/* Router-id update message from zebra. */
|
||||||
|
@ -588,9 +587,6 @@ void pim_zebra_init(void)
|
||||||
zclient->nexthop_update = pim_parse_nexthop_update;
|
zclient->nexthop_update = pim_parse_nexthop_update;
|
||||||
zclient->vxlan_sg_add = pim_zebra_vxlan_sg_proc;
|
zclient->vxlan_sg_add = pim_zebra_vxlan_sg_proc;
|
||||||
zclient->vxlan_sg_del = 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);
|
zclient_init(zclient, ZEBRA_ROUTE_PIM, 0, &pimd_privs);
|
||||||
if (PIM_DEBUG_PIM_TRACE) {
|
if (PIM_DEBUG_PIM_TRACE) {
|
||||||
|
|
|
@ -115,7 +115,6 @@
|
||||||
#define PIM_MASK_MTRACE (1 << 25)
|
#define PIM_MASK_MTRACE (1 << 25)
|
||||||
#define PIM_MASK_VXLAN (1 << 26)
|
#define PIM_MASK_VXLAN (1 << 26)
|
||||||
#define PIM_MASK_BSM_PROC (1 << 27)
|
#define PIM_MASK_BSM_PROC (1 << 27)
|
||||||
#define PIM_MASK_MLAG (1 << 28)
|
|
||||||
/* Remember 32 bits!!! */
|
/* Remember 32 bits!!! */
|
||||||
|
|
||||||
/* PIM error codes */
|
/* PIM error codes */
|
||||||
|
@ -172,7 +171,6 @@ extern uint8_t qpim_ecmp_rebalance_enable;
|
||||||
#define PIM_DEBUG_IGMP_TRACE_DETAIL \
|
#define PIM_DEBUG_IGMP_TRACE_DETAIL \
|
||||||
(router->debugs & (PIM_MASK_IGMP_TRACE_DETAIL | PIM_MASK_IGMP_TRACE))
|
(router->debugs & (PIM_MASK_IGMP_TRACE_DETAIL | PIM_MASK_IGMP_TRACE))
|
||||||
#define PIM_DEBUG_ZEBRA (router->debugs & PIM_MASK_ZEBRA)
|
#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_SSMPINGD (router->debugs & PIM_MASK_SSMPINGD)
|
||||||
#define PIM_DEBUG_MROUTE (router->debugs & PIM_MASK_MROUTE)
|
#define PIM_DEBUG_MROUTE (router->debugs & PIM_MASK_MROUTE)
|
||||||
#define PIM_DEBUG_MROUTE_DETAIL \
|
#define PIM_DEBUG_MROUTE_DETAIL \
|
||||||
|
@ -219,7 +217,6 @@ extern uint8_t qpim_ecmp_rebalance_enable;
|
||||||
#define PIM_DO_DEBUG_IGMP_TRACE_DETAIL \
|
#define PIM_DO_DEBUG_IGMP_TRACE_DETAIL \
|
||||||
(router->debugs |= PIM_MASK_IGMP_TRACE_DETAIL)
|
(router->debugs |= PIM_MASK_IGMP_TRACE_DETAIL)
|
||||||
#define PIM_DO_DEBUG_ZEBRA (router->debugs |= PIM_MASK_ZEBRA)
|
#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_SSMPINGD (router->debugs |= PIM_MASK_SSMPINGD)
|
||||||
#define PIM_DO_DEBUG_MROUTE (router->debugs |= PIM_MASK_MROUTE)
|
#define PIM_DO_DEBUG_MROUTE (router->debugs |= PIM_MASK_MROUTE)
|
||||||
#define PIM_DO_DEBUG_MROUTE_DETAIL (router->debugs |= PIM_MASK_MROUTE_DETAIL)
|
#define PIM_DO_DEBUG_MROUTE_DETAIL (router->debugs |= PIM_MASK_MROUTE_DETAIL)
|
||||||
|
@ -251,7 +248,6 @@ extern uint8_t qpim_ecmp_rebalance_enable;
|
||||||
#define PIM_DONT_DEBUG_IGMP_TRACE_DETAIL \
|
#define PIM_DONT_DEBUG_IGMP_TRACE_DETAIL \
|
||||||
(router->debugs &= ~PIM_MASK_IGMP_TRACE_DETAIL)
|
(router->debugs &= ~PIM_MASK_IGMP_TRACE_DETAIL)
|
||||||
#define PIM_DONT_DEBUG_ZEBRA (router->debugs &= ~PIM_MASK_ZEBRA)
|
#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_SSMPINGD (router->debugs &= ~PIM_MASK_SSMPINGD)
|
||||||
#define PIM_DONT_DEBUG_MROUTE (router->debugs &= ~PIM_MASK_MROUTE)
|
#define PIM_DONT_DEBUG_MROUTE (router->debugs &= ~PIM_MASK_MROUTE)
|
||||||
#define PIM_DONT_DEBUG_MROUTE_DETAIL (router->debugs &= ~PIM_MASK_MROUTE_DETAIL)
|
#define PIM_DONT_DEBUG_MROUTE_DETAIL (router->debugs &= ~PIM_MASK_MROUTE_DETAIL)
|
||||||
|
|
|
@ -62,7 +62,6 @@ pimd_libpim_a_SOURCES = \
|
||||||
pimd/pim_zebra.c \
|
pimd/pim_zebra.c \
|
||||||
pimd/pim_zlookup.c \
|
pimd/pim_zlookup.c \
|
||||||
pimd/pim_vxlan.c \
|
pimd/pim_vxlan.c \
|
||||||
pimd/pim_mlag.c \
|
|
||||||
pimd/pimd.c \
|
pimd/pimd.c \
|
||||||
# end
|
# end
|
||||||
|
|
||||||
|
@ -115,7 +114,6 @@ noinst_HEADERS += \
|
||||||
pimd/pim_zebra.h \
|
pimd/pim_zebra.h \
|
||||||
pimd/pim_zlookup.h \
|
pimd/pim_zlookup.h \
|
||||||
pimd/pim_vxlan.h \
|
pimd/pim_vxlan.h \
|
||||||
pimd/pim_mlag.h \
|
|
||||||
pimd/pim_vxlan_instance.h \
|
pimd/pim_vxlan_instance.h \
|
||||||
pimd/pimd.h \
|
pimd/pimd.h \
|
||||||
pimd/mtracebis_netlink.h \
|
pimd/mtracebis_netlink.h \
|
||||||
|
|
|
@ -38,9 +38,6 @@ man8 += $(MANBUILD)/zebra.8
|
||||||
endif
|
endif
|
||||||
|
|
||||||
zebra_zebra_LDADD = lib/libfrr.la $(LIBCAP)
|
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_zebra_SOURCES = \
|
||||||
zebra/connected.c \
|
zebra/connected.c \
|
||||||
zebra/debug.c \
|
zebra/debug.c \
|
||||||
|
@ -69,7 +66,6 @@ zebra_zebra_SOURCES = \
|
||||||
zebra/rule_netlink.c \
|
zebra/rule_netlink.c \
|
||||||
zebra/rule_socket.c \
|
zebra/rule_socket.c \
|
||||||
zebra/zebra_mlag.c \
|
zebra/zebra_mlag.c \
|
||||||
zebra/zebra_mlag_private.c \
|
|
||||||
zebra/zebra_l2.c \
|
zebra/zebra_l2.c \
|
||||||
zebra/zebra_memory.c \
|
zebra/zebra_memory.c \
|
||||||
zebra/zebra_dplane.c \
|
zebra/zebra_dplane.c \
|
||||||
|
@ -134,7 +130,6 @@ noinst_HEADERS += \
|
||||||
zebra/rtadv.h \
|
zebra/rtadv.h \
|
||||||
zebra/rule_netlink.h \
|
zebra/rule_netlink.h \
|
||||||
zebra/zebra_mlag.h \
|
zebra/zebra_mlag.h \
|
||||||
zebra/zebra_mlag_private.h \
|
|
||||||
zebra/zebra_fpm_private.h \
|
zebra/zebra_fpm_private.h \
|
||||||
zebra/zebra_l2.h \
|
zebra/zebra_l2.h \
|
||||||
zebra/zebra_dplane.h \
|
zebra/zebra_dplane.h \
|
||||||
|
|
|
@ -2551,9 +2551,6 @@ void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
|
||||||
[ZEBRA_IPTABLE_DELETE] = zread_iptable,
|
[ZEBRA_IPTABLE_DELETE] = zread_iptable,
|
||||||
[ZEBRA_VXLAN_FLOOD_CONTROL] = zebra_vxlan_flood_control,
|
[ZEBRA_VXLAN_FLOOD_CONTROL] = zebra_vxlan_flood_control,
|
||||||
[ZEBRA_VXLAN_SG_REPLAY] = zebra_vxlan_sg_replay,
|
[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)
|
#if defined(HANDLE_ZAPI_FUZZING)
|
||||||
|
|
1367
zebra/zebra_mlag.c
1367
zebra/zebra_mlag.c
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
||||||
/* Zebra mlag header.
|
/* Zebra mlag header.
|
||||||
* Copyright (C) 2019 Cumulus Networks, Inc.
|
* Copyright (C) 2018 Cumulus Networks, Inc.
|
||||||
* Donald Sharp
|
* Donald Sharp
|
||||||
*
|
*
|
||||||
* This file is part of FRR.
|
* This file is part of FRR.
|
||||||
|
@ -23,55 +23,18 @@
|
||||||
#define __ZEBRA_MLAG_H__
|
#define __ZEBRA_MLAG_H__
|
||||||
|
|
||||||
#include "mlag.h"
|
#include "mlag.h"
|
||||||
#include "zclient.h"
|
|
||||||
#include "zebra/zserv.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_PROTOBUF
|
#ifdef __cplusplus
|
||||||
#include "mlag/mlag.pb-c.h"
|
extern "C" {
|
||||||
#endif
|
#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_init(void);
|
||||||
void zebra_mlag_terminate(void);
|
void zebra_mlag_terminate(void);
|
||||||
|
|
||||||
enum mlag_role zebra_mlag_get_role(void);
|
enum mlag_role zebra_mlag_get_role(void);
|
||||||
|
|
||||||
void zebra_mlag_client_register(ZAPI_HANDLER_ARGS);
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
void zebra_mlag_client_unregister(ZAPI_HANDLER_ARGS);
|
#endif
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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*/
|
|
|
@ -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
|
|
|
@ -71,36 +71,6 @@ struct zebra_mlag_info {
|
||||||
|
|
||||||
/* The system mac being used */
|
/* The system mac being used */
|
||||||
struct ethaddr mac;
|
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 {
|
struct zebra_router {
|
||||||
|
|
|
@ -99,13 +99,6 @@ struct zserv {
|
||||||
uint8_t proto;
|
uint8_t proto;
|
||||||
uint16_t instance;
|
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 */
|
/* Statistics */
|
||||||
uint32_t redist_v4_add_cnt;
|
uint32_t redist_v4_add_cnt;
|
||||||
uint32_t redist_v4_del_cnt;
|
uint32_t redist_v4_del_cnt;
|
||||||
|
|
Loading…
Reference in a new issue