is configured as a route server (option <cf/rs client/), in
that case default is <cf/drop/, because route servers usually
does not forward packets ifselves.
+
+ <tag>gateway direct|recursive</tag>For received routes, their
+ <cf/gw/ (immediate next hop) attribute is computed from
+ received <cf/bgp_next_hop/ attribute. This option specifies
+ how it is computed. Direct mode means that the IP address from
+ <cf/bgp_next_hop/ is used if it is directly reachable,
+ otherwise the neighbor IP address is used. Recursive mode
+ means that the gateway is computed by a IGP routing table
+ lookup for the IP address from <cf/bgp_next_hop/. Recursive
+ mode is the behavior specified by the BGP standard. Direct
+ mode is simpler, does not require any routes in a routing
+ table, and was used in older versions of BIRD, but does not
+ handle well nontrivial iBGP setups and multihop. Default:
+ <cf/direct/ for singlehop eBGP, <cf/recursive/ otherwise.
+
+ <tag>igp table <m/name/</tag> Specifies a table that is used
+ in a recursive gateway mode for computing <cf/gw/ attributes.
+ Default: the same as the table BGP is connected to.
<tag>password <m/string/</tag> Use this password for MD5 authentication
of BGP sessions. Default: no authentication. Password has to be set by
void
bgp_check(struct bgp_config *c)
{
+ int internal = (c->local_as == c->remote_as);
+
if (!c->local_as)
cf_error("Local AS number must be set");
if (!(c->capabilities && c->enable_as4) && (c->remote_as > 0xFFFF))
cf_error("Neighbor AS number out of range (AS4 not available)");
- if ((c->local_as != c->remote_as) && (c->rr_client))
+ if (!internal && c->rr_client)
cf_error("Only internal neighbor can be RR client");
- if ((c->local_as == c->remote_as) && (c->rs_client))
+ if (internal && c->rs_client)
cf_error("Only external neighbor can be RS client");
+ if (c->multihop && (c->gw_mode == GW_DIRECT))
+ cf_error("Multihop BGP cannot use direct gateway mode");
+
/* Different default based on rs_client */
- if (c->missing_lladdr == 0)
+ if (!c->missing_lladdr)
c->missing_lladdr = c->rs_client ? MLL_DROP : MLL_SELF;
+
+ /* Different default for gw_mode */
+ if (!c->gw_mode)
+ c->gw_mode = (c->multihop || internal) ? GW_RECURSIVE : GW_DIRECT;
}
static char *bgp_state_names[] = { "Idle", "Connect", "Active", "OpenSent", "OpenConfirm", "Established", "Close" };
CF_DECLS
-CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE,
- MULTIHOP, STARTUP, VIA, NEXT, HOP, SELF, DEFAULT, PATH, METRIC,
- ERROR, START, DELAY, FORGET, WAIT, ENABLE, DISABLE, AFTER,
- BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN, BGP_NEXT_HOP,
- BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS,
- PASSWORD, RR, RS, CLIENT, CLUSTER, ID, AS4, ADVERTISE, IPV4,
- CAPABILITIES, LIMIT, PASSIVE, PREFER, OLDER, MISSING, LLADDR,
- DROP, IGNORE, ROUTE, REFRESH, INTERPRET, COMMUNITIES,
- BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP, TABLE)
+CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY,
+ KEEPALIVE, MULTIHOP, STARTUP, VIA, NEXT, HOP, SELF, DEFAULT,
+ PATH, METRIC, ERROR, START, DELAY, FORGET, WAIT, ENABLE,
+ DISABLE, AFTER, BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN,
+ BGP_NEXT_HOP, BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY,
+ SOURCE, ADDRESS, PASSWORD, RR, RS, CLIENT, CLUSTER, ID, AS4,
+ ADVERTISE, IPV4, CAPABILITIES, LIMIT, PASSIVE, PREFER, OLDER,
+ MISSING, LLADDR, DROP, IGNORE, ROUTE, REFRESH, INTERPRET,
+ COMMUNITIES, BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP, TABLE,
+ GATEWAY, DIRECT, RECURSIVE)
CF_GRAMMAR
| bgp_proto MISSING LLADDR SELF ';' { BGP_CFG->missing_lladdr = MLL_SELF; }
| bgp_proto MISSING LLADDR DROP ';' { BGP_CFG->missing_lladdr = MLL_DROP; }
| bgp_proto MISSING LLADDR IGNORE ';' { BGP_CFG->missing_lladdr = MLL_IGNORE; }
+ | bgp_proto GATEWAY DIRECT ';' { BGP_CFG->gw_mode = GW_DIRECT; }
+ | bgp_proto GATEWAY RECURSIVE ';' { BGP_CFG->gw_mode = GW_RECURSIVE; }
| bgp_proto PATH METRIC bool ';' { BGP_CFG->compare_path_lengths = $4; }
| bgp_proto PREFER OLDER bool ';' { BGP_CFG->prefer_older = $4; }
| bgp_proto DEFAULT BGP_MED expr ';' { BGP_CFG->default_med = $4; }