BGP: Mandatory option for channels
Allow to mark channel to be mandatory, and do not allow BGP sessions if no common AFI/SAFI is established.
This commit is contained in:
parent
7e5f769d91
commit
3c3605818f
4 changed files with 52 additions and 1 deletions
|
@ -2565,6 +2565,15 @@ be used in explicit configuration.
|
||||||
<p>BGP channels have additional config options (together with the common ones):
|
<p>BGP channels have additional config options (together with the common ones):
|
||||||
|
|
||||||
<descrip>
|
<descrip>
|
||||||
|
<tag><label id="bgp-mandatory">mandatory <m/switch/</tag>
|
||||||
|
When local and neighbor sets of configured AFI/SAFI pairs differ,
|
||||||
|
capability negotiation ensures that a common subset is used. For
|
||||||
|
mandatory channels their associated AFI/SAFI must be negotiated
|
||||||
|
(i.e., also announced by the neighbor), otherwise BGP session
|
||||||
|
negotiation fails with <it/'Required capability missing'/ error.
|
||||||
|
Regardless, at least one AFI/SAFI must be negotiated in order to BGP
|
||||||
|
session be successfully established. Default: off.
|
||||||
|
|
||||||
<tag><label id="bgp-next-hop-keep">next hop keep <m/switch/|ibgp|ebgp</tag>
|
<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
|
Do not modify the Next Hop attribute and advertise the current one
|
||||||
unchanged even in cases where our own local address should be used
|
unchanged even in cases where our own local address should be used
|
||||||
|
|
|
@ -136,6 +136,7 @@ struct bgp_channel_config {
|
||||||
ip_addr next_hop_addr; /* Local address for NEXT_HOP attribute */
|
ip_addr next_hop_addr; /* Local address for NEXT_HOP attribute */
|
||||||
u8 next_hop_self; /* Always set next hop to local IP address (NH_*) */
|
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 next_hop_keep; /* Do not modify next hop attribute (NH_*) */
|
||||||
|
u8 mandatory; /* Channel is mandatory in capability negotiation */
|
||||||
u8 missing_lladdr; /* What we will do when we don' know link-local addr, see MLL_* */
|
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 gw_mode; /* How we compute route gateway from next_hop attr, see GW_* */
|
||||||
u8 secondary; /* Accept also non-best routes (i.e. RA_ACCEPTED) */
|
u8 secondary; /* Accept also non-best routes (i.e. RA_ACCEPTED) */
|
||||||
|
|
|
@ -29,7 +29,7 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE,
|
||||||
SECURITY, DETERMINISTIC, SECONDARY, ALLOW, BFD, ADD, PATHS, RX, TX,
|
SECURITY, DETERMINISTIC, SECONDARY, ALLOW, BFD, ADD, PATHS, RX, TX,
|
||||||
GRACEFUL, RESTART, AWARE, CHECK, LINK, PORT, EXTENDED, MESSAGES, SETKEY,
|
GRACEFUL, RESTART, AWARE, CHECK, LINK, PORT, EXTENDED, MESSAGES, SETKEY,
|
||||||
STRICT, BIND, CONFEDERATION, MEMBER, MULTICAST, FLOW4, FLOW6, LONG,
|
STRICT, BIND, CONFEDERATION, MEMBER, MULTICAST, FLOW4, FLOW6, LONG,
|
||||||
LIVED, STALE, IMPORT, IBGP, EBGP)
|
LIVED, STALE, IMPORT, IBGP, EBGP, MANDATORY)
|
||||||
|
|
||||||
%type <i> bgp_nh
|
%type <i> bgp_nh
|
||||||
%type <i32> bgp_afi
|
%type <i32> bgp_afi
|
||||||
|
@ -223,6 +223,7 @@ bgp_channel_item:
|
||||||
| NEXT HOP ADDRESS ipa { BGP_CC->next_hop_addr = $4; }
|
| NEXT HOP ADDRESS ipa { BGP_CC->next_hop_addr = $4; }
|
||||||
| NEXT HOP SELF bgp_nh { BGP_CC->next_hop_self = $4; }
|
| NEXT HOP SELF bgp_nh { BGP_CC->next_hop_self = $4; }
|
||||||
| NEXT HOP KEEP bgp_nh { BGP_CC->next_hop_keep = $4; }
|
| NEXT HOP KEEP bgp_nh { BGP_CC->next_hop_keep = $4; }
|
||||||
|
| MANDATORY bool { BGP_CC->mandatory = $2; }
|
||||||
| MISSING LLADDR SELF { BGP_CC->missing_lladdr = MLL_SELF; }
|
| MISSING LLADDR SELF { BGP_CC->missing_lladdr = MLL_SELF; }
|
||||||
| MISSING LLADDR DROP { BGP_CC->missing_lladdr = MLL_DROP; }
|
| MISSING LLADDR DROP { BGP_CC->missing_lladdr = MLL_DROP; }
|
||||||
| MISSING LLADDR IGNORE { BGP_CC->missing_lladdr = MLL_IGNORE; }
|
| MISSING LLADDR IGNORE { BGP_CC->missing_lladdr = MLL_IGNORE; }
|
||||||
|
|
|
@ -573,6 +573,42 @@ err:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
bgp_check_capabilities(struct bgp_conn *conn)
|
||||||
|
{
|
||||||
|
struct bgp_proto *p = conn->bgp;
|
||||||
|
struct bgp_caps *local = conn->local_caps;
|
||||||
|
struct bgp_caps *remote = conn->remote_caps;
|
||||||
|
struct bgp_channel *c;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
/* This is partially overlapping with bgp_conn_enter_established_state(),
|
||||||
|
but we need to run this just after we receive OPEN message */
|
||||||
|
|
||||||
|
WALK_LIST(c, p->p.channels)
|
||||||
|
{
|
||||||
|
const struct bgp_af_caps *loc = bgp_find_af_caps(local, c->afi);
|
||||||
|
const struct bgp_af_caps *rem = bgp_find_af_caps(remote, c->afi);
|
||||||
|
|
||||||
|
/* Find out whether this channel will be active */
|
||||||
|
int active = loc && loc->ready &&
|
||||||
|
((rem && rem->ready) || (!remote->length && (c->afi == BGP_AF_IPV4)));
|
||||||
|
|
||||||
|
/* Mandatory must be active */
|
||||||
|
if (c->cf->mandatory && !active)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (active)
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We need at least one channel active */
|
||||||
|
if (!count)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bgp_read_options(struct bgp_conn *conn, byte *pos, int len)
|
bgp_read_options(struct bgp_conn *conn, byte *pos, int len)
|
||||||
{
|
{
|
||||||
|
@ -683,6 +719,10 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, uint len)
|
||||||
if (!id || (p->is_internal && id == p->local_id))
|
if (!id || (p->is_internal && id == p->local_id))
|
||||||
{ bgp_error(conn, 2, 3, pkt+24, -4); return; }
|
{ bgp_error(conn, 2, 3, pkt+24, -4); return; }
|
||||||
|
|
||||||
|
/* RFC 5492 4 - check for required capabilities */
|
||||||
|
if (p->cf->capabilities && !bgp_check_capabilities(conn))
|
||||||
|
{ bgp_error(conn, 2, 7, NULL, 0); return; }
|
||||||
|
|
||||||
struct bgp_caps *caps = conn->remote_caps;
|
struct bgp_caps *caps = conn->remote_caps;
|
||||||
|
|
||||||
if (caps->as4_support)
|
if (caps->as4_support)
|
||||||
|
|
Loading…
Reference in a new issue