the number of hops is 2. Default: enabled for iBGP.
<tag><label id="bgp-source-address">source address <m/ip/</tag>
- Define local address we should use for next hop calculation and as a
- source address for the BGP session. Default: the address of the local
- end of the interface our neighbor is connected to.
+ Define local address we should use as a source address for the BGP
+ session. Default: the address of the local end of the interface our
+ neighbor is connected to.
<tag><label id="bgp-strict-bind">strict bind <m/switch/</tag>
Specify whether BGP listening socket should be bound to a specific local
<p>BGP channels have additional config options (together with the common ones):
<descrip>
- <tag><label id="bgp-next-hop-keep">next hop keep</tag>
- Forward the received Next Hop attribute even in situations where the
- local address should be used instead, like when the route is sent to an
- interface with a different subnet. Default: disabled.
-
- <tag><label id="bgp-next-hop-self">next hop self</tag>
- Avoid calculation of the Next Hop attribute and always advertise our own
- source address as a next hop. This needs to be used only occasionally to
- circumvent misconfigurations of other routers. Default: disabled.
+ <tag><label id="bgp-next-hop-keep">next hop keep <m/switch/|ibgp|ebgp</tag>
+ Do not modify the Next Hop attribute and advertise the current one
+ unchanged even in cases where our own local address should be used
+ 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 <m/switch/|ibgp|ebgp</tag>
+ Always advertise our own local address as a next hop, even in cases
+ where the current Next Hop attribute should be used unchanged. This is
+ 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>
- Avoid calculation of the Next Hop attribute and always advertise this address
- as a next hop.
+ Specify which address to use when our own local address should be
+ 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>
Next Hop attribute in BGP-IPv6 sometimes contains just the global IPv6
the channel is connected to (if eligible).
<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/
in BGP terminology. BIRD BGP by default operates without import tables,
in which case received routes are just processed by import filters,
if ((cc->c.in_limit.action == PLA_RESTART) && cf->disable_after_error)
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 */
if (!cc->missing_lladdr)
cc->missing_lladdr = cf->rs_client ? MLL_IGNORE : MLL_SELF;
const struct bgp_af_desc *desc;
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_keep; /* Do not touch next hop attribute */
+ u8 next_hop_self; /* Always set next hop to local IP address (NH_*) */
+ 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 gw_mode; /* How we compute route gateway from next_hop attr, see GW_* */
u8 secondary; /* Accept also non-best routes (i.e. RA_ACCEPTED) */
struct rtable_config *igp_table_ip6; /* Table for recursive IPv6 next hop lookups */
};
-#define MLL_SELF 1
-#define MLL_DROP 2
-#define MLL_IGNORE 3
+#define NH_NO 0
+#define NH_ALL 1
+#define NH_IBGP 2
+#define NH_EBGP 3
-#define GW_DIRECT 1
-#define GW_RECURSIVE 2
+#define MLL_SELF 1
+#define MLL_DROP 2
+#define MLL_IGNORE 3
+
+#define GW_DIRECT 1
+#define GW_RECURSIVE 2
#define BGP_ADD_PATH_RX 1
#define BGP_ADD_PATH_TX 2
SECURITY, DETERMINISTIC, SECONDARY, ALLOW, BFD, ADD, PATHS, RX, TX,
GRACEFUL, RESTART, AWARE, CHECK, LINK, PORT, EXTENDED, MESSAGES, SETKEY,
STRICT, BIND, CONFEDERATION, MEMBER, MULTICAST, FLOW4, FLOW6, LONG,
- LIVED, STALE, IMPORT)
+ LIVED, STALE, IMPORT, IBGP, EBGP)
+%type <i> bgp_nh
%type <i32> bgp_afi
CF_KEYWORDS(CEASE, PREFIX, LIMIT, HIT, ADMINISTRATIVE, SHUTDOWN, RESET, PEER,
BGP_CC->c.ra_mode = RA_UNDEF;
BGP_CC->afi = $1;
BGP_CC->desc = desc;
+ BGP_CC->next_hop_keep = 0xff; /* undefined */
BGP_CC->gr_able = 0xff; /* undefined */
BGP_CC->llgr_able = 0xff; /* undefined */
BGP_CC->llgr_time = ~0U; /* undefined */
}
};
+bgp_nh:
+ bool { $$ = $1; }
+ | IBGP { $$ = NH_IBGP; }
+ | EBGP { $$ = NH_EBGP; }
+
bgp_channel_item:
channel_item
| 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 KEEP { BGP_CC->next_hop_keep = 1; BGP_CC->next_hop_self = 0; }
+ | NEXT HOP SELF bgp_nh { BGP_CC->next_hop_self = $4; }
+ | NEXT HOP KEEP bgp_nh { BGP_CC->next_hop_keep = $4; }
| MISSING LLADDR SELF { BGP_CC->missing_lladdr = MLL_SELF; }
| MISSING LLADDR DROP { BGP_CC->missing_lladdr = MLL_DROP; }
| MISSING LLADDR IGNORE { BGP_CC->missing_lladdr = MLL_IGNORE; }
}
+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
bgp_use_next_hop(struct bgp_export_state *s, eattr *a)
{
struct bgp_channel *c = s->channel;
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;
- 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;
/* Keep it when explicitly set in export filter */
struct bgp_channel *c = s->channel;
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;
/* We need one valid global gateway */