Zebra and bgpd: VRF support for BFD

Following changes have been done to support VRF for BFD in zebra and bgpd.
 - Pass the correct VRF value from bgpd to zebra for reg and dereg of BFD destinations.
 - Send the non-default vrf name in reg/dereg messages of multihop destination to BFD/PTM from zebra.

Signed-off-by: Radhika Mahankali <radhika@cumulusnetworks.com>

Ticket: CM-8450
Reviewed By: CCR-4253
Testing Done: Unit, PTM smoke, BGP Smoke
This commit is contained in:
radhika 2016-03-08 05:10:56 -08:00
parent a4c52804ac
commit d553294e09
7 changed files with 63 additions and 22 deletions

View File

@ -88,21 +88,25 @@ static void
bgp_bfd_peer_sendmsg (struct peer *peer, int command) bgp_bfd_peer_sendmsg (struct peer *peer, int command)
{ {
struct bfd_info *bfd_info; struct bfd_info *bfd_info;
vrf_id_t vrf_id = VRF_DEFAULT;
bfd_info = (struct bfd_info *)peer->bfd_info; bfd_info = (struct bfd_info *)peer->bfd_info;
if (peer->bgp && (peer->bgp->inst_type == BGP_INSTANCE_TYPE_VRF))
vrf_id = peer->bgp->vrf_id;
if (peer->su.sa.sa_family == AF_INET) if (peer->su.sa.sa_family == AF_INET)
bfd_peer_sendmsg (zclient, bfd_info, AF_INET, bfd_peer_sendmsg (zclient, bfd_info, AF_INET,
&peer->su.sin.sin_addr, &peer->su.sin.sin_addr,
(peer->su_local) ? &peer->su_local->sin.sin_addr : NULL, (peer->su_local) ? &peer->su_local->sin.sin_addr : NULL,
(peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL, (peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL,
peer->ttl, bgp_bfd_is_peer_multihop(peer), command, 1, VRF_DEFAULT); peer->ttl, bgp_bfd_is_peer_multihop(peer), command, 1, vrf_id);
else if (peer->su.sa.sa_family == AF_INET6) else if (peer->su.sa.sa_family == AF_INET6)
bfd_peer_sendmsg (zclient, bfd_info, AF_INET6, bfd_peer_sendmsg (zclient, bfd_info, AF_INET6,
&peer->su.sin6.sin6_addr, &peer->su.sin6.sin6_addr,
(peer->su_local) ? &peer->su_local->sin6.sin6_addr : NULL, (peer->su_local) ? &peer->su_local->sin6.sin6_addr : NULL,
(peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL, (peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL,
peer->ttl, bgp_bfd_is_peer_multihop(peer), command, 1, VRF_DEFAULT); peer->ttl, bgp_bfd_is_peer_multihop(peer), command, 1, vrf_id);
} }
/* /*
@ -307,6 +311,9 @@ bgp_bfd_dest_update (int command, struct zclient *zclient,
else else
continue; continue;
if ((vrf_id != VRF_DEFAULT) && (peer->bgp->vrf_id != vrf_id))
continue;
bgp_bfd_peer_status_update(peer, status); bgp_bfd_peer_status_update(peer, status);
} }
} }

View File

@ -34,6 +34,7 @@
#include "buffer.h" #include "buffer.h"
#include "zebra/zebra_ptm_redistribute.h" #include "zebra/zebra_ptm_redistribute.h"
#include "bfd.h" #include "bfd.h"
#include "vrf.h"
#define ZEBRA_PTM_RECONNECT_TIME_INITIAL 1 /* initial reconnect is 1s */ #define ZEBRA_PTM_RECONNECT_TIME_INITIAL 1 /* initial reconnect is 1s */
#define ZEBRA_PTM_RECONNECT_TIME_MAX 300 #define ZEBRA_PTM_RECONNECT_TIME_MAX 300
@ -56,8 +57,10 @@ const char ZEBRA_PTM_BFDSTATUS_UP_STR[] = "Up";
const char ZEBRA_PTM_BFDSTATUS_DOWN_STR[] = "Down"; const char ZEBRA_PTM_BFDSTATUS_DOWN_STR[] = "Down";
const char ZEBRA_PTM_BFDDEST_STR[] = "peer"; const char ZEBRA_PTM_BFDDEST_STR[] = "peer";
const char ZEBRA_PTM_BFDSRC_STR[] = "local"; const char ZEBRA_PTM_BFDSRC_STR[] = "local";
const char ZEBRA_PTM_BFDVRF_STR[] = "vrf";
const char ZEBRA_PTM_INVALID_PORT_NAME[] = "N/A"; const char ZEBRA_PTM_INVALID_PORT_NAME[] = "N/A";
const char ZEBRA_PTM_INVALID_SRC_IP[] = "N/A"; const char ZEBRA_PTM_INVALID_SRC_IP[] = "N/A";
const char ZEBRA_PTM_INVALID_VRF[] = "N/A";
const char ZEBRA_PTM_BFD_DST_IP_FIELD[] = "dstIPaddr"; const char ZEBRA_PTM_BFD_DST_IP_FIELD[] = "dstIPaddr";
const char ZEBRA_PTM_BFD_SRC_IP_FIELD[] = "srcIPaddr"; const char ZEBRA_PTM_BFD_SRC_IP_FIELD[] = "srcIPaddr";
@ -70,6 +73,7 @@ const char ZEBRA_PTM_BFD_SEQID_FIELD[] = "seqid";
const char ZEBRA_PTM_BFD_IFNAME_FIELD[] = "ifName"; const char ZEBRA_PTM_BFD_IFNAME_FIELD[] = "ifName";
const char ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD[] = "maxHopCnt"; const char ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD[] = "maxHopCnt";
const char ZEBRA_PTM_BFD_SEND_EVENT[] = "sendEvent"; const char ZEBRA_PTM_BFD_SEND_EVENT[] = "sendEvent";
const char ZEBRA_PTM_BFD_VRF_NAME_FIELD[] = "vrfName";
extern struct zebra_t zebrad; extern struct zebra_t zebrad;
@ -319,7 +323,7 @@ zebra_ptm_install_commands (void)
/* BFD session goes down, send message to the protocols. */ /* BFD session goes down, send message to the protocols. */
static void static void
if_bfd_session_update (struct interface *ifp, struct prefix *dp, if_bfd_session_update (struct interface *ifp, struct prefix *dp,
struct prefix *sp, int status) struct prefix *sp, int status, vrf_id_t vrf_id)
{ {
if (IS_ZEBRA_DEBUG_EVENT) if (IS_ZEBRA_DEBUG_EVENT)
{ {
@ -336,15 +340,15 @@ if_bfd_session_update (struct interface *ifp, struct prefix *dp,
else else
{ {
zlog_debug ("MESSAGE: ZEBRA_INTERFACE_BFD_DEST_UPDATE %s/%d " zlog_debug ("MESSAGE: ZEBRA_INTERFACE_BFD_DEST_UPDATE %s/%d "
"with src %s/%d %s event", "with src %s/%d and vrf %d %s event",
inet_ntop (dp->family, &dp->u.prefix, buf[0], INET6_ADDRSTRLEN), inet_ntop (dp->family, &dp->u.prefix, buf[0], INET6_ADDRSTRLEN),
dp->prefixlen, dp->prefixlen,
inet_ntop (sp->family, &sp->u.prefix, buf[1], INET6_ADDRSTRLEN), inet_ntop (sp->family, &sp->u.prefix, buf[1], INET6_ADDRSTRLEN),
sp->prefixlen, bfd_get_status_str(status)); sp->prefixlen, vrf_id, bfd_get_status_str(status));
} }
} }
zebra_interface_bfd_update (ifp, dp, sp, status); zebra_interface_bfd_update (ifp, dp, sp, status, vrf_id);
} }
static int static int
@ -353,6 +357,7 @@ zebra_ptm_handle_bfd_msg(void *arg, void *in_ctxt, struct interface *ifp)
char bfdst_str[32]; char bfdst_str[32];
char dest_str[64]; char dest_str[64];
char src_str[64]; char src_str[64];
char vrf_str[64];
struct prefix dest_prefix; struct prefix dest_prefix;
struct prefix src_prefix; struct prefix src_prefix;
@ -378,10 +383,18 @@ zebra_ptm_handle_bfd_msg(void *arg, void *in_ctxt, struct interface *ifp)
return -1; return -1;
} }
ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_BFDVRF_STR, vrf_str);
if (vrf_str[0] == '\0') {
zlog_debug("%s: Key %s not found in PTM msg", __func__,
ZEBRA_PTM_BFDVRF_STR);
return -1;
}
if (IS_ZEBRA_DEBUG_EVENT) if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("%s: Recv Port [%s] bfd status [%s] peer [%s] local [%s]", zlog_debug("%s: Recv Port [%s] bfd status [%s] vrf [%s] peer [%s] local [%s]",
__func__, ifp ? ifp->name : "N/A", bfdst_str, __func__, ifp ? ifp->name : "N/A", bfdst_str,
dest_str, src_str); vrf_str, dest_str, src_str);
if (str2prefix(dest_str, &dest_prefix) == 0) { if (str2prefix(dest_str, &dest_prefix) == 0) {
zlog_err("%s: Peer addr %s not found", __func__, zlog_err("%s: Peer addr %s not found", __func__,
@ -399,9 +412,11 @@ zebra_ptm_handle_bfd_msg(void *arg, void *in_ctxt, struct interface *ifp)
} }
if (!strcmp (bfdst_str, ZEBRA_PTM_BFDSTATUS_DOWN_STR)) { if (!strcmp (bfdst_str, ZEBRA_PTM_BFDSTATUS_DOWN_STR)) {
if_bfd_session_update(ifp, &dest_prefix, &src_prefix, BFD_STATUS_DOWN); if_bfd_session_update(ifp, &dest_prefix, &src_prefix, BFD_STATUS_DOWN,
vrf_name_to_id(vrf_str));
} else { } else {
if_bfd_session_update(ifp, &dest_prefix, &src_prefix, BFD_STATUS_UP); if_bfd_session_update(ifp, &dest_prefix, &src_prefix, BFD_STATUS_UP,
vrf_name_to_id(vrf_str));
} }
return 0; return 0;
@ -540,7 +555,7 @@ zebra_ptm_sock_read (struct thread *thread)
/* BFD peer/dst register/update */ /* BFD peer/dst register/update */
int int
zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length, zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length,
int command) int command, vrf_id_t vrf_id)
{ {
struct stream *s; struct stream *s;
struct prefix src_p; struct prefix src_p;
@ -556,6 +571,7 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length,
char buf[INET6_ADDRSTRLEN]; char buf[INET6_ADDRSTRLEN];
char tmp_buf[64]; char tmp_buf[64];
int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF; int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF;
struct zebra_vrf *zvrf;
if (command == ZEBRA_BFD_DEST_UPDATE) if (command == ZEBRA_BFD_DEST_UPDATE)
client->bfd_peer_upd8_cnt++; client->bfd_peer_upd8_cnt++;
@ -652,6 +668,14 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length,
sprintf(tmp_buf, "%d", multi_hop_cnt); sprintf(tmp_buf, "%d", multi_hop_cnt);
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD, ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD,
tmp_buf); tmp_buf);
if (vrf_id)
{
zvrf = vrf_info_lookup (vrf_id);
if (zvrf)
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_VRF_NAME_FIELD,
zvrf->name);
}
} }
else else
{ {
@ -703,7 +727,8 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length,
/* BFD peer/dst deregister */ /* BFD peer/dst deregister */
int int
zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length) zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length,
vrf_id_t vrf_id)
{ {
struct stream *s; struct stream *s;
struct prefix src_p; struct prefix src_p;
@ -715,6 +740,7 @@ zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length)
char tmp_buf[64]; char tmp_buf[64];
int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF; int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF;
void *out_ctxt; void *out_ctxt;
struct zebra_vrf *zvrf;
client->bfd_peer_del_cnt++; client->bfd_peer_del_cnt++;
@ -794,6 +820,13 @@ zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length)
ZEBRA_PTM_BFD_SRC_IP_FIELD, buf); ZEBRA_PTM_BFD_SRC_IP_FIELD, buf);
} }
#endif /* HAVE_IPV6 */ #endif /* HAVE_IPV6 */
if (vrf_id)
{
zvrf = vrf_info_lookup (vrf_id);
if (zvrf)
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_VRF_NAME_FIELD,
zvrf->name);
}
} }
else else
{ {

View File

@ -57,8 +57,9 @@ void zebra_ptm_write (struct vty *vty);
int zebra_ptm_get_enable_state(void); int zebra_ptm_get_enable_state(void);
int zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length, int zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length,
int command); int command, vrf_id_t vrf_id);
int zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length); int zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock,
u_short length, vrf_id_t vrf_id);
void void
zebra_ptm_show_status(struct vty *vty, struct interface *ifp); zebra_ptm_show_status(struct vty *vty, struct interface *ifp);
#endif #endif

