]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BGP: Allow multiple EBGP neighbors with the same peer.
authorAlexander Zubkov <green@qrator.net>
Wed, 7 Feb 2024 18:11:10 +0000 (19:11 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Wed, 7 Feb 2024 18:11:10 +0000 (19:11 +0100)
We can distinguish BGP sessions if at least one side uses a different IP
address. Extend olock mechanism to handle local IP as a part of key, with
optional wildcard, so BGP sessions could local IP in the olock and not
block themselves.

lib/ip.h
nest/locks.c
nest/locks.h
proto/bgp/bgp.c

index f2650d3fba3bd8de1d0400dd8ec7e7bab935033e..8dd925ed2aeb0e0fab31ce90c2d47ca92de1598f 100644 (file)
--- a/lib/ip.h
+++ b/lib/ip.h
@@ -176,6 +176,10 @@ static inline ip6_addr ip6_not(ip6_addr a)
 #define ipa_xor(x,y) ip6_xor(x,y)
 #define ipa_not(x) ip6_not(x)
 
+/* Compare addresses when zero address works like a wildcard */
+static inline int ipa_equal_wildcard(ip_addr x, ip_addr y)
+{ return ipa_zero(x) || ipa_zero(y) || ipa_equal(x, y); }
+
 
 /*
  * A zero address is either a token for invalid/unused, or the prefix of default
index 812a65342268b9b97b3f19f1960c8e8b5e07377c..637f2c159632503d8ce1487ce89ceaaa369140fb 100644 (file)
@@ -48,7 +48,8 @@ olock_same(struct object_lock *x, struct object_lock *y)
     x->vrf == y->vrf &&
     x->port == y->port &&
     x->inst == y->inst &&
-    ipa_equal(x->addr, y->addr);
+    ipa_equal(x->addr, y->addr) &&
+    ipa_equal_wildcard(x->addr_local, y->addr_local);
 }
 
 static void
@@ -91,7 +92,7 @@ olock_dump(resource *r)
   struct object_lock *l = (struct object_lock *) r;
   static char *olock_states[] = { "free", "locked", "waiting", "event" };
 
-  debug("(%d:%s:%I:%d:%d) [%s]\n", l->type, (l->iface ? l->iface->name : "?"), l->addr, l->port, l->inst, olock_states[l->state]);
+  debug("(%d:%s:%I:%I:%d:%d) [%s]\n", l->type, (l->iface ? l->iface->name : "?"), l->addr, l->addr_local, l->port, l->inst, olock_states[l->state]);
   if (!EMPTY_LIST(l->waiters))
     debug(" [wanted]\n");
 }
index 37026c68c1a7dd82df8b3e9f3708d5d4ec96489e..1686e6ecfd45be3735c682d39d9ffbc758a83e00 100644 (file)
@@ -25,7 +25,8 @@
 
 struct object_lock {
   resource r;
-  ip_addr addr;                /* Identification of a object: IP address */
+  ip_addr addr;                /* Identification of a object: IP address (strict compare) */
+  ip_addr addr_local;  /* ... another IP address (allow zero IP wildcard) */
   uint type;           /* ... object type (OBJLOCK_xxx) */
   uint port;           /* ... port number */
   uint inst;           /* ... instance ID */
index cd57c32bc69077fa4041f1dae638bd035e833f7d..e97b45e6fea3b6f2c23a15d360630ec24eca4f40 100644 (file)
@@ -1616,6 +1616,7 @@ bgp_start(struct proto *P)
   struct object_lock *lock;
   lock = p->lock = olock_new(P->pool);
   lock->addr = p->remote_ip;
+  lock->addr_local = p->cf->local_ip;
   lock->port = p->cf->remote_port;
   lock->iface = p->cf->iface;
   lock->vrf = p->cf->iface ? NULL : p->p.vrf;