]> git.puffer.fish Git - mirror/frr.git/commitdiff
Zebra and bgpd: VRF support for BFD
authorradhika <radhika@cumulusnetworks.com>
Tue, 8 Mar 2016 13:10:56 +0000 (05:10 -0800)
committerradhika <radhika@cumulusnetworks.com>
Tue, 8 Mar 2016 13:10:56 +0000 (05:10 -0800)
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

bgpd/bgp_bfd.c
zebra/zebra_ptm.c
zebra/zebra_ptm.h
zebra/zebra_ptm_null.c
zebra/zebra_ptm_redistribute.c
zebra/zebra_ptm_redistribute.h
zebra/zserv.c

index e61297472326075dd6b0ee2a046564fd57b5fd70..6679206de96c827b64024690d18a57b26e4d20db 100644 (file)
@@ -88,21 +88,25 @@ static void
 bgp_bfd_peer_sendmsg (struct peer *peer, int command)
 {
   struct bfd_info *bfd_info;
+  vrf_id_t vrf_id = VRF_DEFAULT;
 
   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)
     bfd_peer_sendmsg (zclient, bfd_info, AF_INET,
                       &peer->su.sin.sin_addr,
                       (peer->su_local) ? &peer->su_local->sin.sin_addr : 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)
     bfd_peer_sendmsg (zclient, bfd_info, AF_INET6,
                       &peer->su.sin6.sin6_addr,
                       (peer->su_local) ? &peer->su_local->sin6.sin6_addr : 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
                 continue;
 
+              if ((vrf_id != VRF_DEFAULT) && (peer->bgp->vrf_id != vrf_id))
+                continue;
+
               bgp_bfd_peer_status_update(peer, status);
             }
         }
index 039e80ddbbba27eb42fde3eac04d86f67329a354..8e20226cb0485699b119e939ea61b0cfe3f2b79c 100644 (file)
@@ -34,6 +34,7 @@
 #include "buffer.h"
 #include "zebra/zebra_ptm_redistribute.h"
 #include "bfd.h"
+#include "vrf.h"
 
 #define ZEBRA_PTM_RECONNECT_TIME_INITIAL 1 /* initial reconnect is 1s */
 #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_BFDDEST_STR[] = "peer";
 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_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_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_MAX_HOP_CNT_FIELD[] = "maxHopCnt";
 const char ZEBRA_PTM_BFD_SEND_EVENT[] = "sendEvent";
+const char ZEBRA_PTM_BFD_VRF_NAME_FIELD[] = "vrfName";
 
 extern struct zebra_t zebrad;
 
@@ -319,7 +323,7 @@ zebra_ptm_install_commands (void)
 /* BFD session goes down, send message to the protocols. */
 static void
 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)
     {
@@ -336,15 +340,15 @@ if_bfd_session_update (struct interface *ifp, struct prefix *dp,
       else
         {
           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),
                   dp->prefixlen,
                   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
@@ -353,6 +357,7 @@ zebra_ptm_handle_bfd_msg(void *arg, void *in_ctxt, struct interface *ifp)
   char bfdst_str[32];
   char dest_str[64];
   char src_str[64];
+  char vrf_str[64];
   struct prefix dest_prefix;
   struct prefix src_prefix;
 
@@ -378,10 +383,18 @@ zebra_ptm_handle_bfd_msg(void *arg, void *in_ctxt, struct interface *ifp)
     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)
-    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,
-                  dest_str, src_str);
+                  vrf_str, dest_str, src_str);
 
   if (str2prefix(dest_str, &dest_prefix) == 0) {
       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_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 {
-    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;
@@ -540,7 +555,7 @@ zebra_ptm_sock_read (struct thread *thread)
 /* BFD peer/dst register/update */
 int
 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 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 tmp_buf[64];
   int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF;
+  struct zebra_vrf *zvrf;
 
   if (command == ZEBRA_BFD_DEST_UPDATE)
     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);
       ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD,
                           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
     {
@@ -703,7 +727,8 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length,
 
 /* BFD peer/dst deregister */
 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 prefix src_p;
@@ -715,6 +740,7 @@ zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length)
   char tmp_buf[64];
   int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF;
   void *out_ctxt;
+  struct zebra_vrf *zvrf;
 
   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);
         }
 #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
     {
index 6767d822e01a5d3f1c07276bf461a1a117709acd..15a4228298c94e7510d4ac3a9cba73cc32a49ed1 100644 (file)
@@ -57,8 +57,9 @@ void zebra_ptm_write (struct vty *vty);
 int zebra_ptm_get_enable_state(void);
 
 int zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length,
-                                  int command);
-int zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length);
+                                  int command, vrf_id_t vrf_id);
+int zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock,
+                                  u_short length, vrf_id_t vrf_id);
 void
 zebra_ptm_show_status(struct vty *vty, struct interface *ifp);
 #endif
