Skip to content
Snippets Groups Projects
Commit 60e9def9 authored by Ondřej Zajíček's avatar Ondřej Zajíček
Browse files

BGP: Add option 'free bind'

The BGP 'free bind' option applies the IP_FREEBIND/IPV6_FREEBIND
socket option for the BGP listening socket.

Thanks to Alexander Zubkov for the idea.
parent 87a02489
No related branches found
No related tags found
No related merge requests found
Pipeline #93131 passed with warnings
......@@ -2412,6 +2412,12 @@ using the following configuration parameters:
same address family and using the same local port) should have set
<cf/strict bind/, or none of them. Default: disabled.
<tag><label id="bgp-free-bind">free bind <m/switch/</tag>
Use IP_FREEBIND socket option for the listening socket, which allows
binding to an IP address not (yet) assigned to an interface. Note that
all BGP instances that share a listening socket should have the same
value of the <cf/freebind/ option. Default: disabled.
<tag><label id="bgp-check-link">check link <M>switch</M></tag>
BGP could use hardware link state into consideration. If enabled,
BIRD tracks the link state of the associated interface and when link
......
......@@ -157,6 +157,8 @@ 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;
/* FIXME: Add some global init? */
if (!bgp_linpool)
......@@ -165,8 +167,11 @@ bgp_open(struct bgp_proto *p)
/* 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;
......@@ -180,7 +185,7 @@ bgp_open(struct bgp_proto *p)
sk->sport = port;
sk->iface = ifa;
sk->vrf = p->p.vrf;
sk->flags = 0;
sk->flags = flags;
sk->tos = IP_PREC_INTERNET_CONTROL;
sk->rbsize = BGP_RX_BUFFER_SIZE;
sk->tbsize = BGP_TX_BUFFER_SIZE;
......
......@@ -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 */
......
......@@ -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
......@@ -155,6 +155,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; }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment