]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: pim bfd support 576/head
authorChirag Shah <chirag@cumulusnetworks.com>
Tue, 11 Apr 2017 01:01:53 +0000 (18:01 -0700)
committerChirag Shah <chirag@cumulusnetworks.com>
Thu, 18 May 2017 05:42:28 +0000 (22:42 -0700)
All PIM Neighbors for a given pim interface is registered with
BFD.
Upon receiving BFD status down event, PIM Neighbor with BFD info is deleted.
Add pim bfd configuraiton (CLI) per interface, '[no] ip pim bfd'

Testing Done:
Configure BFD under PIM interface on all neighbor routers,
check bfd sessions up, remote end unconfigure BFD, results in BFD session down.
Previous state was UP to New state DOWN, results in PIM neighbor delete behind
that particular pim interface.
Pim-smoke Results:
Ran 94 tests in 7409.680s
FAILED (SKIP=8, failures=2)

Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
15 files changed:
pimd/Makefile.am
pimd/pim_bfd.c [new file with mode: 0644]
pimd/pim_bfd.h [new file with mode: 0644]
pimd/pim_cmd.c
pimd/pim_iface.h
pimd/pim_main.c
pimd/pim_neighbor.c
pimd/pim_neighbor.h
pimd/pim_upstream.h
pimd/pim_vty.c
pimd/pim_zebra.c
pimd/pimd.c
zebra/client_main.c
zebra/zebra_ptm.c
zebra/zebra_ptm_redistribute.c

index 77eb5c7568f628905fe8ac9af5f9719f1635b490..0dd6c569dcb9d75098a6523a21a05db459572dc4 100644 (file)
@@ -53,7 +53,7 @@ libpim_a_SOURCES = \
        pim_ssmpingd.c pim_int.c pim_rp.c \
        pim_static.c pim_br.c pim_register.c pim_routemap.c \
        pim_msdp.c pim_msdp_socket.c pim_msdp_packet.c \
-       pim_jp_agg.c pim_nht.c pim_ssm.c
+       pim_jp_agg.c pim_nht.c pim_ssm.c pim_bfd.c
 
 noinst_HEADERS = \
        pim_memory.h \
@@ -66,7 +66,7 @@ noinst_HEADERS = \
        pim_igmp_join.h pim_ssmpingd.h pim_int.h pim_rp.h \
        pim_static.h pim_br.h pim_register.h \
        pim_msdp.h pim_msdp_socket.h pim_msdp_packet.h pim_nht.h \
-       pim_jp_agg.h pim_ssm.h
+       pim_jp_agg.h pim_ssm.h pim_bfd.h
 
 pimd_SOURCES = \
        pim_main.c $(libpim_a_SOURCES)
