diff options
author | Alexander Zubkov <green@qrator.net> | 2024-02-07 19:11:10 +0100 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2024-02-07 19:11:10 +0100 |
commit | 574d7eb241a60622b0573ab1460cb23d968ba1cc (patch) | |
tree | b17bc117bad5762d520ae91d003c44137918368c | |
parent | 0b52f7c01f55707b25eebd0a66c48eafe06fe455 (diff) |
BGP: Allow multiple EBGP neighbors with the same peer.
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.
-rw-r--r-- | lib/ip.h | 4 | ||||
-rw-r--r-- | nest/locks.c | 5 | ||||
-rw-r--r-- | nest/locks.h | 3 | ||||
-rw-r--r-- | proto/bgp/bgp.c | 1 |
4 files changed, 10 insertions, 3 deletions
@@ -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 diff --git a/nest/locks.c b/nest/locks.c index 812a6534..637f2c15 100644 --- a/nest/locks.c +++ b/nest/locks.c @@ -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"); } diff --git a/nest/locks.h b/nest/locks.h index 37026c68..1686e6ec 100644 --- a/nest/locks.h +++ b/nest/locks.h @@ -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 */ diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index cd57c32b..e97b45e6 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -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; |