]>
Commit | Line | Data |
---|---|---|
da877822 MM |
1 | /* |
2 | * BIRD -- Core Configuration | |
3 | * | |
4b87e256 | 4 | * (c) 1998--2000 Martin Mares <mj@ucw.cz> |
bc956fca | 5 | * (c) 2004 Ondrej Filip <feela@network.cz> |
da877822 MM |
6 | * |
7 | * Can be freely distributed and used under the terms of the GNU GPL. | |
8 | */ | |
9 | ||
10 | CF_HDR | |
11 | ||
50d8424a | 12 | #include "nest/rt-dev.h" |
1a2ded45 | 13 | #include "nest/password.h" |
4b87e256 | 14 | #include "nest/cmds.h" |
5236fb03 | 15 | #include "lib/lists.h" |
56cb3bed | 16 | #include "lib/mac.h" |
50d8424a | 17 | |
2edb31b0 MM |
18 | CF_DEFINES |
19 | ||
20 | static struct proto_config *this_proto; | |
f4a60a9b | 21 | static struct channel_config *this_channel; |
2edb31b0 | 22 | static struct iface_patt *this_ipatt; |
20e94fb8 | 23 | static struct iface_patt_node *this_ipn; |
9656dce7 | 24 | /* static struct roa_table_config *this_roa_table; */ |
5236fb03 OF |
25 | static list *this_p_list; |
26 | static struct password_item *this_p_item; | |
b21f68b4 OZ |
27 | static int password_id; |
28 | ||
d7c06285 OZ |
29 | static void |
30 | iface_patt_check(void) | |
31 | { | |
32 | struct iface_patt_node *pn; | |
33 | ||
34 | WALK_LIST(pn, this_ipatt->ipn_list) | |
04632fd7 | 35 | if (!pn->pattern || pn->prefix.type) |
d7c06285 OZ |
36 | cf_error("Interface name/mask expected, not IP prefix"); |
37 | } | |
38 | ||
39 | ||
024c310b OZ |
40 | static inline void |
41 | reset_passwords(void) | |
42 | { | |
a7f23f58 | 43 | this_p_list = NULL; |
024c310b OZ |
44 | } |
45 | ||
46 | static inline list * | |
b21f68b4 OZ |
47 | get_passwords(void) |
48 | { | |
49 | list *rv = this_p_list; | |
50 | this_p_list = NULL; | |
51 | return rv; | |
52 | } | |
53 | ||
f4a60a9b OZ |
54 | static void |
55 | proto_postconfig(void) | |
56 | { | |
57 | CALL(this_proto->protocol->postconfig, this_proto); | |
58 | this_channel = NULL; | |
59 | this_proto = NULL; | |
60 | } | |
61 | ||
62 | ||
a7f23f58 | 63 | #define DIRECT_CFG ((struct rt_dev_config *) this_proto) |
2edb31b0 | 64 | |
da877822 MM |
65 | CF_DECLS |
66 | ||
a7f23f58 | 67 | CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT) |
943478b0 | 68 | CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, VRF, TABLE, STATES, ROUTES, FILTERS) |
be17805c | 69 | CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, SADR, MPLS) |
b662290f | 70 | CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED) |
6a9f28b0 | 71 | CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES) |
56cb3bed | 72 | CF_KEYWORDS(ALGORITHM, KEYED, HMAC, MD5, SHA1, SHA256, SHA384, SHA512) |
2faf519c | 73 | CF_KEYWORDS(PRIMARY, STATS, COUNT, BY, FOR, COMMANDS, PREEXPORT, NOEXPORT, GENERATE) |
3e52d112 | 74 | CF_KEYWORDS(BGP, PASSWORDS, DESCRIPTION, SORTED) |
ef4a50be | 75 | CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP) |
f047271c | 76 | CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, ROUTE, PROTOCOL, BASE, LOG, S, MS, US) |
7aa80901 | 77 | CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS) |
da877822 | 78 | |
b2949999 | 79 | /* For r_args_channel */ |
be17805c | 80 | CF_KEYWORDS(IPV4, IPV4_MC, IPV4_MPLS, IPV6, IPV6_MC, IPV6_MPLS, IPV6_SADR, VPN4, VPN4_MC, VPN4_MPLS, VPN6, VPN6_MC, VPN6_MPLS, ROA4, ROA6, FLOW4, FLOW6, MPLS, PRI, SEC) |
b2949999 | 81 | |
7d509304 | 82 | CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT, |
12640c14 | 83 | RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE, BABEL) |
bf6d91dc | 84 | CF_ENUM(T_ENUM_SCOPE, SCOPE_, HOST, LINK, SITE, ORGANIZATION, UNIVERSE, UNDEFINED) |
4e276a89 | 85 | CF_ENUM(T_ENUM_RTD, RTD_, UNICAST, BLACKHOLE, UNREACHABLE, PROHIBIT) |
cb1bd816 | 86 | CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID) |
7d509304 | 87 | |
dce26783 | 88 | %type <i32> idval |
5056c559 | 89 | %type <f> imexport |
0e02abfd | 90 | %type <r> rtable |
9eef9c64 | 91 | %type <s> optproto |
730f2e2c | 92 | %type <ra> r_args |
0f808c06 | 93 | %type <sd> sym_args |
8860e991 | 94 | %type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode limit_action net_type table_sorted tos password_algorithm |
e304fd4b | 95 | %type <ps> proto_patt proto_patt2 |
f4a60a9b OZ |
96 | %type <cc> channel_start proto_channel |
97 | %type <cl> limit_spec | |
3484cb9a MM |
98 | %type <net> r_args_for_val |
99 | %type <net_ptr> r_args_for | |
b2949999 | 100 | %type <t> r_args_channel |
da877822 MM |
101 | |
102 | CF_GRAMMAR | |
103 | ||
c74c0e3c MM |
104 | /* Setting of router ID */ |
105 | ||
f851f0d7 | 106 | conf: rtrid ; |
0e02abfd | 107 | |
04632fd7 | 108 | rtrid: |
79b4e12e OZ |
109 | ROUTER ID idval ';' { new_config->router_id = $3; } |
110 | | ROUTER ID FROM iface_patt ';' { new_config->router_id_from = this_ipatt; } | |
da877822 MM |
111 | ; |
112 | ||
113 | idval: | |
dce26783 | 114 | NUM { $$ = $1; } |
23e3b1e6 | 115 | | '(' term ')' { $$ = f_eval_int(f_linearize($2)); } |
fe9f1a6d | 116 | | IP4 { $$ = ip4_to_u32($1); } |
9eef9c64 | 117 | | CF_SYM_KNOWN { |
17661ff9 OZ |
118 | if ($1->class == (SYM_CONSTANT | T_INT) || $1->class == (SYM_CONSTANT | T_QUAD)) |
119 | $$ = SYM_VAL($1).i; | |
5e173e9f MM |
120 | else if (($1->class == (SYM_CONSTANT | T_IP)) && ipa_is_ip4(SYM_VAL($1).ip)) |
121 | $$ = ipa_to_u32(SYM_VAL($1).ip); | |
17661ff9 | 122 | else |
79a4f74a | 123 | cf_error("Number or IPv4 address constant expected"); |
17661ff9 | 124 | } |
da877822 MM |
125 | ; |
126 | ||
f851f0d7 | 127 | conf: gr_opts ; |
0c791f87 OZ |
128 | |
129 | gr_opts: GRACEFUL RESTART WAIT expr ';' { new_config->gr_wait = $4; } ; | |
130 | ||
131 | ||
f4a60a9b | 132 | /* Network types (for tables, channels) */ |
0e02abfd | 133 | |
f4a60a9b OZ |
134 | net_type: |
135 | IPV4 { $$ = NET_IP4; } | |
0bf95f99 | 136 | | IPV6 { $$ = NET_IP6; } |
be17805c | 137 | | IPV6 SADR { $$ = NET_IP6_SADR; } |
fe9f1a6d OZ |
138 | | VPN4 { $$ = NET_VPN4; } |
139 | | VPN6 { $$ = NET_VPN6; } | |
f9d729ab PT |
140 | | ROA4 { $$ = NET_ROA4; } |
141 | | ROA6 { $$ = NET_ROA6; } | |
77234bbb OZ |
142 | | FLOW4{ $$ = NET_FLOW4; } |
143 | | FLOW6{ $$ = NET_FLOW6; } | |
66acbc8d | 144 | | MPLS { $$ = NET_MPLS; } |
fe9f1a6d OZ |
145 | ; |
146 | ||
be17805c | 147 | CF_ENUM(T_ENUM_NETTYPE, NET_, IP4, IP6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, IP6_SADR) |
8c9986d3 | 148 | |
f4a60a9b OZ |
149 | |
150 | /* Creation of routing tables */ | |
151 | ||
f851f0d7 | 152 | conf: table ; |
f4a60a9b | 153 | |
fe9f1a6d | 154 | table_sorted: |
a82f692e | 155 | { $$ = 0; } |
26822d8f OZ |
156 | | SORTED { $$ = 1; } |
157 | ; | |
158 | ||
c0e958e0 | 159 | table: net_type TABLE CF_SYM_VOID table_sorted { |
26822d8f | 160 | struct rtable_config *cf; |
fe9f1a6d OZ |
161 | cf = rt_new_table($3, $1); |
162 | cf->sorted = $4; | |
0e02abfd MM |
163 | } |
164 | ; | |
165 | ||
f4a60a9b | 166 | |
c74c0e3c MM |
167 | /* Definition of protocols */ |
168 | ||
f851f0d7 | 169 | conf: proto { proto_postconfig(); } ; |
c74c0e3c | 170 | |
a7f23f58 OZ |
171 | proto_start: |
172 | PROTOCOL { $$ = SYM_PROTO; } | |
173 | | TEMPLATE { $$ = SYM_TEMPLATE; } | |
de10a974 | 174 | ; |
c74c0e3c MM |
175 | |
176 | proto_name: | |
177 | /* EMPTY */ { | |
d272fe22 | 178 | struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter); |
a7f23f58 | 179 | s->class = this_proto->class; |
0b39b1cb | 180 | s->proto = this_proto; |
c74c0e3c MM |
181 | this_proto->name = s->name; |
182 | } | |
c0e958e0 | 183 | | CF_SYM_VOID { |
0b39b1cb | 184 | cf_define_symbol($1, this_proto->class, proto, this_proto); |
c74c0e3c MM |
185 | this_proto->name = $1->name; |
186 | } | |
9eef9c64 MM |
187 | | FROM CF_SYM_KNOWN { |
188 | if (($2->class != SYM_TEMPLATE) && ($2->class != SYM_PROTO)) cf_error("Template or protocol name expected"); | |
189 | ||
a5a5a41e | 190 | struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter); |
9fe1d3ca | 191 | s->class = this_proto->class; |
0b39b1cb | 192 | s->proto = this_proto; |
a5a5a41e | 193 | this_proto->name = s->name; |
9fe1d3ca | 194 | |
0b39b1cb | 195 | proto_copy_config(this_proto, $2->proto); |
a5a5a41e | 196 | } |
9eef9c64 MM |
197 | | CF_SYM_VOID FROM CF_SYM_KNOWN { |
198 | if (($3->class != SYM_TEMPLATE) && ($3->class != SYM_PROTO)) cf_error("Template or protocol name expected"); | |
199 | ||
0b39b1cb | 200 | cf_define_symbol($1, this_proto->class, proto, this_proto); |
a7f23f58 OZ |
201 | this_proto->name = $1->name; |
202 | ||
0b39b1cb | 203 | proto_copy_config(this_proto, $3->proto); |
a7f23f58 | 204 | } |
c74c0e3c MM |
205 | ; |
206 | ||
207 | proto_item: | |
208 | /* EMPTY */ | |
ca77641d | 209 | | DISABLED bool { this_proto->disabled = $2; } |
96d8e3bf | 210 | | DEBUG debug_mask { this_proto->debug = $2; } |
cf31112f | 211 | | MRTDUMP mrtdump_mask { this_proto->mrtdump = $2; } |
4cdd0784 | 212 | | ROUTER ID idval { this_proto->router_id = $3; } |
9eceab33 | 213 | | DESCRIPTION text { this_proto->dsc = $2; } |
46434a3c | 214 | | VRF text { this_proto->vrf = if_get_by_name($2); } |
5056c559 MM |
215 | ; |
216 | ||
f4a60a9b OZ |
217 | |
218 | channel_start: net_type | |
219 | { | |
72163bd5 | 220 | $$ = this_channel = channel_config_get(NULL, net_label[$1], $1, this_proto); |
f4a60a9b OZ |
221 | }; |
222 | ||
223 | channel_item: | |
224 | TABLE rtable { | |
225 | if (this_channel->net_type && ($2->addr_type != this_channel->net_type)) | |
226 | cf_error("Incompatible table type"); | |
227 | this_channel->table = $2; | |
228 | } | |
229 | | IMPORT imexport { this_channel->in_filter = $2; } | |
230 | | EXPORT imexport { this_channel->out_filter = $2; } | |
231 | | RECEIVE LIMIT limit_spec { this_channel->rx_limit = $3; } | |
232 | | IMPORT LIMIT limit_spec { this_channel->in_limit = $3; } | |
233 | | EXPORT LIMIT limit_spec { this_channel->out_limit = $3; } | |
234 | | PREFERENCE expr { this_channel->preference = $2; check_u16($2); } | |
235 | | IMPORT KEEP FILTERED bool { this_channel->in_keep_filtered = $4; } | |
236 | ; | |
237 | ||
238 | channel_opts: | |
239 | /* empty */ | |
240 | | channel_opts channel_item ';' | |
241 | ; | |
242 | ||
243 | channel_opt_list: | |
244 | /* empty */ | |
245 | | '{' channel_opts '}' | |
246 | ; | |
247 | ||
248 | channel_end: | |
249 | { | |
250 | if (!this_channel->table) | |
251 | cf_error("Routing table not specified"); | |
252 | ||
253 | this_channel = NULL; | |
254 | }; | |
255 | ||
256 | proto_channel: channel_start channel_opt_list channel_end; | |
257 | ||
258 | ||
9eef9c64 | 259 | rtable: CF_SYM_KNOWN { cf_assert_symbol($1, SYM_TABLE); $$ = $1->table; } ; |
f4a60a9b | 260 | |
5056c559 MM |
261 | imexport: |
262 | FILTER filter { $$ = $2; } | |
f8809249 | 263 | | where_filter |
5056c559 MM |
264 | | ALL { $$ = FILTER_ACCEPT; } |
265 | | NONE { $$ = FILTER_REJECT; } | |
c74c0e3c MM |
266 | ; |
267 | ||
ebecb6f6 | 268 | limit_action: |
d9b77cc2 | 269 | /* default */ { $$ = PLA_DISABLE; } |
bf422073 OZ |
270 | | ACTION WARN { $$ = PLA_WARN; } |
271 | | ACTION BLOCK { $$ = PLA_BLOCK; } | |
272 | | ACTION RESTART { $$ = PLA_RESTART; } | |
273 | | ACTION DISABLE { $$ = PLA_DISABLE; } | |
ebecb6f6 OZ |
274 | ; |
275 | ||
276 | limit_spec: | |
f4a60a9b OZ |
277 | expr limit_action { $$ = (struct channel_limit){ .limit = $1, $$.action = $2 }; } |
278 | | OFF { $$ = (struct channel_limit){}; } | |
0e02abfd MM |
279 | ; |
280 | ||
f047271c | 281 | |
f851f0d7 | 282 | conf: debug_default ; |
f30b86f9 MM |
283 | |
284 | debug_default: | |
285 | DEBUG PROTOCOLS debug_mask { new_config->proto_default_debug = $3; } | |
4761efdb | 286 | | DEBUG COMMANDS expr { new_config->cli_debug = $3; } |
f30b86f9 MM |
287 | ; |
288 | ||
cf31112f OZ |
289 | /* MRTDUMP PROTOCOLS is in systep/unix/config.Y */ |
290 | ||
f851f0d7 | 291 | conf: timeformat_base ; |
f047271c OZ |
292 | |
293 | timeformat_which: | |
294 | ROUTE { $$ = &new_config->tf_route; } | |
295 | | PROTOCOL { $$ = &new_config->tf_proto; } | |
296 | | BASE { $$ = &new_config->tf_base; } | |
297 | | LOG { $$ = &new_config->tf_log; } | |
298 | ; | |
299 | ||
300 | timeformat_spec: | |
301 | timeformat_which TEXT { *$1 = (struct timeformat){$2, NULL, 0}; } | |
302 | | timeformat_which TEXT expr TEXT { *$1 = (struct timeformat){$2, $4, (s64) $3 S_}; } | |
303 | | timeformat_which ISO SHORT { *$1 = TM_ISO_SHORT_S; } | |
304 | | timeformat_which ISO SHORT MS { *$1 = TM_ISO_SHORT_MS; } | |
305 | | timeformat_which ISO SHORT US { *$1 = TM_ISO_SHORT_US; } | |
306 | | timeformat_which ISO LONG { *$1 = TM_ISO_LONG_S; } | |
307 | | timeformat_which ISO LONG MS { *$1 = TM_ISO_LONG_MS; } | |
308 | | timeformat_which ISO LONG US { *$1 = TM_ISO_LONG_US; } | |
309 | ; | |
310 | ||
311 | timeformat_base: | |
312 | TIMEFORMAT timeformat_spec ';' | |
313 | ; | |
314 | ||
315 | ||
8edf2361 MM |
316 | /* Interface patterns */ |
317 | ||
20e94fb8 OZ |
318 | iface_patt_node_init: |
319 | /* EMPTY */ { | |
320 | struct iface_patt_node *ipn = cfg_allocz(sizeof(struct iface_patt_node)); | |
321 | add_tail(&this_ipatt->ipn_list, NODE ipn); | |
322 | this_ipn = ipn; | |
323 | } | |
324 | ; | |
325 | ||
326 | iface_patt_node_body: | |
04632fd7 OZ |
327 | TEXT { this_ipn->pattern = $1; /* this_ipn->prefix stays zero */ } |
328 | | opttext net_or_ipa { this_ipn->pattern = $1; this_ipn->prefix = $2; } | |
20e94fb8 OZ |
329 | ; |
330 | ||
331 | iface_negate: | |
332 | { this_ipn->positive = 1; } | |
333 | | '-' { this_ipn->positive = 0; } | |
334 | ; | |
335 | ||
336 | iface_patt_node: | |
04632fd7 | 337 | iface_patt_node_init iface_negate iface_patt_node_body |
20e94fb8 OZ |
338 | ; |
339 | ||
340 | ||
341 | iface_patt_list: | |
342 | iface_patt_node | |
343 | | iface_patt_list ',' iface_patt_node | |
8edf2361 MM |
344 | ; |
345 | ||
d7c06285 OZ |
346 | /* For name/mask-only iface patterns */ |
347 | iface_patt_list_nopx: iface_patt_list { iface_patt_check(); } | |
348 | ||
79b4e12e OZ |
349 | iface_patt_init: { |
350 | /* Generic this_ipatt init */ | |
351 | this_ipatt = cfg_allocz(sizeof(struct iface_patt)); | |
352 | init_list(&this_ipatt->ipn_list); | |
353 | } | |
354 | ; | |
355 | ||
356 | iface_patt: | |
357 | iface_patt_init iface_patt_list | |
358 | ; | |
359 | ||
ef4a50be | 360 | tos: |
6aaaa635 OZ |
361 | CLASS expr { $$ = $2 & 0xfc; if ($2 > 255) cf_error("TX class must be in range 0-255"); } |
362 | | DSCP expr { $$ = ($2 & 0x3f) << 2; if ($2 > 63) cf_error("TX DSCP must be in range 0-63"); } | |
ef4a50be | 363 | ; |
20e94fb8 | 364 | |
7e5f5ffd | 365 | /* Direct device route protocol */ |
50d8424a | 366 | |
f851f0d7 | 367 | proto: dev_proto '}' ; |
50d8424a | 368 | |
7e5f5ffd | 369 | dev_proto_start: proto_start DIRECT { |
2bbc3083 | 370 | this_proto = proto_config_new(&proto_device, $1); |
a7f23f58 | 371 | init_list(&DIRECT_CFG->iface_list); |
50d8424a MM |
372 | } |
373 | ; | |
374 | ||
375 | dev_proto: | |
7e5f5ffd | 376 | dev_proto_start proto_name '{' |
50d8424a | 377 | | dev_proto proto_item ';' |
f4a60a9b | 378 | | dev_proto proto_channel ';' |
20e94fb8 | 379 | | dev_proto dev_iface_patt ';' |
e90dd656 | 380 | | dev_proto CHECK LINK bool ';' { DIRECT_CFG->check_link = $4; } |
50d8424a MM |
381 | ; |
382 | ||
20e94fb8 | 383 | dev_iface_init: |
8edf2361 | 384 | /* EMPTY */ { |
20e94fb8 | 385 | this_ipatt = cfg_allocz(sizeof(struct iface_patt)); |
a7f23f58 | 386 | add_tail(&DIRECT_CFG->iface_list, NODE this_ipatt); |
20e94fb8 | 387 | init_list(&this_ipatt->ipn_list); |
50d8424a | 388 | } |
50d8424a MM |
389 | ; |
390 | ||
20e94fb8 OZ |
391 | dev_iface_patt: |
392 | INTERFACE dev_iface_init iface_patt_list | |
8edf2361 MM |
393 | ; |
394 | ||
96d8e3bf MM |
395 | /* Debug flags */ |
396 | ||
397 | debug_mask: | |
398 | ALL { $$ = ~0; } | |
399 | | OFF { $$ = 0; } | |
400 | | '{' debug_list '}' { $$ = $2; } | |
401 | ; | |
402 | ||
403 | debug_list: | |
404 | debug_flag | |
405 | | debug_list ',' debug_flag { $$ = $1 | $3; } | |
406 | ; | |
407 | ||
408 | debug_flag: | |
409 | STATES { $$ = D_STATES; } | |
410 | | ROUTES { $$ = D_ROUTES; } | |
411 | | FILTERS { $$ = D_FILTERS; } | |
6a9f28b0 | 412 | | INTERFACES { $$ = D_IFACES; } |
96d8e3bf MM |
413 | | EVENTS { $$ = D_EVENTS; } |
414 | | PACKETS { $$ = D_PACKETS; } | |
415 | ; | |
416 | ||
cf31112f OZ |
417 | /* MRTDump flags */ |
418 | ||
419 | mrtdump_mask: | |
420 | ALL { $$ = ~0; } | |
421 | | OFF { $$ = 0; } | |
422 | | '{' mrtdump_list '}' { $$ = $2; } | |
423 | ; | |
424 | ||
425 | mrtdump_list: | |
426 | mrtdump_flag | |
427 | | mrtdump_list ',' mrtdump_flag { $$ = $1 | $3; } | |
428 | ; | |
429 | ||
430 | mrtdump_flag: | |
431 | STATES { $$ = MD_STATES; } | |
432 | | MESSAGES { $$ = MD_MESSAGES; } | |
433 | ; | |
434 | ||
8edf2361 MM |
435 | /* Password lists */ |
436 | ||
b21f68b4 OZ |
437 | password_list: |
438 | PASSWORDS '{' password_items '}' | |
439 | | password_item | |
440 | ; | |
441 | ||
9fcb9637 | 442 | password_items: |
5236fb03 OF |
443 | /* empty */ |
444 | | password_item ';' password_items | |
445 | ; | |
446 | ||
447 | password_item: | |
448 | password_item_begin '{' password_item_params '}' | |
449 | | password_item_begin | |
450 | ; | |
451 | ||
452 | password_item_begin: | |
9eceab33 | 453 | PASSWORD text { |
b21f68b4 | 454 | if (!this_p_list) { |
a82f692e OZ |
455 | this_p_list = cfg_alloc(sizeof(list)); |
456 | init_list(this_p_list); | |
457 | password_id = 1; | |
b21f68b4 | 458 | } |
5236fb03 OF |
459 | this_p_item = cfg_alloc(sizeof (struct password_item)); |
460 | this_p_item->password = $2; | |
56cb3bed | 461 | this_p_item->length = strlen($2); |
5236fb03 OF |
462 | this_p_item->genfrom = 0; |
463 | this_p_item->gento = TIME_INFINITY; | |
464 | this_p_item->accfrom = 0; | |
465 | this_p_item->accto = TIME_INFINITY; | |
b21f68b4 | 466 | this_p_item->id = password_id++; |
56cb3bed | 467 | this_p_item->alg = ALG_UNDEFINED; |
5236fb03 | 468 | add_tail(this_p_list, &this_p_item->n); |
1a2ded45 | 469 | } |
5236fb03 | 470 | ; |
1a2ded45 | 471 | |
5236fb03 | 472 | password_item_params: |
286e2011 | 473 | /* empty */ { } |
f047271c OZ |
474 | | GENERATE FROM time ';' password_item_params { this_p_item->genfrom = $3; } |
475 | | GENERATE TO time ';' password_item_params { this_p_item->gento = $3; } | |
476 | | ACCEPT FROM time ';' password_item_params { this_p_item->accfrom = $3; } | |
477 | | ACCEPT TO time ';' password_item_params { this_p_item->accto = $3; } | |
478 | | FROM time ';' password_item_params { this_p_item->genfrom = this_p_item->accfrom = $2; } | |
479 | | TO time ';' password_item_params { this_p_item->gento = this_p_item->accto = $2; } | |
bc956fca | 480 | | ID expr ';' password_item_params { this_p_item->id = $2; if ($2 <= 0) cf_error("Password ID has to be greated than zero."); } |
56cb3bed | 481 | | ALGORITHM password_algorithm ';' password_item_params { this_p_item->alg = $2; } |
1a2ded45 PM |
482 | ; |
483 | ||
56cb3bed PT |
484 | password_algorithm: |
485 | KEYED MD5 { $$ = ALG_MD5; } | |
486 | | KEYED SHA1 { $$ = ALG_SHA1; } | |
487 | | KEYED SHA256 { $$ = ALG_SHA256; } | |
488 | | KEYED SHA384 { $$ = ALG_SHA384; } | |
489 | | KEYED SHA512 { $$ = ALG_SHA512; } | |
490 | | HMAC MD5 { $$ = ALG_HMAC_MD5; } | |
491 | | HMAC SHA1 { $$ = ALG_HMAC_SHA1; } | |
492 | | HMAC SHA256 { $$ = ALG_HMAC_SHA256; } | |
493 | | HMAC SHA384 { $$ = ALG_HMAC_SHA384; } | |
494 | | HMAC SHA512 { $$ = ALG_HMAC_SHA512; } | |
495 | ; | |
87d7fd97 | 496 | |
bc2fb680 | 497 | /* Core commands */ |
fae0396e | 498 | CF_CLI_HELP(SHOW, ..., [[Show status information]]) |
ae97b946 | 499 | |
4b87e256 | 500 | CF_CLI(SHOW STATUS,,, [[Show router status]]) |
de10a974 | 501 | { cmd_show_status(); } ; |
ae97b946 | 502 | |
acb60628 OZ |
503 | CF_CLI(SHOW MEMORY,,, [[Show memory usage]]) |
504 | { cmd_show_memory(); } ; | |
505 | ||
e304fd4b | 506 | CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocols]]) |
e0a45fb4 | 507 | { proto_apply_cmd($3, proto_cmd_show, 0, 0); } ; |
0d3e6bce | 508 | |
e304fd4b | 509 | CF_CLI(SHOW PROTOCOLS ALL, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocol details]]) |
e0a45fb4 | 510 | { proto_apply_cmd($4, proto_cmd_show, 0, 1); } ; |
ae97b946 | 511 | |
c0e958e0 | 512 | optproto: |
9eef9c64 | 513 | CF_SYM_KNOWN { cf_assert_symbol($1, SYM_PROTO); $$ = $1; } |
730f2e2c MM |
514 | | /* empty */ { $$ = NULL; } |
515 | ; | |
516 | ||
ae97b946 MM |
517 | CF_CLI(SHOW INTERFACES,,, [[Show network interfaces]]) |
518 | { if_show(); } ; | |
519 | ||
520 | CF_CLI(SHOW INTERFACES SUMMARY,,, [[Show summary of network interfaces]]) | |
521 | { if_show_summary(); } ; | |
522 | ||
c47d037e | 523 | CF_CLI_HELP(SHOW ROUTE, ..., [[Show routing table]]) |
7aa80901 | 524 | CF_CLI(SHOW ROUTE, r_args, [[[<prefix>|for <prefix>|for <ip>] [table <t>] [filter <f>|where <cond>] [all] [primary] [filtered] [(export|preexport|noexport) <p>] [protocol <p>] [stats|count]]], [[Show routing table]]) |
730f2e2c MM |
525 | { rt_show($3); } ; |
526 | ||
527 | r_args: | |
528 | /* empty */ { | |
529 | $$ = cfg_allocz(sizeof(struct rt_show_data)); | |
b2949999 | 530 | init_list(&($$->tables)); |
730f2e2c | 531 | $$->filter = FILTER_ACCEPT; |
265419a3 | 532 | $$->running_on_config = new_config->fallback; |
730f2e2c | 533 | } |
d7661fbe | 534 | | r_args net_any { |
730f2e2c | 535 | $$ = $1; |
04632fd7 OZ |
536 | if ($$->addr) cf_error("Only one prefix expected"); |
537 | $$->addr = $2; | |
730f2e2c | 538 | } |
3484cb9a | 539 | | r_args FOR r_args_for { |
9449c91a | 540 | $$ = $1; |
04632fd7 | 541 | if ($$->addr) cf_error("Only one prefix expected"); |
9449c91a | 542 | $$->show_for = 1; |
3484cb9a | 543 | $$->addr = $3; |
9449c91a | 544 | } |
9eef9c64 MM |
545 | | r_args TABLE CF_SYM_KNOWN { |
546 | cf_assert_symbol($3, SYM_TABLE); | |
730f2e2c | 547 | $$ = $1; |
0b39b1cb | 548 | rt_show_add_table($$, $3->table->table); |
2faf519c MM |
549 | $$->tables_defined_by = RSD_TDB_DIRECT; |
550 | } | |
551 | | r_args TABLE ALL { | |
552 | struct rtable_config *t; | |
553 | $$ = $1; | |
554 | WALK_LIST(t, config->tables) | |
555 | rt_show_add_table($$, t->table); | |
556 | $$->tables_defined_by = RSD_TDB_ALL; | |
730f2e2c | 557 | } |
9eef9c64 MM |
558 | | r_args IMPORT TABLE CF_SYM_KNOWN '.' r_args_channel { |
559 | cf_assert_symbol($4, SYM_PROTO); | |
682d3f7d | 560 | $$ = $1; |
0b39b1cb | 561 | struct proto_config *cf = $4->proto; |
c0e958e0 | 562 | if (!cf->proto) cf_error("%s is not a protocol", $4->name); |
682d3f7d OZ |
563 | struct channel *c = proto_find_channel_by_name(cf->proto, $6); |
564 | if (!c) cf_error("Channel %s.%s not found", $4->name, $6); | |
565 | if (!c->in_table) cf_error("No import table in channel %s.%s", $4->name, $6); | |
566 | rt_show_add_table($$, c->in_table); | |
567 | $$->tables_defined_by = RSD_TDB_DIRECT; | |
568 | } | |
730f2e2c MM |
569 | | r_args FILTER filter { |
570 | $$ = $1; | |
430da60f | 571 | if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice"); |
730f2e2c MM |
572 | $$->filter = $3; |
573 | } | |
430da60f MM |
574 | | r_args where_filter { |
575 | $$ = $1; | |
576 | if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice"); | |
577 | $$->filter = $2; | |
578 | } | |
730f2e2c MM |
579 | | r_args ALL { |
580 | $$ = $1; | |
581 | $$->verbose = 1; | |
582 | } | |
ce1da96e MM |
583 | | r_args PRIMARY { |
584 | $$ = $1; | |
585 | $$->primary_only = 1; | |
586 | } | |
15550957 | 587 | | r_args FILTERED { |
cf98be7b | 588 | $$ = $1; |
15550957 | 589 | $$->filtered = 1; |
cf98be7b | 590 | } |
9eef9c64 MM |
591 | | r_args export_mode CF_SYM_KNOWN { |
592 | cf_assert_symbol($3, SYM_PROTO); | |
0b39b1cb | 593 | struct proto_config *c = (struct proto_config *) $3->proto; |
ce1da96e | 594 | $$ = $1; |
b2949999 | 595 | if ($$->export_mode) cf_error("Export specified twice"); |
c0e958e0 | 596 | if (!c->proto) cf_error("%s is not a protocol", $3->name); |
ea2ae6dd | 597 | $$->export_mode = $2; |
ea2ae6dd | 598 | $$->export_protocol = c->proto; |
2faf519c | 599 | $$->tables_defined_by = RSD_TDB_INDIRECT; |
ce1da96e | 600 | } |
9eef9c64 MM |
601 | | r_args export_mode CF_SYM_KNOWN '.' r_args_channel { |
602 | cf_assert_symbol($3, SYM_PROTO); | |
0b39b1cb | 603 | struct proto_config *c = (struct proto_config *) $3->proto; |
b2949999 OZ |
604 | $$ = $1; |
605 | if ($$->export_mode) cf_error("Export specified twice"); | |
c0e958e0 | 606 | if (!c->proto) cf_error("%s is not a protocol", $3->name); |
b2949999 OZ |
607 | $$->export_mode = $2; |
608 | $$->export_channel = proto_find_channel_by_name(c->proto, $5); | |
609 | if (!$$->export_channel) cf_error("Export channel not found"); | |
b2949999 OZ |
610 | $$->tables_defined_by = RSD_TDB_INDIRECT; |
611 | } | |
9eef9c64 MM |
612 | | r_args PROTOCOL CF_SYM_KNOWN { |
613 | cf_assert_symbol($3, SYM_PROTO); | |
0b39b1cb | 614 | struct proto_config *c = (struct proto_config *) $3->proto; |
4d176e14 OF |
615 | $$ = $1; |
616 | if ($$->show_protocol) cf_error("Protocol specified twice"); | |
c0e958e0 | 617 | if (!c->proto) cf_error("%s is not a protocol", $3->name); |
4d176e14 | 618 | $$->show_protocol = c->proto; |
2faf519c | 619 | $$->tables_defined_by = RSD_TDB_INDIRECT; |
ce1da96e | 620 | } |
23693958 MM |
621 | | r_args STATS { |
622 | $$ = $1; | |
623 | $$->stats = 1; | |
624 | } | |
33a368ad MM |
625 | | r_args COUNT { |
626 | $$ = $1; | |
627 | $$->stats = 2; | |
628 | } | |
ce1da96e MM |
629 | ; |
630 | ||
3484cb9a MM |
631 | r_args_for: |
632 | r_args_for_val { | |
633 | $$ = cfg_alloc($1.length); | |
634 | net_copy($$, &$1); | |
635 | } | |
636 | | net_vpn4_ | |
637 | | net_vpn6_ | |
be17805c | 638 | | net_ip6_sadr_ |
3484cb9a MM |
639 | | VPN_RD IP4 { |
640 | $$ = cfg_alloc(sizeof(net_addr_vpn4)); | |
641 | net_fill_vpn4($$, $2, IP4_MAX_PREFIX_LENGTH, $1); | |
642 | } | |
643 | | VPN_RD IP6 { | |
644 | $$ = cfg_alloc(sizeof(net_addr_vpn6)); | |
645 | net_fill_vpn6($$, $2, IP6_MAX_PREFIX_LENGTH, $1); | |
646 | } | |
be17805c OZ |
647 | | IP6 FROM IP6 { |
648 | $$ = cfg_alloc(sizeof(net_addr_ip6_sadr)); | |
649 | net_fill_ip6_sadr($$, $1, IP6_MAX_PREFIX_LENGTH, $3, IP6_MAX_PREFIX_LENGTH); | |
650 | } | |
9eef9c64 | 651 | | CF_SYM_KNOWN { |
3484cb9a MM |
652 | if ($1->class == (SYM_CONSTANT | T_IP)) |
653 | { | |
654 | $$ = cfg_alloc(ipa_is_ip4(SYM_VAL($1).ip) ? sizeof(net_addr_ip4) : sizeof(net_addr_ip6)); | |
655 | net_fill_ip_host($$, SYM_VAL($1).ip); | |
656 | } | |
657 | else if (($1->class == (SYM_CONSTANT | T_NET)) && net_type_match(SYM_VAL($1).net, NB_IP | NB_VPN)) | |
1d213067 | 658 | $$ = (net_addr *) SYM_VAL($1).net; /* Avoid const warning */ |
3484cb9a | 659 | else |
9eef9c64 | 660 | cf_error("IP address or network constant expected"); |
3484cb9a MM |
661 | } |
662 | ; | |
663 | ||
664 | r_args_for_val: | |
665 | net_ip4_ | |
666 | | net_ip6_ | |
667 | | IP4 { net_fill_ip4(&($$), $1, IP4_MAX_PREFIX_LENGTH); } | |
668 | | IP6 { net_fill_ip6(&($$), $1, IP6_MAX_PREFIX_LENGTH); } | |
669 | ||
7aa80901 OZ |
670 | export_mode: |
671 | PREEXPORT { $$ = RSEM_PREEXPORT; } | |
672 | | EXPORT { $$ = RSEM_EXPORT; } | |
673 | | NOEXPORT { $$ = RSEM_NOEXPORT; } | |
730f2e2c MM |
674 | ; |
675 | ||
b2949999 OZ |
676 | /* This is ugly hack */ |
677 | r_args_channel: | |
678 | IPV4 { $$ = "ipv4"; } | |
679 | | IPV4_MC { $$ = "ipv4-mc"; } | |
680 | | IPV4_MPLS { $$ = "ipv4-mpls"; } | |
681 | | IPV6 { $$ = "ipv6"; } | |
682 | | IPV6_MC { $$ = "ipv6-mc"; } | |
683 | | IPV6_MPLS { $$ = "ipv6-mpls"; } | |
be17805c | 684 | | IPV6_SADR { $$ = "ipv6-sadr"; } |
b2949999 OZ |
685 | | VPN4 { $$ = "vpn4"; } |
686 | | VPN4_MC { $$ = "vpn4-mc"; } | |
687 | | VPN4_MPLS { $$ = "vpn4-mpls"; } | |
688 | | VPN6 { $$ = "vpn6"; } | |
689 | | VPN6_MC { $$ = "vpn6-mc"; } | |
690 | | VPN6_MPLS { $$ = "vpn6-mpls"; } | |
691 | | ROA4 { $$ = "roa4"; } | |
692 | | ROA6 { $$ = "roa6"; } | |
693 | | FLOW4 { $$ = "flow4"; } | |
694 | | FLOW6 { $$ = "flow6"; } | |
695 | | MPLS { $$ = "mpls"; } | |
696 | | PRI { $$ = "pri"; } | |
697 | | SEC { $$ = "sec"; } | |
698 | ; | |
af582c48 | 699 | |
c47d037e | 700 | CF_CLI_HELP(SHOW SYMBOLS, ..., [[Show all known symbolic names]]) |
d7661fbe | 701 | CF_CLI(SHOW SYMBOLS, sym_args, [table|filter|function|protocol|template|<symbol>], [[Show all known symbolic names]]) |
4b87e256 MM |
702 | { cmd_show_symbols($3); } ; |
703 | ||
0f808c06 OZ |
704 | sym_args: |
705 | /* empty */ { | |
706 | $$ = cfg_allocz(sizeof(struct sym_show_data)); | |
707 | } | |
708 | | sym_args TABLE { $$ = $1; $$->type = SYM_TABLE; } | |
709 | | sym_args FUNCTION { $$ = $1; $$->type = SYM_FUNCTION; } | |
710 | | sym_args FILTER { $$ = $1; $$->type = SYM_FILTER; } | |
711 | | sym_args PROTOCOL { $$ = $1; $$->type = SYM_PROTO; } | |
712 | | sym_args TEMPLATE { $$ = $1; $$->type = SYM_TEMPLATE; } | |
c0e958e0 | 713 | | sym_args symbol { $$ = $1; $$->sym = $2; } |
0f808c06 OZ |
714 | ; |
715 | ||
af582c48 | 716 | |
96d8e3bf MM |
717 | CF_CLI_HELP(DUMP, ..., [[Dump debugging information]]) |
718 | CF_CLI(DUMP RESOURCES,,, [[Dump all allocated resource]]) | |
34350a52 | 719 | { rdump(&root_pool); cli_msg(0, ""); } ; |
96d8e3bf | 720 | CF_CLI(DUMP SOCKETS,,, [[Dump open sockets]]) |
34350a52 | 721 | { sk_dump_all(); cli_msg(0, ""); } ; |
8bcb5fb1 OZ |
722 | CF_CLI(DUMP EVENTS,,, [[Dump event log]]) |
723 | { io_log_dump(); cli_msg(0, ""); } ; | |
96d8e3bf | 724 | CF_CLI(DUMP INTERFACES,,, [[Dump interface information]]) |
34350a52 | 725 | { if_dump_all(); cli_msg(0, ""); } ; |
96d8e3bf | 726 | CF_CLI(DUMP NEIGHBORS,,, [[Dump neighbor cache]]) |
34350a52 | 727 | { neigh_dump_all(); cli_msg(0, ""); } ; |
96d8e3bf | 728 | CF_CLI(DUMP ATTRIBUTES,,, [[Dump attribute cache]]) |
34350a52 | 729 | { rta_dump_all(); cli_msg(0, ""); } ; |
96d8e3bf | 730 | CF_CLI(DUMP ROUTES,,, [[Dump routing table]]) |
34350a52 | 731 | { rt_dump_all(); cli_msg(0, ""); } ; |
96d8e3bf | 732 | CF_CLI(DUMP PROTOCOLS,,, [[Dump protocol information]]) |
34350a52 MM |
733 | { protos_dump_all(); cli_msg(0, ""); } ; |
734 | ||
508d9360 | 735 | CF_CLI(EVAL, term, <expr>, [[Evaluate an expression]]) |
23e3b1e6 | 736 | { cmd_eval(f_linearize($2)); } ; |
508d9360 OZ |
737 | |
738 | CF_CLI_HELP(ECHO, ..., [[Control echoing of log messages]]) | |
9df52a98 | 739 | CF_CLI(ECHO, echo_mask echo_size, (all | off | { debug|trace|info|remote|warning|error|auth [, ...] }) [<buffer-size>], [[Control echoing of log messages]]) { |
34350a52 MM |
740 | cli_set_log_echo(this_cli, $2, $3); |
741 | cli_msg(0, ""); | |
742 | } ; | |
743 | ||
744 | echo_mask: | |
745 | ALL { $$ = ~0; } | |
746 | | OFF { $$ = 0; } | |
508d9360 | 747 | | '{' log_mask_list '}' { $$ = $2; } |
34350a52 MM |
748 | ; |
749 | ||
750 | echo_size: | |
751 | /* empty */ { $$ = 4096; } | |
752 | | NUM { | |
753 | if ($1 < 256 || $1 > 65536) cf_error("Invalid log buffer size"); | |
754 | $$ = $1; | |
755 | } | |
756 | ; | |
bc2fb680 | 757 | |
830ba75e | 758 | CF_CLI(DISABLE, proto_patt opttext, (<protocol> | \"<pattern>\" | all) [message], [[Disable protocol]]) |
cd1d9961 | 759 | { proto_apply_cmd($2, proto_cmd_disable, 1, (uintptr_t) $3); } ; |
830ba75e | 760 | CF_CLI(ENABLE, proto_patt opttext, (<protocol> | \"<pattern>\" | all) [message], [[Enable protocol]]) |
cd1d9961 | 761 | { proto_apply_cmd($2, proto_cmd_enable, 1, (uintptr_t) $3); } ; |
830ba75e | 762 | CF_CLI(RESTART, proto_patt opttext, (<protocol> | \"<pattern>\" | all) [message], [[Restart protocol]]) |
cd1d9961 | 763 | { proto_apply_cmd($2, proto_cmd_restart, 1, (uintptr_t) $3); } ; |
bf47fe4b | 764 | CF_CLI(RELOAD, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol]]) |
e0a45fb4 | 765 | { proto_apply_cmd($2, proto_cmd_reload, 1, CMD_RELOAD); } ; |
8a7fb885 | 766 | CF_CLI(RELOAD IN, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just imported routes)]]) |
e0a45fb4 | 767 | { proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_IN); } ; |
8a7fb885 | 768 | CF_CLI(RELOAD OUT, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just exported routes)]]) |
e0a45fb4 | 769 | { proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_OUT); } ; |
f14a4bec | 770 | |
cf31112f | 771 | CF_CLI_HELP(DEBUG, ..., [[Control protocol debugging via BIRD logs]]) |
9df52a98 | 772 | CF_CLI(DEBUG, proto_patt debug_mask, (<protocol> | \"<pattern>\" | all) (all | off | { states|routes|filters|interfaces|events|packets [, ...] }), [[Control protocol debugging via BIRD logs]]) |
e0a45fb4 | 773 | { proto_apply_cmd($2, proto_cmd_debug, 1, $3); } ; |
cf31112f OZ |
774 | |
775 | CF_CLI_HELP(MRTDUMP, ..., [[Control protocol debugging via MRTdump files]]) | |
9df52a98 | 776 | CF_CLI(MRTDUMP, proto_patt mrtdump_mask, (<protocol> | \"<pattern>\" | all) (all | off | { states|messages [, ...] }), [[Control protocol debugging via MRTdump format]]) |
e0a45fb4 OZ |
777 | { proto_apply_cmd($2, proto_cmd_mrtdump, 1, $3); } ; |
778 | ||
779 | CF_CLI(RESTRICT,,,[[Restrict current CLI session to safe commands]]) | |
780 | { this_cli->restricted = 1; cli_msg(16, "Access restricted"); } ; | |
96d8e3bf | 781 | |
f14a4bec | 782 | proto_patt: |
9eef9c64 | 783 | CF_SYM_KNOWN { cf_assert_symbol($1, SYM_PROTO); $$.ptr = $1; $$.patt = 0; } |
e304fd4b OZ |
784 | | ALL { $$.ptr = NULL; $$.patt = 1; } |
785 | | TEXT { $$.ptr = $1; $$.patt = 1; } | |
f14a4bec MM |
786 | ; |
787 | ||
e304fd4b | 788 | proto_patt2: |
9eef9c64 | 789 | CF_SYM_KNOWN { cf_assert_symbol($1, SYM_PROTO); $$.ptr = $1; $$.patt = 0; } |
e304fd4b OZ |
790 | | { $$.ptr = NULL; $$.patt = 1; } |
791 | | TEXT { $$.ptr = $1; $$.patt = 1; } | |
792 | ; | |
793 | ||
4c553c5a | 794 | dynamic_attr: IGP_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT, 0, T_INT, EA_GEN_IGP_METRIC); } ; |
ba5e5940 | 795 | |
e304fd4b | 796 | |
da877822 MM |
797 | CF_CODE |
798 | ||
799 | CF_END |