diff --git a/pimd/pim_bfd.c b/pimd/pim_bfd.c
new file mode 100644 (file)
index 0000000..5c10df3
--- /dev/null
@@ -0,0 +1,360 @@
+/*
+ * pim_bfd.c: PIM BFD handling routines
+ *
+ * Copyright (C) 2017 Cumulus Networks, Inc.
+ * Chirag Shah
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; see the file COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "lib/json.h"
+#include "command.h"
+#include "vty.h"
+#include "zclient.h"
+
+#include "pim_cmd.h"
+#include "pim_vty.h"
+#include "pim_iface.h"
+#include "pim_bfd.h"
+#include "bfd.h"
+#include "pimd.h"
+#include "pim_zebra.h"
+
+/*
+ * pim_bfd_write_config - Write the interface BFD configuration.
+ */
+void
+pim_bfd_write_config (struct vty *vty, struct interface *ifp)
+{
+  struct pim_interface *pim_ifp = ifp->info;
+  struct bfd_info *bfd_info = NULL;
+
+  if (!pim_ifp)
+    return;
+  bfd_info = (struct bfd_info *) pim_ifp->bfd_info;
+  if (!bfd_info)
+    {
+      zlog_debug ("%s: interface %s bfd_info is NULL ", __PRETTY_FUNCTION__,
+                  ifp->name);
+      return;
+    }
+  if (CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG))
+    vty_out (vty, " ip pim bfd %d %d %d%s",
+             bfd_info->detect_mult, bfd_info->required_min_rx,
+             bfd_info->desired_min_tx, VTY_NEWLINE);
+  else
+    vty_out (vty, " ip pim bfd%s", VTY_NEWLINE);
+}
+
+/*
+ * pim_bfd_show_info - Show BFD info structure
+ */
+void
+pim_bfd_show_info (struct vty *vty, void *bfd_info, json_object * json_obj,
+                   u_char use_json, int param_only)
+{
+  if (param_only)
+    bfd_show_param (vty, (struct bfd_info *) bfd_info, 1, 0, use_json,
+                    json_obj);
+  else
+    bfd_show_info (vty, (struct bfd_info *) bfd_info, 0, 1, use_json,
+                   json_obj);
+}
+
+/*
+ * pim_bfd_info_nbr_create - Create/update BFD information for a neighbor.
+ */
+void
+pim_bfd_info_nbr_create (struct pim_interface *pim_ifp,
+                         struct pim_neighbor *neigh)
+{
+  struct bfd_info *nbr_bfd_info = NULL;
+
+  /* Check if Pim Interface BFD is enabled */
+  if (!pim_ifp || !pim_ifp->bfd_info)
+    return;
+
+  if (!neigh->bfd_info)
+    neigh->bfd_info = bfd_info_create ();
+
+  if (!neigh->bfd_info)
+    return;
+  zlog_debug ("%s: bfd_info ", __PRETTY_FUNCTION__);
+
+  nbr_bfd_info = (struct bfd_info *) neigh->bfd_info;
+  nbr_bfd_info->detect_mult = pim_ifp->bfd_info->detect_mult;
+  nbr_bfd_info->desired_min_tx = pim_ifp->bfd_info->desired_min_tx;
+  nbr_bfd_info->required_min_rx = pim_ifp->bfd_info->required_min_rx;
+}
+
+/*
+ * pim_bfd_info_free - Free BFD info structure
+ */
+void
+pim_bfd_info_free (void **bfd_info)
+{
+  bfd_info_free ((struct bfd_info **) bfd_info);
+}
+
+static void
+pim_bfd_reg_dereg_nbr (struct pim_neighbor *nbr, int command)
+{
+  struct pim_interface *pim_ifp = NULL;
+  struct bfd_info *bfd_info = NULL;
+  struct zclient *zclient = NULL;
+
+  zclient = pim_zebra_zclient_get ();
+
+  if (!nbr)
+    return;
+  pim_ifp = nbr->interface->info;
+  bfd_info = (struct bfd_info *) pim_ifp->bfd_info;
+  if (!bfd_info)
+    return;
+  if (PIM_DEBUG_PIM_TRACE)
+    {
+      char str[INET_ADDRSTRLEN];
+      pim_inet4_dump ("<bfd_nbr?>", nbr->source_addr, str, sizeof (str));
+      zlog_debug ("%s Nbr %s %s with BFD", __PRETTY_FUNCTION__, str,
+              bfd_get_command_dbg_str (command));
+    }
+  bfd_peer_sendmsg (zclient, bfd_info, AF_INET,
+                    &nbr->source_addr, NULL, nbr->interface->name,
+                    0, 0, command, 0, VRF_DEFAULT);
+}
+
+/*
+ * pim_bfd_reg_dereg_all_nbr - Register/Deregister all neighbors associated
+ *                              with a interface with BFD through
+ *                              zebra for starting/stopping the monitoring of
+ *                              the neighbor rechahability.
+ */
+int
+pim_bfd_reg_dereg_all_nbr (struct interface *ifp, int command)
+{
+  struct pim_interface *pim_ifp = NULL;
+  struct listnode *node = NULL;
+  struct pim_neighbor *neigh = NULL;
+
+  pim_ifp = ifp->info;
+  if (!pim_ifp)
+    return -1;
+  if (!pim_ifp->bfd_info)
+    return -1;
+
+  for (ALL_LIST_ELEMENTS_RO (pim_ifp->pim_neighbor_list, node, neigh))
+    {
+      if (command != ZEBRA_BFD_DEST_DEREGISTER)
+        pim_bfd_info_nbr_create (pim_ifp, neigh);
+      else
+        bfd_info_free ((struct bfd_info **) &neigh->bfd_info);
+
+      pim_bfd_reg_dereg_nbr (neigh, command);
+    }
+
+  return 0;
+}
+
+/*
+ * pim_bfd_trigger_event - Neighbor is registered/deregistered with BFD when
+ *                          neighbor state is changed to/from 2way.
+ */
+void
+pim_bfd_trigger_event (struct pim_interface *pim_ifp, struct pim_neighbor *nbr, uint8_t nbr_up)
+{
+  if (nbr_up)
+    {
+      pim_bfd_info_nbr_create (pim_ifp, nbr);
+      pim_bfd_reg_dereg_nbr (nbr, ZEBRA_BFD_DEST_REGISTER);
+    }
+  else
+    {
+      pim_bfd_info_free ((void *)&nbr->bfd_info);
+      pim_bfd_reg_dereg_nbr (nbr, ZEBRA_BFD_DEST_DEREGISTER);
+    }
+}
+
+/*
+ * pim_bfd_if_param_set - Set the configured BFD paramter values for
+ *                         interface.
+ */
+void
+pim_bfd_if_param_set (struct interface *ifp, u_int32_t min_rx,
+                      u_int32_t min_tx, u_int8_t detect_mult, int defaults)
+{
+  struct pim_interface *pim_ifp = ifp->info;
+  int command = 0;
+
+  bfd_set_param ((struct bfd_info **) &(pim_ifp->bfd_info), min_rx, min_tx,
+                 detect_mult, defaults, &command);
+
+  if (pim_ifp->bfd_info)
+    {
+      if (PIM_DEBUG_PIM_TRACE)
+        zlog_debug ("%s: interface %s has bfd_info", __PRETTY_FUNCTION__,
+                    ifp->name);
+    }
+  if (command)
+    pim_bfd_reg_dereg_all_nbr (ifp, command);
+}
+
+
+/*
+ * pim_bfd_interface_dest_update - Find the neighbor for which the BFD status
+ *                                  has changed and bring down the neighbor
+ *                                  connectivity if the BFD status changed to
+ *                                  down.
+ */
+static int
+pim_bfd_interface_dest_update (int command, struct zclient *zclient,
+                               zebra_size_t length, vrf_id_t vrf_id)
+{
+  struct interface *ifp = NULL;
+  struct pim_interface *pim_ifp = NULL;
+  struct prefix p;
+  int status;
+  char msg[100];
+  int old_status;
+  struct bfd_info *bfd_info = NULL;
+  struct timeval tv;
+  struct listnode *neigh_node = NULL;
+  struct listnode *neigh_nextnode = NULL;
+  struct pim_neighbor *neigh = NULL;
+
+  ifp = bfd_get_peer_info (zclient->ibuf, &p, NULL, &status, vrf_id);
+
+  if ((ifp == NULL) || (p.family != AF_INET))
+    return 0;
+
+  pim_ifp = ifp->info;
+  if (!pim_ifp)
+    return 0;
+
+  if (!pim_ifp->bfd_info)
+    {
+      if (PIM_DEBUG_PIM_TRACE)
+        zlog_debug ("%s: pim interface %s BFD is disabled ", __PRETTY_FUNCTION__,
+                    ifp->name);
+      return 0;
+    }
+
+  if (PIM_DEBUG_PIM_TRACE)
+    {
+      char buf[PREFIX2STR_BUFFER];
+      prefix2str (&p, buf, sizeof (buf));
+      zlog_debug ("%s: interface %s bfd destination %s %s",
+                  __PRETTY_FUNCTION__, ifp->name, buf,
+                  bfd_get_status_str (status));
+    }
+
+  for (ALL_LIST_ELEMENTS (pim_ifp->pim_neighbor_list, neigh_node,
+                          neigh_nextnode, neigh))
+    {
+      bfd_info = (struct bfd_info *) neigh->bfd_info;
+      if (bfd_info->status == status)
+        {
+          if (PIM_DEBUG_PIM_TRACE)
+            {
+              char str[INET_ADDRSTRLEN];
+              pim_inet4_dump ("<nht_nbr?>", neigh->source_addr, str,
+                              sizeof (str));
+              zlog_debug ("%s: bfd status is same for nbr %s",
+                          __PRETTY_FUNCTION__, str);
+            }
+          continue;
+        }
+      old_status = bfd_info->status;
+      bfd_info->status = status;
+      monotime(&tv);
+      bfd_info->last_update = tv.tv_sec;
+
+      if (PIM_DEBUG_PIM_TRACE)
+        {
+          zlog_debug ("%s: status %s old_status %s", __PRETTY_FUNCTION__,
+                      bfd_get_status_str (status),
+                      bfd_get_status_str (old_status));
+        }
+      if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP))
+        {
+          snprintf (msg, sizeof (msg), "BFD Session Expired");
+          pim_neighbor_delete (ifp, neigh, msg);
+        }
+    }
+  return 0;
+}
+
+/*
+ * pim_bfd_nbr_replay - Replay all the neighbors that have BFD enabled
+ *                       to zebra
+ */
+static int
+pim_bfd_nbr_replay (int command, struct zclient *zclient, zebra_size_t length,
+                    vrf_id_t vrf_id)
+{
+  struct interface *ifp = NULL;
+  struct pim_interface *pim_ifp = NULL;
+  struct pim_neighbor *neigh = NULL;
+  struct listnode *node;
+  struct listnode *neigh_node;
+  struct listnode *neigh_nextnode;
+
+  /* Send the client registration */
+  bfd_client_sendmsg (zclient, ZEBRA_BFD_CLIENT_REGISTER);
+
+  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
+    {
+      pim_ifp = ifp->info;
+
+      if (!pim_ifp)
+        continue;
+
+      if (pim_ifp->pim_sock_fd < 0)
+        continue;
+
+      for (ALL_LIST_ELEMENTS (pim_ifp->pim_neighbor_list, neigh_node,
+                              neigh_nextnode, neigh))
+        {
+          if (!neigh->bfd_info)
+            continue;
+          if (PIM_DEBUG_PIM_TRACE)
+            {
+              char str[INET_ADDRSTRLEN];
+              pim_inet4_dump ("<bfd_nbr?>", neigh->source_addr, str,
+                              sizeof (str));
+              zlog_debug ("%s: Replaying Pim Neigh %s to BFD",
+                          __PRETTY_FUNCTION__, str);
+            }
+          pim_bfd_reg_dereg_nbr (neigh, ZEBRA_BFD_DEST_UPDATE);
+
+        }
+    }
+  return 0;
+}
+
+void
+pim_bfd_init (void)
+{
+  struct zclient *zclient = NULL;
+
+  zclient = pim_zebra_zclient_get ();
+
+  bfd_gbl_init ();
+
+  zclient->interface_bfd_dest_update = pim_bfd_interface_dest_update;
+  zclient->bfd_dest_replay = pim_bfd_nbr_replay;
+}
diff --git a/pimd/pim_bfd.h b/pimd/pim_bfd.h
new file mode 100644 (file)
index 0000000..23f286b
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * pim_bfd.h: PIM BFD definitions and structures
+ *
+ * Copyright (C) 2017 Cumulus Networks, Inc.
+ * Chirag Shah
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; see the file COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef PIM_BFD_H
+#define PIM_BFD_H
+
+#include "if.h"
+
+void pim_bfd_init (void);
+void pim_bfd_write_config (struct vty *vty, struct interface *ifp);
+void
+pim_bfd_show_info (struct vty *vty, void *bfd_info, json_object * json_obj,
+                   u_char use_json, int param_only);
+void
+pim_bfd_if_param_set (struct interface *ifp, u_int32_t min_rx,
+                      u_int32_t min_tx, u_int8_t detect_mult, int defaults);
+int pim_bfd_reg_dereg_all_nbr (struct interface *ifp, int command);
+void
+pim_bfd_trigger_event (struct pim_interface *pim_ifp, struct pim_neighbor *nbr, uint8_t nbr_up);
+void
+pim_bfd_info_nbr_create (struct pim_interface *pim_ifp, struct pim_neighbor *neigh);
+void pim_bfd_info_free(void **bfd_info);
+#endif /* _PIM_BFD_H */
index da07dcb4acbe769021e4045eceb8378ba00b21a6..60b0b9bf2e0af64740659b5670f2dc0d5b209981 100644 (file)
@@ -57,6 +57,8 @@
 #include "pim_msdp.h"
 #include "pim_ssm.h"
 #include "pim_nht.h"
