Relax BGP neighbor parameter

Permit specifying neighbor address, AS number and port independently.
Add 'interface' parameter for specifying interface for link-local
sessions independently.

Thanks to Alexander V. Chernikov for the original patch.
This commit is contained in:
Ondrej Zajicek 2015-02-22 13:50:58 +01:00
parent 86c3eea0f3
commit a1beb8f3ee
4 changed files with 36 additions and 21 deletions

View file

@ -72,7 +72,7 @@ CF_DECLS
%token <t> TEXT %token <t> TEXT
%type <iface> ipa_scope %type <iface> ipa_scope
%type <i> expr bool pxlen ipa_port %type <i> expr bool pxlen
%type <i32> expr_us %type <i32> expr_us
%type <time> datetime %type <time> datetime
%type <a> ipa %type <a> ipa
@ -161,14 +161,6 @@ ipa_scope:
| '%' SYM { $$ = if_get_by_name($2->name); } | '%' SYM { $$ = if_get_by_name($2->name); }
; ;
ipa_port:
/* empty */ { $$ = 0; }
| PORT expr {
if (($2 < 1) || ($2 > 65535)) cf_error("Invalid port number");
$$ = $2;
}
;
prefix: prefix:
ipa pxlen { ipa pxlen {
if (!ip_is_prefix($1, $2)) cf_error("Invalid prefix"); if (!ip_is_prefix($1, $2)) cf_error("Invalid prefix");

View file

@ -1620,10 +1620,20 @@ using the following configuration parameters:
address, equivalent to the <cf/source address/ option (see below). This address, equivalent to the <cf/source address/ option (see below). This
parameter is mandatory. parameter is mandatory.
<tag>neighbor <m/ip/ [port <m/number/] as <m/number/</tag> <tag>neighbor [<m/ip/] [port <m/number/] [as <m/number/]</tag>
Define neighboring router this instance will be talking to and what AS Define neighboring router this instance will be talking to and what AS
it's located in. In case the neighbor is in the same AS as we are, we it is located in. In case the neighbor is in the same AS as we are, we
automatically switch to iBGP. This parameter is mandatory. automatically switch to iBGP. Optionally, the remote port may also be
specified. The parameter may be used multiple times with different
sub-options (e.g., both <cf/neighbor 10.0.0.1 as 65000;/ and
<cf/neighbor 10.0.0.1; neighbor as 65000;/ are valid). This parameter is
mandatory.
<tag>interface <m/string/</tag>
Define interface we should use for link-local BGP IPv6 sessions.
Interface can also be specified as a part of <cf/neighbor address/
(e.g., <cf/neighbor fe80::1234%eth0 as 65000;/). It is an error to use
this parameter for non link-local sessions.
<tag>direct</tag> <tag>direct</tag>
Specify that the neighbor is directly connected. The IP address of the Specify that the neighbor is directly connected. The IP address of the

View file

@ -1196,9 +1196,18 @@ bgp_check_config(struct bgp_config *c)
if (!c->local_as) if (!c->local_as)
cf_error("Local AS number must be set"); cf_error("Local AS number must be set");
if (!c->remote_as) if (ipa_zero(c->remote_ip))
cf_error("Neighbor must be configured"); cf_error("Neighbor must be configured");
if (!c->remote_as)
cf_error("Remote AS number must be set");
// if (ipa_is_link_local(c->remote_ip) && !c->iface)
// cf_error("Link-local neighbor address requires specified interface");
if (!ipa_is_link_local(c->remote_ip) != !c->iface)
cf_error("Link-local address and interface scope must be used together");
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)");

View file

@ -27,7 +27,7 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY,
INTERPRET, COMMUNITIES, BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP, INTERPRET, COMMUNITIES, BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP,
TABLE, GATEWAY, DIRECT, RECURSIVE, MED, TTL, SECURITY, DETERMINISTIC, TABLE, GATEWAY, DIRECT, RECURSIVE, MED, TTL, SECURITY, DETERMINISTIC,
SECONDARY, ALLOW, BFD, ADD, PATHS, RX, TX, GRACEFUL, RESTART, AWARE, SECONDARY, ALLOW, BFD, ADD, PATHS, RX, TX, GRACEFUL, RESTART, AWARE,
CHECK, LINK) CHECK, LINK, PORT)
CF_GRAMMAR CF_GRAMMAR
@ -35,6 +35,7 @@ CF_ADDTO(proto, bgp_proto '}' { bgp_check_config(BGP_CFG); } )
bgp_proto_start: proto_start BGP { bgp_proto_start: proto_start BGP {
this_proto = proto_config_new(&proto_bgp, $1); this_proto = proto_config_new(&proto_bgp, $1);
BGP_CFG->remote_port = BGP_PORT;
BGP_CFG->multihop = -1; /* undefined */ BGP_CFG->multihop = -1; /* undefined */
BGP_CFG->hold_time = 240; BGP_CFG->hold_time = 240;
BGP_CFG->connect_retry_time = 120; BGP_CFG->connect_retry_time = 120;
@ -56,22 +57,25 @@ bgp_proto_start: proto_start BGP {
} }
; ;
bgp_nbr_opts:
/* empty */
| bgp_nbr_opts PORT expr { BGP_CFG->remote_port = $3; if (($3<1) || ($3>65535)) cf_error("Invalid port number"); }
| bgp_nbr_opts AS expr { BGP_CFG->remote_as = $3; }
;
bgp_proto: bgp_proto:
bgp_proto_start proto_name '{' bgp_proto_start proto_name '{'
| bgp_proto proto_item ';' | bgp_proto proto_item ';'
| bgp_proto LOCAL AS expr ';' { BGP_CFG->local_as = $4; } | bgp_proto LOCAL AS expr ';' { BGP_CFG->local_as = $4; }
| bgp_proto LOCAL ipa AS expr ';' { BGP_CFG->source_addr = $3; BGP_CFG->local_as = $5; } | bgp_proto LOCAL ipa AS expr ';' { BGP_CFG->source_addr = $3; BGP_CFG->local_as = $5; }
| bgp_proto NEIGHBOR ipa ipa_scope ipa_port AS expr ';' { | bgp_proto NEIGHBOR bgp_nbr_opts ';'
| bgp_proto NEIGHBOR ipa ipa_scope bgp_nbr_opts ';' {
if (ipa_nonzero(BGP_CFG->remote_ip)) if (ipa_nonzero(BGP_CFG->remote_ip))
cf_error("Only one neighbor per BGP instance is allowed"); cf_error("Only one neighbor per BGP instance is allowed");
if (!ipa_is_link_local($3) != !$4)
cf_error("Link-local address and interface scope must be used together");
BGP_CFG->remote_ip = $3; BGP_CFG->remote_ip = $3;
BGP_CFG->iface = $4; if ($4) BGP_CFG->iface = $4;
BGP_CFG->remote_port = ($5 > 0) ? $5 : BGP_PORT;
BGP_CFG->remote_as = $7;
} }
| bgp_proto INTERFACE TEXT ';' { BGP_CFG->iface = if_get_by_name($3); }
| bgp_proto RR CLUSTER ID idval ';' { BGP_CFG->rr_cluster_id = $5; } | bgp_proto RR CLUSTER ID idval ';' { BGP_CFG->rr_cluster_id = $5; }
| bgp_proto RR CLIENT ';' { BGP_CFG->rr_client = 1; } | bgp_proto RR CLIENT ';' { BGP_CFG->rr_client = 1; }
| bgp_proto RS CLIENT ';' { BGP_CFG->rs_client = 1; } | bgp_proto RS CLIENT ';' { BGP_CFG->rs_client = 1; }