View File

@ -24,7 +24,7 @@
#include "zebra_ptm_redistribute.h" #include "zebra_ptm_redistribute.h"
void zebra_interface_bfd_update (struct interface *a, struct prefix *dp, void zebra_interface_bfd_update (struct interface *a, struct prefix *dp,
struct prefix *sp, int status) struct prefix *sp, int status, vrf_id_t vrf_id)
{ return; } { return; }
void zebra_bfd_peer_replay_req (void) void zebra_bfd_peer_replay_req (void)

View File

@ -32,7 +32,7 @@ extern struct zebra_t zebrad;
static int static int
zsend_interface_bfd_update (int cmd, struct zserv *client, zsend_interface_bfd_update (int cmd, struct zserv *client,
struct interface *ifp, struct prefix *dp, struct interface *ifp, struct prefix *dp,
struct prefix *sp, int status) struct prefix *sp, int status, vrf_id_t vrf_id)
{ {
int blen; int blen;
struct stream *s; struct stream *s;
@ -44,7 +44,7 @@ zsend_interface_bfd_update (int cmd, struct zserv *client,
s = client->obuf; s = client->obuf;
stream_reset (s); stream_reset (s);
zserv_create_header (s, cmd, (ifp ? ifp->vrf_id : VRF_DEFAULT)); zserv_create_header (s, cmd, vrf_id);
if (ifp) if (ifp)
stream_putl (s, ifp->ifindex); stream_putl (s, ifp->ifindex);
else else
@ -74,7 +74,7 @@ zsend_interface_bfd_update (int cmd, struct zserv *client,
void void
zebra_interface_bfd_update (struct interface *ifp, struct prefix *dp, zebra_interface_bfd_update (struct interface *ifp, struct prefix *dp,
struct prefix *sp, int status) struct prefix *sp, int status, vrf_id_t vrf_id)
{ {
struct listnode *node, *nnode; struct listnode *node, *nnode;
struct zserv *client; struct zserv *client;
@ -88,7 +88,7 @@ zebra_interface_bfd_update (struct interface *ifp, struct prefix *dp,
/* Notify to the protocol daemons. */ /* Notify to the protocol daemons. */
zsend_interface_bfd_update (ZEBRA_INTERFACE_BFD_DEST_UPDATE, client, ifp, zsend_interface_bfd_update (ZEBRA_INTERFACE_BFD_DEST_UPDATE, client, ifp,
dp, sp, status); dp, sp, status, vrf_id);
} }
} }

View File

@ -23,6 +23,6 @@
#ifndef _ZEBRA_PTM_REDISTRIBUTE_H #ifndef _ZEBRA_PTM_REDISTRIBUTE_H
#define _ZEBRA_PTM_REDISTRIBUTE_H #define _ZEBRA_PTM_REDISTRIBUTE_H
extern void zebra_interface_bfd_update (struct interface *, struct prefix *, extern void zebra_interface_bfd_update (struct interface *, struct prefix *,
struct prefix *, int); struct prefix *, int, vrf_id_t);
extern void zebra_bfd_peer_replay_req (void); extern void zebra_bfd_peer_replay_req (void);
#endif /* _ZEBRA_PTM_REDISTRIBUTE_H */ #endif /* _ZEBRA_PTM_REDISTRIBUTE_H */

View File

@ -2068,10 +2068,10 @@ zebra_client_read (struct thread *thread)
break; break;
case ZEBRA_BFD_DEST_UPDATE: case ZEBRA_BFD_DEST_UPDATE:
case ZEBRA_BFD_DEST_REGISTER: case ZEBRA_BFD_DEST_REGISTER:
zebra_ptm_bfd_dst_register(client, sock, length, command); zebra_ptm_bfd_dst_register(client, sock, length, command, vrf_id);
break; break;
case ZEBRA_BFD_DEST_DEREGISTER: case ZEBRA_BFD_DEST_DEREGISTER:
zebra_ptm_bfd_dst_deregister(client, sock, length); zebra_ptm_bfd_dst_deregister(client, sock, length, vrf_id);
break; break;
case ZEBRA_VRF_UNREGISTER: case ZEBRA_VRF_UNREGISTER:
zread_vrf_unregister (client, length, vrf_id); zread_vrf_unregister (client, length, vrf_id);