+#include "pim_bfd.h"
+#include "bfd.h"
 
 static struct cmd_node pim_global_node = {
   PIM_NODE,
@@ -1508,6 +1510,7 @@ static void pim_show_neighbors_single(struct vty *vty, const char *neighbor, u_c
         vty_out(vty, "    Hello Option - Holdtime        : %s%s", option_holdtime ? "yes" : "no", VTY_NEWLINE);
         vty_out(vty, "    Hello Option - LAN Prune Delay : %s%s", option_lan_prune_delay ? "yes" : "no", VTY_NEWLINE);
         vty_out(vty, "    Hello Option - T-bit           : %s%s", option_t_bit ? "yes" : "no", VTY_NEWLINE);
+        pim_bfd_show_info (vty, neigh->bfd_info, json_ifp, uj, 0);
         vty_out(vty, "%s", VTY_NEWLINE);
       }
     }
@@ -5927,6 +5930,99 @@ DEFUN (interface_no_pim_use_source,
   return interface_pim_use_src_cmd_worker (vty, "0.0.0.0");
 }
 
+DEFUN (ip_pim_bfd,
+       ip_pim_bfd_cmd,
+       "ip pim bfd",
+       IP_STR
+       PIM_STR
+       "Enables BFD support\n")
+{
+  VTY_DECLVAR_CONTEXT(interface, ifp);
+  struct pim_interface *pim_ifp = NULL;
+  struct bfd_info *bfd_info = NULL;
+
+  if (!ifp)
+    return CMD_SUCCESS;
+  pim_ifp = ifp->info;
+  if (!pim_ifp)
+    return CMD_SUCCESS;
+  bfd_info = pim_ifp->bfd_info;
+
+  if (!bfd_info || !CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG))
+    pim_bfd_if_param_set (ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
+                          BFD_DEF_DETECT_MULT, 1);
+
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_ip_pim_bfd,
+       no_ip_pim_bfd_cmd,
+       "no ip pim bfd",
+       NO_STR
+       IP_STR
+       PIM_STR
+       "Disables BFD support\n")
+{
+  VTY_DECLVAR_CONTEXT(interface, ifp);
+  struct pim_interface *pim_ifp = NULL;
+
+  assert (ifp);
+
+  pim_ifp = ifp->info;
+  if (!pim_ifp)
+    return CMD_SUCCESS;
+
+  if (pim_ifp->bfd_info)
+    {
+      pim_bfd_reg_dereg_all_nbr (ifp, ZEBRA_BFD_DEST_DEREGISTER);
+      bfd_info_free (&(pim_ifp->bfd_info));
+    }
+
+  return CMD_SUCCESS;
+}
+
+DEFUN (ip_pim_bfd_param,
+       ip_pim_bfd_param_cmd,
+       "ip pim bfd (2-255) (50-60000) (50-60000)",
+       IP_STR
+       PIM_STR
+       "Enables BFD support\n"
+       "Detect Multiplier\n"
+       "Required min receive interval\n"
+       "Desired min transmit interval\n")
+{
+  VTY_DECLVAR_CONTEXT(interface, ifp);
+  int idx_number = 3;
+  int idx_number_2 = 4;
+  int idx_number_3 = 5;
+  u_int32_t rx_val;
+  u_int32_t tx_val;
+  u_int8_t dm_val;
+  int ret;
+
+
+  if ((ret = bfd_validate_param (vty, argv[idx_number]->arg,
+                                 argv[idx_number_2]->arg,
+                                 argv[idx_number_3]->arg,
+                                 &dm_val, &rx_val, &tx_val)) != CMD_SUCCESS)
+    return ret;
+
+  pim_bfd_if_param_set (ifp, rx_val, tx_val, dm_val, 0);
+
+  return CMD_SUCCESS;
+}
+
+ALIAS (no_ip_pim_bfd,
+       no_ip_pim_bfd_param_cmd,
+       "no ip pim bfd (2-255) (50-60000) (50-60000)",
+       NO_STR
+       IP_STR
+       PIM_STR
+       "Enables BFD support\n"
+       "Detect Multiplier\n"
+       "Required min receive interval\n"
+       "Desired min transmit interval\n")
+
 static int
 ip_msdp_peer_cmd_worker (struct vty *vty, const char *peer, const char *local)
 {
@@ -6910,4 +7006,9 @@ void pim_cmd_init()
   install_element (VIEW_NODE, &show_ip_pim_group_type_cmd);
   install_element (INTERFACE_NODE, &interface_pim_use_source_cmd);
   install_element (INTERFACE_NODE, &interface_no_pim_use_source_cmd);
+  /* Install BFD command */
+  install_element (INTERFACE_NODE, &ip_pim_bfd_cmd);
+  install_element (INTERFACE_NODE, &ip_pim_bfd_param_cmd);
+  install_element (INTERFACE_NODE, &no_ip_pim_bfd_cmd);
+  install_element (INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
 }
index fa623d45b4beb2c88994859c3f8fd5acab62d059..a1c2b692f4a5be6029d39ae4bafe5688d6186863 100644 (file)
 
 #include "if.h"
 #include "vty.h"
+#include "vrf.h"
+#include "zclient.h"
 
 #include "pim_igmp.h"
 #include "pim_upstream.h"
+#include "bfd.h"
 
 #define PIM_IF_MASK_PIM                             (1 << 0)
 #define PIM_IF_MASK_IGMP                            (1 << 1)
@@ -127,6 +130,7 @@ struct pim_interface {
   uint32_t       pim_ifstat_reg_stop_send;
   uint32_t       pim_ifstat_assert_recv;
   uint32_t       pim_ifstat_assert_send;
+  struct bfd_info *bfd_info;
 };
 
 extern struct interface *pim_regiface;
index 19dcd3aa9a7f5dd99002d9a49037e50e3931fd49..a80059535d1a7e387fe2bdc9697ba93eaea3b28b 100644 (file)
@@ -45,6 +45,7 @@
 #include "pim_zebra.h"
 #include "pim_msdp.h"
 #include "pim_iface.h"
+#include "pim_bfd.h"
 
 extern struct host host;
 
@@ -129,6 +130,7 @@ int main(int argc, char** argv, char** envp) {
    * Initialize zclient "update" and "lookup" sockets
    */
   pim_zebra_init();
+  pim_bfd_init ();
 
   frr_config_fork();
 
index 00190bd83063d251b3f92eb9b48f84e49a0a9684..dede8e198f281a8dbe3b879d3b68badf708396e7 100644 (file)
@@ -38,6 +38,7 @@
 #include "pim_zebra.h"
 #include "pim_join.h"
 #include "pim_jp_agg.h"
+#include "pim_bfd.h"
 
 static void dr_election_by_addr(struct interface *ifp)
 {
@@ -379,6 +380,9 @@ static struct pim_neighbor *pim_neighbor_new(struct interface *ifp,
     ++pim_ifp->pim_dr_num_nondrpri_neighbors; 
   }
 
+  //Register PIM Neighbor with BFD
+  pim_bfd_trigger_event (pim_ifp, neigh, 1);
+
   return neigh;
 }
 
@@ -682,6 +686,9 @@ void pim_neighbor_delete(struct interface *ifp,
               src_str, ifp->name);
   }
 
+  //De-Register PIM Neighbor with BFD
+  pim_bfd_trigger_event (pim_ifp, neigh, 0);
+
   listnode_delete(pim_ifp->pim_neighbor_list, neigh);
 
   pim_neighbor_free(neigh);
index a3d39d26224e36e6a02d9c4fe1a23dd64d455f27..eaaefd8fef3668de2a1950e980c986853fe5de62 100644 (file)
@@ -43,6 +43,7 @@ struct pim_neighbor {
 
   struct thread     *jp_timer;
   struct list       *upstream_jp_agg;
+  struct bfd_info   *bfd_info;
 };
 
 void pim_neighbor_timer_reset(struct pim_neighbor *neigh, uint16_t holdtime);
index 1de8adcc02e3e76d1d7300eaf4ee28ff9ba68687..ad9e360feb23594a6559f9a3e6c2b4ad4fd50170 100644 (file)
 
 #include <zebra.h>
 #include <prefix.h>
+#include "plist.h"
 
 #include <pimd/pim_rpf.h>
+#include "pim_str.h"
+#include "pim_ifchannel.h"
 
 #define PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED         (1 << 0)
 #define PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED (1 << 1)
index 9cf5c30469a8bdf9e76931a63c5a81e88bbde9bc..f87484ad5d060b08ea35123500972c732fda4d2e 100644 (file)
@@ -38,6 +38,7 @@
 #include "pim_rp.h"
 #include "pim_msdp.h"
 #include "pim_ssm.h"
+#include "pim_bfd.h"
 
 int
 pim_debug_config_write (struct vty *vty)
@@ -320,6 +321,8 @@ int pim_interface_config_write(struct vty *vty)
     }
     vty_out(vty, "!%s", VTY_NEWLINE);
     ++writes;
