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.
This commit is contained in:
parent
87a02489f3
commit
60e9def9ef
4 changed files with 17 additions and 4 deletions
|
@ -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; }
|
||||
|
|
Loading…
Reference in a new issue