diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2015-02-22 13:50:58 +0100 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2015-02-22 13:50:58 +0100 |
commit | a1beb8f3ee7a6e41dbe4bfd336b8bf5eecb46d01 (patch) | |
tree | 07e3269bb4fa1bb649af14e0aaf931003777e601 | |
parent | 86c3eea0f3ec74ac1024d4aba4e98c962126f387 (diff) |
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.
-rw-r--r-- | conf/confbase.Y | 10 | ||||
-rw-r--r-- | doc/bird.sgml | 16 | ||||
-rw-r--r-- | proto/bgp/bgp.c | 11 | ||||
-rw-r--r-- | proto/bgp/config.Y | 20 |
4 files changed, 36 insertions, 21 deletions
diff --git a/conf/confbase.Y b/conf/confbase.Y index 16a493e9..5f487c1d 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -72,7 +72,7 @@ CF_DECLS %token <t> TEXT %type <iface> ipa_scope -%type <i> expr bool pxlen ipa_port +%type <i> expr bool pxlen %type <i32> expr_us %type <time> datetime %type <a> ipa @@ -161,14 +161,6 @@ ipa_scope: | '%' 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: ipa pxlen { if (!ip_is_prefix($1, $2)) cf_error("Invalid prefix"); diff --git a/doc/bird.sgml b/doc/bird.sgml index 1ba52481..5483ee63 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1620,10 +1620,20 @@ using the following configuration parameters: address, equivalent to the <cf/source address/ option (see below). This 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 - it's located in. In case the neighbor is in the same AS as we are, we - automatically switch to iBGP. This parameter is mandatory. + it is located in. In case the neighbor is in the same AS as we are, we + 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> Specify that the neighbor is directly connected. The IP address of the diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 016d3e60..07fd8478 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -1196,9 +1196,18 @@ bgp_check_config(struct bgp_config *c) if (!c->local_as) cf_error("Local AS number must be set"); - if (!c->remote_as) + if (ipa_zero(c->remote_ip)) 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)) cf_error("Neighbor AS number out of range (AS4 not available)"); diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index ed40634f..2da79530 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -27,7 +27,7 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, INTERPRET, COMMUNITIES, BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP, TABLE, GATEWAY, DIRECT, RECURSIVE, MED, TTL, SECURITY, DETERMINISTIC, SECONDARY, ALLOW, BFD, ADD, PATHS, RX, TX, GRACEFUL, RESTART, AWARE, - CHECK, LINK) + CHECK, LINK, PORT) CF_GRAMMAR @@ -35,6 +35,7 @@ CF_ADDTO(proto, bgp_proto '}' { bgp_check_config(BGP_CFG); } ) bgp_proto_start: proto_start BGP { this_proto = proto_config_new(&proto_bgp, $1); + BGP_CFG->remote_port = BGP_PORT; BGP_CFG->multihop = -1; /* undefined */ BGP_CFG->hold_time = 240; 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_start proto_name '{' | bgp_proto proto_item ';' | 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 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)) 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->iface = $4; - BGP_CFG->remote_port = ($5 > 0) ? $5 : BGP_PORT; - BGP_CFG->remote_as = $7; + if ($4) BGP_CFG->iface = $4; } + | 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 CLIENT ';' { BGP_CFG->rr_client = 1; } | bgp_proto RS CLIENT ';' { BGP_CFG->rs_client = 1; } |