+    /* PIM BFD write */
+    pim_bfd_write_config (vty, ifp);
   }
 
   return writes;
index 4506e8cdb5fcba87a3cd1e4debe2050c44e6e7d4..7be4a997babe451b096e366aaa33a80360b1a6fa 100644 (file)
@@ -29,6 +29,7 @@
 #include "network.h"
 #include "vty.h"
 #include "plist.h"
+#include "lib/bfd.h"
 
 #include "pimd.h"
 #include "pim_pim.h"
@@ -624,6 +625,9 @@ void sched_rpf_cache_refresh(void)
 static void
 pim_zebra_connected (struct zclient *zclient)
 {
+  /* Send the client registration */
+  bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
+
   zclient_send_reg_requests (zclient, VRF_DEFAULT);
 }
 
index 8aab5d2ef70fd40c828648dd400650c1ba01e5b2..51a0833cd52cedd47b0e93aef3c2772bcc5a955a 100644 (file)
@@ -27,6 +27,7 @@
 #include "plist.h"
 #include "hash.h"
 #include "jhash.h"
+#include "vrf.h"
 
 #include "pimd.h"
 #include "pim_cmd.h"
index cf423ad25fe7e0742227320a68d632b1a5b44de5..c9d738bb0807d4af3a34433476f7b3d568fd1cb1 100644 (file)
@@ -115,6 +115,7 @@ struct zebra_info
   { "ospf6",  ZEBRA_ROUTE_OSPF6 },
   { "bgp",    ZEBRA_ROUTE_BGP },
   { "nhrp",   ZEBRA_ROUTE_NHRP },
