Hi,

I am using BFD neighbor to config BFD sessions statically. I found that if I add/remove BFD neighbors in bird.conf  and ask bird to reload with HUP signal, bird cannot reload the configuration correctly.

Here is the BFD config I used to test. If I start bird with this configuration, then comment one of the neighbors and send HUP with kill to bird, bird simply says session reconfigured without remove the commented neighbor.

protocol bfd {
interface "*" {
        passive;
};

neighbor 172.17.0.2;
neighbor 172.17.0.3;
}

After digging into the code, I found that it looks like there is a bug in function bfd_reconfigure_neighbors. It loops to check neighbor in old and new configuration. There is a return in the block if (bfd_same_neighbor(nn, on)). If there is  neighbor existing in both new and old, reconfiguration might be skipped.

I tried to modify the code to make it work. And the attached patch is the one I got. Hopefully this is the proper way to solve the issue.


Regards.

Chen.

>From 9948dea9516f015cee536d929becad389b639b78 Mon Sep 17 00:00:00 2001
From: Winston Chen <yoniorc...@gmail.com>
Date: Mon, 30 Sep 2019 22:06:01 +0800
Subject: [PATCH] BFD: Fix reload issue when neighbors change

---
 proto/bfd/bfd.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c
index f774e67b..de42be82 100644
--- a/proto/bfd/bfd.c
+++ b/proto/bfd/bfd.c
@@ -825,22 +825,30 @@ bfd_reconfigure_neighbors(struct bfd_proto *p, struct bfd_config *new)
 {
   struct bfd_config *old = (struct bfd_config *) (p->p.cf);
   struct bfd_neighbor *on, *nn;
+  int found;
 
   WALK_LIST(on, old->neigh_list)
   {
+    found = 0;
     WALK_LIST(nn, new->neigh_list)
+    {
       if (bfd_same_neighbor(nn, on))
       {
-	nn->neigh = on->neigh;
-	if (nn->neigh)
-	  nn->neigh->data = nn;
-
-	nn->req = on->req;
-	nn->active = 1;
-	return;
+        found = 1;
+        break;
       }
-
-    bfd_stop_neighbor(p, on);
+    }
+    if (found)
+    {
+      nn->neigh = on->neigh;
+      if (nn->neigh)
+        nn->neigh->data = nn;
+
+      nn->req = on->req;
+      nn->active = 1;
+    } else {
+      bfd_stop_neighbor(p, on);
+    }
   }
 
   WALK_LIST(nn, new->neigh_list)
-- 
2.23.0

Reply via email to