Adds some options and documentation related to recursive next hops.
This commit is contained in:
parent
f038f0a638
commit
087cecd0e2
5 changed files with 48 additions and 15 deletions
|
@ -1028,6 +1028,24 @@ for each neighbor using the following configuration parameters:
|
||||||
is configured as a route server (option <cf/rs client/), in
|
is configured as a route server (option <cf/rs client/), in
|
||||||
that case default is <cf/drop/, because route servers usually
|
that case default is <cf/drop/, because route servers usually
|
||||||
does not forward packets ifselves.
|
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
|
<tag>password <m/string/</tag> Use this password for MD5 authentication
|
||||||
of BGP sessions. Default: no authentication. Password has to be set by
|
of BGP sessions. Default: no authentication. Password has to be set by
|
||||||
|
|
|
@ -951,6 +951,8 @@ bgp_store_error(struct bgp_proto *p, struct bgp_conn *c, u8 class, u32 code)
|
||||||
void
|
void
|
||||||
bgp_check(struct bgp_config *c)
|
bgp_check(struct bgp_config *c)
|
||||||
{
|
{
|
||||||
|
int internal = (c->local_as == c->remote_as);
|
||||||
|
|
||||||
if (!c->local_as)
|
if (!c->local_as)
|
||||||
cf_error("Local AS number must be set");
|
cf_error("Local AS number must be set");
|
||||||
|
|
||||||
|
@ -960,15 +962,22 @@ bgp_check(struct bgp_config *c)
|
||||||
if (!(c->capabilities && c->enable_as4) && (c->remote_as > 0xFFFF))
|
if (!(c->capabilities && c->enable_as4) && (c->remote_as > 0xFFFF))
|
||||||
cf_error("Neighbor AS number out of range (AS4 not available)");
|
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");
|
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");
|
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 */
|
/* 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;
|
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" };
|
static char *bgp_state_names[] = { "Idle", "Connect", "Active", "OpenSent", "OpenConfirm", "Established", "Close" };
|
||||||
|
|
|
@ -23,6 +23,7 @@ struct bgp_config {
|
||||||
ip_addr source_addr; /* Source address to use */
|
ip_addr source_addr; /* Source address to use */
|
||||||
int next_hop_self; /* Always set next hop to local IP address */
|
int next_hop_self; /* Always set next hop to local IP address */
|
||||||
int missing_lladdr; /* What we will do when we don' know link-local addr, see MLL_* */
|
int missing_lladdr; /* What we will do when we don' know link-local addr, see MLL_* */
|
||||||
|
int gw_mode; /* How we compute route gateway from next_hop attr, see GW_* */
|
||||||
int compare_path_lengths; /* Use path lengths when selecting best route */
|
int compare_path_lengths; /* Use path lengths when selecting best route */
|
||||||
int prefer_older; /* Prefer older routes according to RFC 5004 */
|
int prefer_older; /* Prefer older routes according to RFC 5004 */
|
||||||
u32 default_local_pref; /* Default value for LOCAL_PREF attribute */
|
u32 default_local_pref; /* Default value for LOCAL_PREF attribute */
|
||||||
|
@ -53,6 +54,9 @@ struct bgp_config {
|
||||||
#define MLL_DROP 2
|
#define MLL_DROP 2
|
||||||
#define MLL_IGNORE 3
|
#define MLL_IGNORE 3
|
||||||
|
|
||||||
|
#define GW_DIRECT 1
|
||||||
|
#define GW_RECURSIVE 2
|
||||||
|
|
||||||
struct bgp_conn {
|
struct bgp_conn {
|
||||||
struct bgp_proto *bgp;
|
struct bgp_proto *bgp;
|
||||||
struct birdsock *sk;
|
struct birdsock *sk;
|
||||||
|
|
|
@ -16,15 +16,16 @@ CF_DEFINES
|
||||||
|
|
||||||
CF_DECLS
|
CF_DECLS
|
||||||
|
|
||||||
CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE,
|
CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY,
|
||||||
MULTIHOP, STARTUP, VIA, NEXT, HOP, SELF, DEFAULT, PATH, METRIC,
|
KEEPALIVE, MULTIHOP, STARTUP, VIA, NEXT, HOP, SELF, DEFAULT,
|
||||||
ERROR, START, DELAY, FORGET, WAIT, ENABLE, DISABLE, AFTER,
|
PATH, METRIC, ERROR, START, DELAY, FORGET, WAIT, ENABLE,
|
||||||
BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN, BGP_NEXT_HOP,
|
DISABLE, AFTER, BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN,
|
||||||
BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS,
|
BGP_NEXT_HOP, BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY,
|
||||||
PASSWORD, RR, RS, CLIENT, CLUSTER, ID, AS4, ADVERTISE, IPV4,
|
SOURCE, ADDRESS, PASSWORD, RR, RS, CLIENT, CLUSTER, ID, AS4,
|
||||||
CAPABILITIES, LIMIT, PASSIVE, PREFER, OLDER, MISSING, LLADDR,
|
ADVERTISE, IPV4, CAPABILITIES, LIMIT, PASSIVE, PREFER, OLDER,
|
||||||
DROP, IGNORE, ROUTE, REFRESH, INTERPRET, COMMUNITIES,
|
MISSING, LLADDR, DROP, IGNORE, ROUTE, REFRESH, INTERPRET,
|
||||||
BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP, TABLE)
|
COMMUNITIES, BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP, TABLE,
|
||||||
|
GATEWAY, DIRECT, RECURSIVE)
|
||||||
|
|
||||||
CF_GRAMMAR
|
CF_GRAMMAR
|
||||||
|
|
||||||
|
@ -74,6 +75,8 @@ bgp_proto:
|
||||||
| bgp_proto MISSING LLADDR SELF ';' { BGP_CFG->missing_lladdr = MLL_SELF; }
|
| 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 DROP ';' { BGP_CFG->missing_lladdr = MLL_DROP; }
|
||||||
| bgp_proto MISSING LLADDR IGNORE ';' { BGP_CFG->missing_lladdr = MLL_IGNORE; }
|
| 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 PATH METRIC bool ';' { BGP_CFG->compare_path_lengths = $4; }
|
||||||
| bgp_proto PREFER OLDER bool ';' { BGP_CFG->prefer_older = $4; }
|
| bgp_proto PREFER OLDER bool ';' { BGP_CFG->prefer_older = $4; }
|
||||||
| bgp_proto DEFAULT BGP_MED expr ';' { BGP_CFG->default_med = $4; }
|
| bgp_proto DEFAULT BGP_MED expr ';' { BGP_CFG->default_med = $4; }
|
||||||
|
|
|
@ -807,8 +807,7 @@ bgp_set_next_hop(struct bgp_proto *p, rta *a)
|
||||||
struct eattr *nh = ea_find(a->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
|
struct eattr *nh = ea_find(a->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
|
||||||
ip_addr nexthop = *(ip_addr *) nh->u.ptr->data;
|
ip_addr nexthop = *(ip_addr *) nh->u.ptr->data;
|
||||||
|
|
||||||
if (!p->is_internal) /* FIXME better option
|
if (p->cf->gw_mode == GW_DIRECT)
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
neighbor *ng = neigh_find(&p->p, &nexthop, 0) ? : p->neigh;
|
neighbor *ng = neigh_find(&p->p, &nexthop, 0) ? : p->neigh;
|
||||||
if (ng->scope == SCOPE_HOST)
|
if (ng->scope == SCOPE_HOST)
|
||||||
|
@ -819,7 +818,7 @@ bgp_set_next_hop(struct bgp_proto *p, rta *a)
|
||||||
a->iface = ng->iface;
|
a->iface = ng->iface;
|
||||||
a->hostentry = NULL;
|
a->hostentry = NULL;
|
||||||
}
|
}
|
||||||
else
|
else /* GW_RECURSIVE */
|
||||||
rta_set_recursive_next_hop(p->p.table, a, p->igp_table, &nexthop);
|
rta_set_recursive_next_hop(p->p.table, a, p->igp_table, &nexthop);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
Loading…
Reference in a new issue