BGP: Extend 'next hop keep' and 'next hop self' options
Extend 'next hop keep' and 'next hop self' options to have boolean values (enabled / disabled) and also values 'ibgp'/ 'ebgp' to restrict it to routes received from IBGP / EBGP. This allows to have it enabled by default in some cases, matches features of other implementations, and allows to handle some strange cases like EBGP border router with 'next hop self' also doing IBGP route reflecting. Change default of 'next hop keep' to enabled for route servers, and 'ibgp' for route reflectors. Update documentation for these options.
This commit is contained in:
parent
337165959c
commit
1cab2b4a7c
5 changed files with 69 additions and 27 deletions
|
@ -2220,9 +2220,9 @@ using the following configuration parameters:
|
||||||
the number of hops is 2. Default: enabled for iBGP.
|
the number of hops is 2. Default: enabled for iBGP.
|
||||||
|
|
||||||
<tag><label id="bgp-source-address">source address <m/ip/</tag>
|
<tag><label id="bgp-source-address">source address <m/ip/</tag>
|
||||||
Define local address we should use for next hop calculation and as a
|
Define local address we should use as a source address for the BGP
|
||||||
source address for the BGP session. Default: the address of the local
|
session. Default: the address of the local end of the interface our
|
||||||
end of the interface our neighbor is connected to.
|
neighbor is connected to.
|
||||||
|
|
||||||
<tag><label id="bgp-strict-bind">strict bind <m/switch/</tag>
|
<tag><label id="bgp-strict-bind">strict bind <m/switch/</tag>
|
||||||
Specify whether BGP listening socket should be bound to a specific local
|
Specify whether BGP listening socket should be bound to a specific local
|
||||||
|
@ -2565,19 +2565,29 @@ be used in explicit configuration.
|
||||||
<p>BGP channels have additional config options (together with the common ones):
|
<p>BGP channels have additional config options (together with the common ones):
|
||||||
|
|
||||||
<descrip>
|
<descrip>
|
||||||
<tag><label id="bgp-next-hop-keep">next hop keep</tag>
|
<tag><label id="bgp-next-hop-keep">next hop keep <m/switch/|ibgp|ebgp</tag>
|
||||||
Forward the received Next Hop attribute even in situations where the
|
Do not modify the Next Hop attribute and advertise the current one
|
||||||
local address should be used instead, like when the route is sent to an
|
unchanged even in cases where our own local address should be used
|
||||||
interface with a different subnet. Default: disabled.
|
instead. This is necessary when the BGP speaker does not forward network
|
||||||
|
traffic (route servers and some route reflectors) and also can be useful
|
||||||
|
in some other cases (e.g. multihop EBGP sessions). Can be enabled for
|
||||||
|
all routes, or just for routes received from IBGP / EBGP neighbors.
|
||||||
|
Default: disabled for regular BGP, enabled for route servers,
|
||||||
|
<cf/ibgp/ for route reflectors.
|
||||||
|
|
||||||
<tag><label id="bgp-next-hop-self">next hop self</tag>
|
<tag><label id="bgp-next-hop-self">next hop self <m/switch/|ibgp|ebgp</tag>
|
||||||
Avoid calculation of the Next Hop attribute and always advertise our own
|
Always advertise our own local address as a next hop, even in cases
|
||||||
source address as a next hop. This needs to be used only occasionally to
|
where the current Next Hop attribute should be used unchanged. This is
|
||||||
circumvent misconfigurations of other routers. Default: disabled.
|
sometimes used for routes propagated from EBGP to IBGP when IGP routing
|
||||||
|
does not cover inter-AS links, therefore IP addreses of EBGP neighbors
|
||||||
|
are not resolvable through IGP. Can be enabled for all routes, or just
|
||||||
|
for routes received from IBGP / EBGP neighbors. Default: disabled.
|
||||||
|
|
||||||
<tag><label id="bgp-next-hop-address">next hop address <m/ip/</tag>
|
<tag><label id="bgp-next-hop-address">next hop address <m/ip/</tag>
|
||||||
Avoid calculation of the Next Hop attribute and always advertise this address
|
Specify which address to use when our own local address should be
|
||||||
as a next hop.
|
announced in the Next Hop attribute. Default: the source address of the
|
||||||
|
BGP session (if acceptable), or the preferred address of an associated
|
||||||
|
interface.
|
||||||
|
|
||||||
<tag><label id="bgp-missing-lladdr">missing lladdr self|drop|ignore</tag>
|
<tag><label id="bgp-missing-lladdr">missing lladdr self|drop|ignore</tag>
|
||||||
Next Hop attribute in BGP-IPv6 sometimes contains just the global IPv6
|
Next Hop attribute in BGP-IPv6 sometimes contains just the global IPv6
|
||||||
|
@ -2618,7 +2628,7 @@ be used in explicit configuration.
|
||||||
the channel is connected to (if eligible).
|
the channel is connected to (if eligible).
|
||||||
|
|
||||||
<tag><label id="bgp-import-table">import table <m/switch/</tag>
|
<tag><label id="bgp-import-table">import table <m/switch/</tag>
|
||||||
A BGP import table contain all received routes from given BGP neighbor,
|
A BGP import table contains all received routes from given BGP neighbor,
|
||||||
before application of import filters. It is also called <em/Adj-RIB-In/
|
before application of import filters. It is also called <em/Adj-RIB-In/
|
||||||
in BGP terminology. BIRD BGP by default operates without import tables,
|
in BGP terminology. BIRD BGP by default operates without import tables,
|
||||||
in which case received routes are just processed by import filters,
|
in which case received routes are just processed by import filters,
|
||||||
|
|
|
@ -1814,6 +1814,10 @@ bgp_postconfig(struct proto_config *CF)
|
||||||
if ((cc->c.in_limit.action == PLA_RESTART) && cf->disable_after_error)
|
if ((cc->c.in_limit.action == PLA_RESTART) && cf->disable_after_error)
|
||||||
cc->c.in_limit.action = PLA_DISABLE;
|
cc->c.in_limit.action = PLA_DISABLE;
|
||||||
|
|
||||||
|
/* Different default based on rr_client, rs_client */
|
||||||
|
if (cc->next_hop_keep == 0xff)
|
||||||
|
cc->next_hop_keep = cf->rr_client ? NH_IBGP : (cf->rs_client ? NH_ALL : NH_NO);
|
||||||
|
|
||||||
/* Different default based on rs_client */
|
/* Different default based on rs_client */
|
||||||
if (!cc->missing_lladdr)
|
if (!cc->missing_lladdr)
|
||||||
cc->missing_lladdr = cf->rs_client ? MLL_IGNORE : MLL_SELF;
|
cc->missing_lladdr = cf->rs_client ? MLL_IGNORE : MLL_SELF;
|
||||||
|
|
|
@ -134,8 +134,8 @@ struct bgp_channel_config {
|
||||||
const struct bgp_af_desc *desc;
|
const struct bgp_af_desc *desc;
|
||||||
|
|
||||||
ip_addr next_hop_addr; /* Local address for NEXT_HOP attribute */
|
ip_addr next_hop_addr; /* Local address for NEXT_HOP attribute */
|
||||||
u8 next_hop_self; /* Always set next hop to local IP address */
|
u8 next_hop_self; /* Always set next hop to local IP address (NH_*) */
|
||||||
u8 next_hop_keep; /* Do not touch next hop attribute */
|
u8 next_hop_keep; /* Do not modify next hop attribute (NH_*) */
|
||||||
u8 missing_lladdr; /* What we will do when we don' know link-local addr, see MLL_* */
|
u8 missing_lladdr; /* What we will do when we don' know link-local addr, see MLL_* */
|
||||||
u8 gw_mode; /* How we compute route gateway from next_hop attr, see GW_* */
|
u8 gw_mode; /* How we compute route gateway from next_hop attr, see GW_* */
|
||||||
u8 secondary; /* Accept also non-best routes (i.e. RA_ACCEPTED) */
|
u8 secondary; /* Accept also non-best routes (i.e. RA_ACCEPTED) */
|
||||||
|
@ -151,6 +151,11 @@ struct bgp_channel_config {
|
||||||
struct rtable_config *igp_table_ip6; /* Table for recursive IPv6 next hop lookups */
|
struct rtable_config *igp_table_ip6; /* Table for recursive IPv6 next hop lookups */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define NH_NO 0
|
||||||
|
#define NH_ALL 1
|
||||||
|
#define NH_IBGP 2
|
||||||
|
#define NH_EBGP 3
|
||||||
|
|
||||||
#define MLL_SELF 1
|
#define MLL_SELF 1
|
||||||
#define MLL_DROP 2
|
#define MLL_DROP 2
|
||||||
#define MLL_IGNORE 3
|
#define MLL_IGNORE 3
|
||||||
|
|
|
@ -29,8 +29,9 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE,
|
||||||
SECURITY, DETERMINISTIC, SECONDARY, ALLOW, BFD, ADD, PATHS, RX, TX,
|
SECURITY, DETERMINISTIC, SECONDARY, ALLOW, BFD, ADD, PATHS, RX, TX,
|
||||||
GRACEFUL, RESTART, AWARE, CHECK, LINK, PORT, EXTENDED, MESSAGES, SETKEY,
|
GRACEFUL, RESTART, AWARE, CHECK, LINK, PORT, EXTENDED, MESSAGES, SETKEY,
|
||||||
STRICT, BIND, CONFEDERATION, MEMBER, MULTICAST, FLOW4, FLOW6, LONG,
|
STRICT, BIND, CONFEDERATION, MEMBER, MULTICAST, FLOW4, FLOW6, LONG,
|
||||||
LIVED, STALE, IMPORT)
|
LIVED, STALE, IMPORT, IBGP, EBGP)
|
||||||
|
|
||||||
|
%type <i> bgp_nh
|
||||||
%type <i32> bgp_afi
|
%type <i32> bgp_afi
|
||||||
|
|
||||||
CF_KEYWORDS(CEASE, PREFIX, LIMIT, HIT, ADMINISTRATIVE, SHUTDOWN, RESET, PEER,
|
CF_KEYWORDS(CEASE, PREFIX, LIMIT, HIT, ADMINISTRATIVE, SHUTDOWN, RESET, PEER,
|
||||||
|
@ -205,17 +206,23 @@ bgp_channel_start: bgp_afi
|
||||||
BGP_CC->c.ra_mode = RA_UNDEF;
|
BGP_CC->c.ra_mode = RA_UNDEF;
|
||||||
BGP_CC->afi = $1;
|
BGP_CC->afi = $1;
|
||||||
BGP_CC->desc = desc;
|
BGP_CC->desc = desc;
|
||||||
|
BGP_CC->next_hop_keep = 0xff; /* undefined */
|
||||||
BGP_CC->gr_able = 0xff; /* undefined */
|
BGP_CC->gr_able = 0xff; /* undefined */
|
||||||
BGP_CC->llgr_able = 0xff; /* undefined */
|
BGP_CC->llgr_able = 0xff; /* undefined */
|
||||||
BGP_CC->llgr_time = ~0U; /* undefined */
|
BGP_CC->llgr_time = ~0U; /* undefined */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bgp_nh:
|
||||||
|
bool { $$ = $1; }
|
||||||
|
| IBGP { $$ = NH_IBGP; }
|
||||||
|
| EBGP { $$ = NH_EBGP; }
|
||||||
|
|
||||||
bgp_channel_item:
|
bgp_channel_item:
|
||||||
channel_item
|
channel_item
|
||||||
| NEXT HOP ADDRESS ipa { BGP_CC->next_hop_addr = $4; }
|
| NEXT HOP ADDRESS ipa { BGP_CC->next_hop_addr = $4; }
|
||||||
| NEXT HOP SELF { BGP_CC->next_hop_self = 1; BGP_CC->next_hop_keep = 0; }
|
| NEXT HOP SELF bgp_nh { BGP_CC->next_hop_self = $4; }
|
||||||
| NEXT HOP KEEP { BGP_CC->next_hop_keep = 1; BGP_CC->next_hop_self = 0; }
|
| NEXT HOP KEEP bgp_nh { BGP_CC->next_hop_keep = $4; }
|
||||||
| MISSING LLADDR SELF { BGP_CC->missing_lladdr = MLL_SELF; }
|
| MISSING LLADDR SELF { BGP_CC->missing_lladdr = MLL_SELF; }
|
||||||
| MISSING LLADDR DROP { BGP_CC->missing_lladdr = MLL_DROP; }
|
| MISSING LLADDR DROP { BGP_CC->missing_lladdr = MLL_DROP; }
|
||||||
| MISSING LLADDR IGNORE { BGP_CC->missing_lladdr = MLL_IGNORE; }
|
| MISSING LLADDR IGNORE { BGP_CC->missing_lladdr = MLL_IGNORE; }
|
||||||
|
|
|
@ -851,6 +851,19 @@ bgp_apply_mpls_labels(struct bgp_parse_state *s, rta *a, u32 *labels, uint lnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
bgp_match_src(struct bgp_export_state *s, int mode)
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case NH_NO: return 0;
|
||||||
|
case NH_ALL: return 1;
|
||||||
|
case NH_IBGP: return s->src && s->src->is_internal;
|
||||||
|
case NH_EBGP: return s->src && !s->src->is_internal;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
bgp_use_next_hop(struct bgp_export_state *s, eattr *a)
|
bgp_use_next_hop(struct bgp_export_state *s, eattr *a)
|
||||||
{
|
{
|
||||||
|
@ -858,10 +871,12 @@ bgp_use_next_hop(struct bgp_export_state *s, eattr *a)
|
||||||
struct bgp_channel *c = s->channel;
|
struct bgp_channel *c = s->channel;
|
||||||
ip_addr *nh = (void *) a->u.ptr->data;
|
ip_addr *nh = (void *) a->u.ptr->data;
|
||||||
|
|
||||||
if (s->channel->cf->next_hop_self)
|
/* Handle next hop self option */
|
||||||
|
if (c->cf->next_hop_self && bgp_match_src(s, c->cf->next_hop_self))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (s->channel->cf->next_hop_keep)
|
/* Handle next hop keep option */
|
||||||
|
if (c->cf->next_hop_keep && bgp_match_src(s, c->cf->next_hop_keep))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* Keep it when explicitly set in export filter */
|
/* Keep it when explicitly set in export filter */
|
||||||
|
@ -888,7 +903,8 @@ bgp_use_gateway(struct bgp_export_state *s)
|
||||||
struct bgp_channel *c = s->channel;
|
struct bgp_channel *c = s->channel;
|
||||||
rta *ra = s->route->attrs;
|
rta *ra = s->route->attrs;
|
||||||
|
|
||||||
if (s->channel->cf->next_hop_self)
|
/* Handle next hop self option - also applies to gateway */
|
||||||
|
if (c->cf->next_hop_self && bgp_match_src(s, c->cf->next_hop_self))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* We need one valid global gateway */
|
/* We need one valid global gateway */
|
||||||
|
|
Loading…
Reference in a new issue