1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
From 80d3b227f32679332957299a9c01da66cce54427 Mon Sep 17 00:00:00 2001
From: "Alexander V. Chernikov" <melifaro@yandex-team.ru>
Date: Fri, 19 Dec 2014 15:36:40 +0000
Subject: [PATCH 1/3] Simplify using templates for BGP:
Permit specifying remote as via 'remote as' statement.
Permit specifying interface for link-local sessions via 'interface'
statement.
Relax 'neighbor' statement: do not require specifying as.
---
conf/confbase.Y | 3 +--
doc/bird.sgml | 11 ++++++++++-
proto/bgp/bgp.c | 11 +++++++++++
proto/bgp/config.Y | 19 ++++++++++++-------
4 files changed, 34 insertions(+), 10 deletions(-)
diff --git conf/confbase.Y conf/confbase.Y
index 49831b1..ccc9e10 100644
--- conf/confbase.Y
+++ conf/confbase.Y
@@ -162,8 +162,7 @@ ipa_scope:
;
ipa_port:
- /* empty */ { $$ = 0; }
- | PORT expr {
+ PORT expr {
if (($2 < 1) || ($2 > 65535)) cf_error("Invalid port number");
$$ = $2;
}
diff --git doc/bird.sgml doc/bird.sgml
index 31b1d6f..e9e5920 100644
--- doc/bird.sgml
+++ doc/bird.sgml
@@ -1620,7 +1620,11 @@ 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>remote as <m/number/</tag>
+ Define neighboring AS number. AS number can also be specified inside
+ <cf/neighbor/ statement. In that case, this paremeter is optional.
+
+ <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.
@@ -1649,6 +1653,11 @@ using the following configuration parameters:
source address for the BGP session. Default: the address of the local
end of the interface our neighbor is connected to.
+ <tag>interface <m/iface/</tag>
+ Define interface we should use for link-local BGP IPv6 sessions. Interface
+ can also be specified inside <cf/neighbor address/. It is an error to use
+ this parameter for non link-local sessions. This parameter is optional.
+
<tag>next hop self</tag>
Avoid calculation of the Next Hop attribute and always advertise our own
source address as a next hop. This needs to be used only occasionally to
diff --git proto/bgp/bgp.c proto/bgp/bgp.c
index e233911..3fbedad 100644
--- proto/bgp/bgp.c
+++ proto/bgp/bgp.c
@@ -1157,6 +1157,9 @@ bgp_check_config(struct bgp_config *c)
if (!c->remote_as)
cf_error("Neighbor must be configured");
+ if (!c->remote_port)
+ cf_error("Correct BGP port must be set");
+
if (!(c->capabilities && c->enable_as4) && (c->remote_as > 0xFFFF))
cf_error("Neighbor AS number out of range (AS4 not available)");
@@ -1176,6 +1179,14 @@ bgp_check_config(struct bgp_config *c)
if (c->multihop && c->bfd && ipa_zero(c->source_addr))
cf_error("Multihop BGP with BFD requires specified source address");
+ if (!c->iface && (ipa_has_link_scope(c->remote_ip) ||
+ ipa_has_link_scope(c->source_addr)))
+ cf_error("Link-local BGP requires specifying interface");
+
+ if (c->iface && (!ipa_has_link_scope(c->remote_ip) &&
+ !ipa_has_link_scope(c->source_addr)))
+ cf_error("Explicit interface specified for global addresses");
+
if ((c->gw_mode == GW_RECURSIVE) && c->c.table->sorted)
cf_error("BGP in recursive mode prohibits sorted table");
diff --git proto/bgp/config.Y proto/bgp/config.Y
index 8e0b241..d04c16d 100644
--- proto/bgp/config.Y
+++ proto/bgp/config.Y
@@ -16,7 +16,7 @@ CF_DEFINES
CF_DECLS
-CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY,
+CF_KEYWORDS(BGP, LOCAL, REMOTE, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY,
KEEPALIVE, MULTIHOP, STARTUP, VIA, NEXT, HOP, SELF, DEFAULT,
PATH, METRIC, ERROR, START, DELAY, FORGET, WAIT, ENABLE,
DISABLE, AFTER, BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN,
@@ -52,24 +52,29 @@ bgp_proto_start: proto_start BGP {
BGP_CFG->default_local_pref = 100;
BGP_CFG->gr_mode = BGP_GR_AWARE;
BGP_CFG->gr_time = 120;
+ BGP_CFG->remote_port = BGP_PORT;
}
;
+bpg_neighbor_opts:
+ | ipa_port { if ($1 != 0) BGP_CFG->remote_port = $1; }
+ | AS expr { BGP_CFG->remote_as = $2; }
+ ;
+
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 REMOTE AS expr ';' { BGP_CFG->remote_as = $4; }
+ | bgp_proto INTERFACE SYM ';' { BGP_CFG->iface = if_get_by_name($3->name); }
+ | bgp_proto NEIGHBOR ipa ipa_scope bpg_neighbor_opts ';' {
if (ipa_nonzero(BGP_CFG->remote_ip))
cf_error("Only one neighbor per BGP instance is allowed");
- if (!ipa_has_link_scope($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 != NULL)
+ BGP_CFG->iface = $4;
}
| bgp_proto RR CLUSTER ID idval ';' { BGP_CFG->rr_cluster_id = $5; }
| bgp_proto RR CLIENT ';' { BGP_CFG->rr_client = 1; }
--
2.1.2
|