]> git.puffer.fish Git - matthieu/frr.git/commitdiff
Fix for IPv6 OSPF BFD session staying down when ifdown/ifup on logical interfaces
authorradhika <radhika@cumulusnetworks.com>
Fri, 9 Oct 2015 20:44:32 +0000 (13:44 -0700)
committerradhika <radhika@cumulusnetworks.com>
Fri, 9 Oct 2015 20:44:32 +0000 (13:44 -0700)
Ticket: CM-7649
Reviewed By: Donald
Testing Done:

This is porting of the patch, ospf6d-bfd-fix-dereg-miss.patch from br2.5.

 Issue: The IPv6 OSPF BFD sessions stay down after ifdown/ifup on logical interfaces. This problem doesn’t exist for BFD sessions created by BGP and IPv4 OSPF.

 Root cause: When the interface is brought down the IPv6 neighbors discovered on that interface are deleted. This deletion happens without first bringing down the neighbor and the BFD deregistration happens only when the neighbor state changes. This leaves an orphaned BFD session in PTM. Also, the BFD session socket that is bound to the interface that was brought down loses connection. The socket has to be rebound to the interface when it comes up. This problem will not happen if the client deleted the sessions and re-adds it when interface goes down and come up. IPv4 OSPF and BGP work exactly like that.

 Fix: Added the BFD deregistration code to IPv6 OSPF neighbor delete.

ospf6d/ospf6_bfd.c
ospf6d/ospf6_bfd.h
ospf6d/ospf6_neighbor.c

index 5ef4ab4ca85116d4cf1244ae85e3dedb6c6a58ef..16dedb1031c44a3daac9aa67481ebc41b8b1d1b0 100644 (file)
@@ -71,7 +71,7 @@ ospf6_bfd_show_info(struct vty *vty, void *bfd_info, int param_only)
  *                           zebra for starting/stopping the monitoring of
  *                           the neighbor rechahability.
  */
-static void
+void
 ospf6_bfd_reg_dereg_nbr (struct ospf6_neighbor *on, int command)
 {
   struct ospf6_interface *oi = on->ospf6_if;
@@ -79,7 +79,7 @@ ospf6_bfd_reg_dereg_nbr (struct ospf6_neighbor *on, int command)
   struct bfd_info *bfd_info;
   char src[64];
 
-  if (!oi->bfd_info)
+  if (!oi->bfd_info || !on->bfd_info)
     return;
   bfd_info = (struct bfd_info *)oi->bfd_info;
 
@@ -93,6 +93,9 @@ ospf6_bfd_reg_dereg_nbr (struct ospf6_neighbor *on, int command)
   bfd_peer_sendmsg (zclient, bfd_info, AF_INET6, &on->linklocal_addr,
                     on->ospf6_if->linklocal_addr, ifp->name,
                     0, 0, command, 0);
+
+  if (command == ZEBRA_BFD_DEST_DEREGISTER)
+    bfd_info_free((struct bfd_info **)&on->bfd_info);
 }
 
 /*
@@ -123,14 +126,16 @@ ospf6_bfd_reg_dereg_all_nbr (struct ospf6_interface *oi, int command)
 
   for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, node, on))
     {
-      if (command != ZEBRA_BFD_DEST_DEREGISTER)
+      if (command == ZEBRA_BFD_DEST_REGISTER)
         ospf6_bfd_info_nbr_create(oi, on);
-      else
-        bfd_info_free((struct bfd_info **)&on->bfd_info);
 
       if (on->state < OSPF6_NEIGHBOR_TWOWAY)
-        continue;
-
+        {
+          if (command == ZEBRA_BFD_DEST_DEREGISTER)
+            bfd_info_free((struct bfd_info **)&on->bfd_info);
+          continue;
+        }
       ospf6_bfd_reg_dereg_nbr(on, command);
     }
 }
index 11b13d66fb9db085fbb61c3ebf09566cd6b843d9..9c3b57aa247b54fba4224f61875434f1fdccd754 100644 (file)
@@ -43,4 +43,6 @@ ospf6_bfd_info_free(void **bfd_info);
 extern void
 ospf6_bfd_show_info(struct vty *vty, void *bfd_info, int param_only);
 
+extern void
+ospf6_bfd_reg_dereg_nbr (struct ospf6_neighbor *on, int command);
 #endif /* OSPF6_BFD_H */
index 1636c262890cb87c5e5c9a4b345b8033fa5ee0b1..6f9c8bb4f8e49a6ae7c68907c73e3f53a79b8a41 100644 (file)
@@ -141,7 +141,7 @@ ospf6_neighbor_delete (struct ospf6_neighbor *on)
   THREAD_OFF (on->thread_send_lsupdate);
   THREAD_OFF (on->thread_send_lsack);
 
-  ospf6_bfd_info_free(&on->bfd_info);
+  ospf6_bfd_reg_dereg_nbr(on, ZEBRA_BFD_DEST_DEREGISTER);
   XFREE (MTYPE_OSPF6_NEIGHBOR, on);
 }