diff options
-rw-r--r-- | doc/bird.sgml | 40 | ||||
-rw-r--r-- | proto/bgp/bgp.c | 4 | ||||
-rw-r--r-- | proto/bgp/bgp.h | 19 | ||||
-rw-r--r-- | proto/bgp/config.Y | 13 | ||||
-rw-r--r-- | proto/bgp/packets.c | 22 |
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 */ |