+  { "pim",    ZEBRA_ROUTE_PIM },
   { NULL,     0 }
 };
 
index 68d2bff718f5c354f4ee8df9b3ab88e31cc30400..e49347638b293f148131c93f850e8d74de9fef68 100644 (file)
@@ -1026,7 +1026,7 @@ zebra_ptm_bfd_client_deregister (int proto)
   int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF;
 
   if (proto != ZEBRA_ROUTE_OSPF && proto != ZEBRA_ROUTE_BGP
-      && proto != ZEBRA_ROUTE_OSPF6)
+      && proto != ZEBRA_ROUTE_OSPF6 && proto != ZEBRA_ROUTE_PIM)
     return;
 
   if (IS_ZEBRA_DEBUG_EVENT)
index efa29989e1e47cf338c0a9d116d8d0db51d044bd..d6902142a334cb67289afec498e8904cffd377ff 100644 (file)
@@ -78,9 +78,9 @@ zebra_interface_bfd_update (struct interface *ifp, struct prefix *dp,
 
   for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
     {
-      /* Supporting for OSPF and BGP */
+      /* Supporting for OSPF, BGP and PIM */
       if (client->proto != ZEBRA_ROUTE_OSPF && client->proto != ZEBRA_ROUTE_BGP
-          && client->proto != ZEBRA_ROUTE_OSPF6)
+          && client->proto != ZEBRA_ROUTE_OSPF6 && client->proto != ZEBRA_ROUTE_PIM)
         continue;
 
       /* Notify to the protocol daemons. */
@@ -117,7 +117,8 @@ zebra_bfd_peer_replay_req (void)
       /* Supporting for BGP */
       if ((client->proto != ZEBRA_ROUTE_BGP) &&
           (client->proto != ZEBRA_ROUTE_OSPF) &&
-          (client->proto != ZEBRA_ROUTE_OSPF6))
+          (client->proto != ZEBRA_ROUTE_OSPF6) &&
+          (client->proto != ZEBRA_ROUTE_PIM))
         continue;
 
       /* Notify to the protocol daemons. */