summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2015-02-22 13:50:58 +0100
committerOndrej Zajicek <santiago@crfreenet.org>2015-02-22 13:50:58 +0100
commita1beb8f3ee7a6e41dbe4bfd336b8bf5eecb46d01 (patch)
tree07e3269bb4fa1bb649af14e0aaf931003777e601
parent86c3eea0f3ec74ac1024d4aba4e98c962126f387 (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.Y10
-rw-r--r--doc/bird.sgml16
-rw-r--r--proto/bgp/bgp.c11
-rw-r--r--proto/bgp/config.Y20
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; }