summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/bird.sgml40
-rw-r--r--proto/bgp/bgp.c4
-rw-r--r--proto/bgp/bgp.h19
-rw-r--r--proto/bgp/config.Y13
-rw-r--r--proto/bgp/packets.c22
5 files changed, 70 insertions, 28 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml
index 8dc872e7..c76873cd 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -2220,9 +2220,9 @@ using the following configuration parameters:
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
@@ -2565,19 +2565,29 @@ be used in explicit configuration.
<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
@@ -2618,7 +2628,7 @@ be used in explicit configuration.
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,
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index ae4a1b0a..fb6c9881 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -1814,6 +1814,10 @@ bgp_postconfig(struct proto_config *CF)
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;
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index 76b835fa..2b60f90f 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -134,8 +134,8 @@ struct bgp_channel_config {
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) */
@@ -151,12 +151,17 @@ struct bgp_channel_config {
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
diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y
index f155eee2..ac8d024a 100644
--- a/proto/bgp/config.Y
+++ b/proto/bgp/config.Y
@@ -29,8 +29,9 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE,
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,
@@ -205,17 +206,23 @@ bgp_channel_start: bgp_afi
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; }
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index e7089eba..26716573 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -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
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;
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 */
@@ -888,7 +903,8 @@ bgp_use_gateway(struct bgp_export_state *s)
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 */