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