summaryrefslogtreecommitdiff
path: root/proto/bgp
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-02-04 15:26:36 +0100
committerMaria Matejka <mq@ucw.cz>2022-02-04 15:26:36 +0100
commitfe840ddad96259ed7b2f1d0d2f07bdf8d4c03384 (patch)
tree8a59e7eceaa1cfabb400f1fc2fbf0eaebf0d959f /proto/bgp
parent14bb6fd29a1c88103e73138d5fd4396e610aa469 (diff)
parenta9646efd40569f3a1d749bc1bd13219876b33a00 (diff)
Merge commit 'a9646efd40569f3a1d749bc1bd13219876b33a00' into sark-bgp-rebased
Diffstat (limited to 'proto/bgp')
-rw-r--r--proto/bgp/bgp.c11
-rw-r--r--proto/bgp/bgp.h1
-rw-r--r--proto/bgp/config.Y3
3 files changed, 11 insertions, 4 deletions
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index 65cc3a40..e2754649 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -165,12 +165,17 @@ bgp_open(struct bgp_proto *p)
ip_addr addr = p->cf->strict_bind ? p->cf->local_ip :
(p->ipv4 ? IPA_NONE4 : IPA_NONE6);
uint port = p->cf->local_port;
+ uint flags = p->cf->free_bind ? SKF_FREEBIND : 0;
+ uint flag_mask = SKF_FREEBIND;
/* We assume that cf->iface is defined iff cf->local_ip is link-local */
WALK_LIST(bs, bgp_sockets)
- if (ipa_equal(bs->sk->saddr, addr) && (bs->sk->sport == port) &&
- (bs->sk->iface == ifa) && (bs->sk->vrf == p->p.vrf))
+ if (ipa_equal(bs->sk->saddr, addr) &&
+ (bs->sk->sport == port) &&
+ (bs->sk->iface == ifa) &&
+ (bs->sk->vrf == p->p.vrf) &&
+ ((bs->sk->flags & flag_mask) == flags))
{
bs->uc++;
p->sock = bs;
@@ -184,7 +189,7 @@ bgp_open(struct bgp_proto *p)
sk->sport = port;
sk->iface = ifa;
sk->vrf = p->p.vrf;
- sk->flags = SKF_PASSIVE_THREAD;
+ sk->flags = flags | SKF_PASSIVE_THREAD;
sk->tos = IP_PREC_INTERNET_CONTROL;
sk->rbsize = BGP_RX_BUFFER_SIZE;
sk->tbsize = BGP_TX_BUFFER_SIZE;
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index d5ac3bd9..2a2fe689 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -86,6 +86,7 @@ struct bgp_config {
int peer_type; /* Internal or external BGP (BGP_PT_*, optional) */
int multihop; /* Number of hops if multihop */
int strict_bind; /* Bind listening socket to local address */
+ int free_bind; /* Bind listening socket with SKF_FREEBIND */
int ttl_security; /* Enable TTL security [RFC 5082] */
int compare_path_lengths; /* Use path lengths when selecting best route */
int med_metric; /* Compare MULTI_EXIT_DISC even between routes from differen ASes */
diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y
index 8e42bbdb..7c0d8d65 100644
--- a/proto/bgp/config.Y
+++ b/proto/bgp/config.Y
@@ -31,7 +31,7 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE,
STRICT, BIND, CONFEDERATION, MEMBER, MULTICAST, FLOW4, FLOW6, LONG,
LIVED, STALE, IMPORT, IBGP, EBGP, MANDATORY, INTERNAL, EXTERNAL, SETS,
DYNAMIC, RANGE, NAME, DIGITS, BGP_AIGP, AIGP, ORIGINATE, COST, ENFORCE,
- FIRST)
+ FIRST, FREE)
%type <i> bgp_nh
%type <i32> bgp_afi
@@ -156,6 +156,7 @@ bgp_proto:
}
| bgp_proto DYNAMIC NAME DIGITS expr ';' { BGP_CFG->dynamic_name_digits = $5; if ($5>10) cf_error("Dynamic name digits must be at most 10"); }
| bgp_proto STRICT BIND bool ';' { BGP_CFG->strict_bind = $4; }
+ | bgp_proto FREE BIND bool ';' { BGP_CFG->free_bind = $4; }
| bgp_proto PATH METRIC bool ';' { BGP_CFG->compare_path_lengths = $4; }
| bgp_proto MED METRIC bool ';' { BGP_CFG->med_metric = $4; }
| bgp_proto IGP METRIC bool ';' { BGP_CFG->igp_metric = $4; }