index 293db2e674ff861def2424c5841ca8e8d1b5faa6..4afa2ce522eeaffb914b6d86eb445f209446bb4c 100644 (file)
@@ -24,7 +24,7 @@
 #include "zebra_ptm_redistribute.h"
 
 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; }
 
 void zebra_bfd_peer_replay_req (void)
index 8d033355fe301fd3227ac75f7f8115d7e389721c..8533219d283163330f58121054b1e68f9fbbdc76 100644 (file)
@@ -32,7 +32,7 @@ extern struct zebra_t zebrad;
 static int
 zsend_interface_bfd_update (int cmd, struct zserv *client,
                             struct interface *ifp, struct prefix *dp,
-                            struct prefix *sp, int status)
+                            struct prefix *sp, int status, vrf_id_t vrf_id)
 {
   int blen;
   struct stream *s;
@@ -44,7 +44,7 @@ zsend_interface_bfd_update (int cmd, struct zserv *client,
   s = client->obuf;
   stream_reset (s);
 
-  zserv_create_header (s, cmd, (ifp ? ifp->vrf_id : VRF_DEFAULT));
+  zserv_create_header (s, cmd, vrf_id);
   if (ifp)
     stream_putl (s, ifp->ifindex);
   else
@@ -74,7 +74,7 @@ zsend_interface_bfd_update (int cmd, struct zserv *client,
 
 void
 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 zserv *client;
@@ -88,7 +88,7 @@ zebra_interface_bfd_update (struct interface *ifp, struct prefix *dp,
 
       /* Notify to the protocol daemons. */
       zsend_interface_bfd_update (ZEBRA_INTERFACE_BFD_DEST_UPDATE, client, ifp,
-                                    dp, sp, status);
+                                    dp, sp, status, vrf_id);
     }
 }
 
index d78390e890166d3ac32c749c9200fb98c753ab53..d5aa37d5f86a7610d74628faa249d91553294d8b 100644 (file)
@@ -23,6 +23,6 @@
 #ifndef _ZEBRA_PTM_REDISTRIBUTE_H
 #define _ZEBRA_PTM_REDISTRIBUTE_H
 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);
 #endif /* _ZEBRA_PTM_REDISTRIBUTE_H */
index 9eb53dff0fe2bd6f16bad52f81a559d787da73a0..3d5cbec03cc3ac55a3e5e312a49ac70344092677 100644 (file)
@@ -2068,10 +2068,10 @@ zebra_client_read (struct thread *thread)
       break;
     case ZEBRA_BFD_DEST_UPDATE:
     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;
     case ZEBRA_BFD_DEST_DEREGISTER:
-      zebra_ptm_bfd_dst_deregister(client, sock, length);
+      zebra_ptm_bfd_dst_deregister(client, sock, length, vrf_id);
       break;
     case ZEBRA_VRF_UNREGISTER:
       zread_vrf_unregister (client, length, vrf_id);