]>
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 | ||
1ae42e52 | 20 | static struct rtable_config *this_table; |
2edb31b0 | 21 | static struct proto_config *this_proto; |
f4a60a9b | 22 | static struct channel_config *this_channel; |
2edb31b0 | 23 | static struct iface_patt *this_ipatt; |
20e94fb8 | 24 | static struct iface_patt_node *this_ipn; |
9656dce7 | 25 | /* static struct roa_table_config *this_roa_table; */ |
5236fb03 OF |
26 | static list *this_p_list; |
27 | static struct password_item *this_p_item; | |
b21f68b4 | 28 | static int password_id; |
9d3fc306 | 29 | static struct bfd_options *this_bfd_opts; |
b21f68b4 | 30 | |
d7c06285 OZ |
31 | static void |
32 | iface_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 | 41 | static inline void |
8eea396b | 42 | init_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 | ||
51 | static inline void | |
52 | init_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 |
66 | static inline void |
67 | reset_passwords(void) | |
68 | { | |
a7f23f58 | 69 | this_p_list = NULL; |
024c310b OZ |
70 | } |
71 | ||
72 | static inline list * | |
b21f68b4 OZ |
73 | get_passwords(void) |
74 | { | |
75 | list *rv = this_p_list; | |
76 | this_p_list = NULL; | |
77 | return rv; | |
78 | } | |
79 | ||
3b56bf88 OZ |
80 | static inline void |
81 | init_bfd_opts(struct bfd_options **opts) | |
82 | { | |
83 | cf_check_bfd(1); | |
84 | ||
85 | if (! *opts) | |
86 | *opts = bfd_new_options(); | |
87 | } | |
88 | ||
89 | static inline void | |
90 | open_bfd_opts(struct bfd_options **opts) | |
91 | { | |
92 | init_bfd_opts(opts); | |
93 | this_bfd_opts = *opts; | |
94 | } | |
95 | ||
96 | static inline void | |
97 | close_bfd_opts(void) | |
98 | { | |
99 | this_bfd_opts = NULL; | |
100 | } | |
101 | ||
f4a60a9b OZ |
102 | static void |
103 | proto_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 |
113 | CF_DECLS |
114 | ||
71423871 | 115 | CF_KEYWORDS(ROUTER, ID, HOSTNAME, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT) |
18f70a62 | 116 | CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, VRF, DEFAULT, TABLE, STATES, ROUTES, FILTERS) |
be17805c | 117 | CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, SADR, MPLS) |
0a3db4c6 | 118 | CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED, RPKI) |
596f2e32 | 119 | CF_KEYWORDS(PASSWORD, KEY, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, CHANNELS, INTERFACES) |
725d9af9 | 120 | CF_KEYWORDS(ALGORITHM, KEYED, HMAC, MD5, SHA1, SHA256, SHA384, SHA512, BLAKE2S128, BLAKE2S256, BLAKE2B256, BLAKE2B512) |
ea97b890 | 121 | CF_KEYWORDS(PRIMARY, STATS, COUNT, BY, FOR, IN, COMMANDS, PREEXPORT, NOEXPORT, EXPORTED, GENERATE) |
1ae42e52 | 122 | CF_KEYWORDS(BGP, PASSWORDS, DESCRIPTION) |
ef4a50be | 123 | CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP) |
f047271c | 124 | CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, ROUTE, PROTOCOL, BASE, LOG, S, MS, US) |
7aa80901 | 125 | CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS) |
9d3fc306 | 126 | CF_KEYWORDS(MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE) |
f9eb9b4c | 127 | CF_KEYWORDS(CHECK, LINK) |
a8a3d95b | 128 | CF_KEYWORDS(SORTED, TRIE, MIN, MAX, SETTLE, TIME, GC, THRESHOLD, PERIOD) |
da877822 | 129 | |
b2949999 | 130 | /* For r_args_channel */ |
be17805c | 131 | 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 | 132 | |
3660f19d | 133 | CF_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 | 135 | CF_ENUM(T_ENUM_SCOPE, SCOPE_, HOST, LINK, SITE, ORGANIZATION, UNIVERSE, UNDEFINED) |
4e276a89 | 136 | CF_ENUM(T_ENUM_RTD, RTD_, UNICAST, BLACKHOLE, UNREACHABLE, PROHIBIT) |
cb1bd816 | 137 | CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID) |
0edf0c8c | 138 | CF_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 | |
155 | CF_GRAMMAR | |
156 | ||
c74c0e3c MM |
157 | /* Setting of router ID */ |
158 | ||
f851f0d7 | 159 | conf: rtrid ; |
0e02abfd | 160 | |
04632fd7 | 161 | rtrid: |
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 | ||
166 | idval: | |
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 |
180 | conf: hostname_override ; |
181 | ||
182 | hostname_override: HOSTNAME text ';' { new_config->hostname = $2; } ; | |
183 | ||
f851f0d7 | 184 | conf: gr_opts ; |
0c791f87 OZ |
185 | |
186 | gr_opts: GRACEFUL RESTART WAIT expr ';' { new_config->gr_wait = $4; } ; | |
187 | ||
188 | ||
f4a60a9b | 189 | /* Network types (for tables, channels) */ |
0e02abfd | 190 | |
f4a60a9b OZ |
191 | net_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 | 204 | CF_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 | 209 | conf: table ; |
f4a60a9b | 210 | |
1ae42e52 OZ |
211 | table: table_start table_sorted table_opt_list ; |
212 | ||
213 | table_start: net_type TABLE symbol { | |
214 | this_table = rt_new_table($3, $1); | |
215 | } | |
216 | ; | |
217 | ||
fe9f1a6d | 218 | table_sorted: |
1ae42e52 OZ |
219 | /* empty */ |
220 | | SORTED { this_table->sorted = 1; } | |
26822d8f OZ |
221 | ; |
222 | ||
1ae42e52 OZ |
223 | table_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 | ||
236 | table_opts: | |
237 | /* empty */ | |
238 | | table_opts table_opt ';' | |
239 | ; | |
240 | ||
241 | table_opt_list: | |
242 | /* empty */ | |
243 | | '{' table_opts '}' | |
0e02abfd MM |
244 | ; |
245 | ||
f4a60a9b | 246 | |
c74c0e3c MM |
247 | /* Definition of protocols */ |
248 | ||
f851f0d7 | 249 | conf: proto { proto_postconfig(); } ; |
c74c0e3c | 250 | |
a7f23f58 OZ |
251 | proto_start: |
252 | PROTOCOL { $$ = SYM_PROTO; } | |
253 | | TEMPLATE { $$ = SYM_TEMPLATE; } | |
de10a974 | 254 | ; |
c74c0e3c MM |
255 | |
256 | proto_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 | ||
287 | proto_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 | |
299 | channel_start: net_type | |
300 | { | |
72163bd5 | 301 | $$ = this_channel = channel_config_get(NULL, net_label[$1], $1, this_proto); |
f4a60a9b OZ |
302 | }; |
303 | ||
61dae32b | 304 | channel_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 */ |
321 | channel_item: | |
322 | channel_item_ | |
323 | | DEBUG debug_mask { this_channel->debug = $2; } | |
324 | ; | |
325 | ||
f4a60a9b OZ |
326 | channel_opts: |
327 | /* empty */ | |
328 | | channel_opts channel_item ';' | |
329 | ; | |
330 | ||
331 | channel_opt_list: | |
332 | /* empty */ | |
333 | | '{' channel_opts '}' | |
334 | ; | |
335 | ||
336 | channel_end: | |
337 | { | |
338 | if (!this_channel->table) | |
339 | cf_error("Routing table not specified"); | |
340 | ||
341 | this_channel = NULL; | |
342 | }; | |
343 | ||
344 | proto_channel: channel_start channel_opt_list channel_end; | |
345 | ||
346 | ||
9eef9c64 | 347 | rtable: CF_SYM_KNOWN { cf_assert_symbol($1, SYM_TABLE); $$ = $1->table; } ; |
f4a60a9b | 348 | |
5056c559 MM |
349 | imexport: |
350 | FILTER filter { $$ = $2; } | |
f8809249 | 351 | | where_filter |
5056c559 MM |
352 | | ALL { $$ = FILTER_ACCEPT; } |
353 | | NONE { $$ = FILTER_REJECT; } | |
c74c0e3c MM |
354 | ; |
355 | ||
ebecb6f6 | 356 | limit_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 | ||
364 | limit_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 | 370 | conf: debug_default ; |
f30b86f9 MM |
371 | |
372 | debug_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 | 380 | conf: timeformat_base ; |
f047271c OZ |
381 | |
382 | timeformat_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 | ||
389 | timeformat_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 | ||
400 | timeformat_base: | |
401 | TIMEFORMAT timeformat_spec ';' | |
402 | ; | |
403 | ||
404 | ||
8edf2361 MM |
405 | /* Interface patterns */ |
406 | ||
20e94fb8 OZ |
407 | iface_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 | ||
415 | iface_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 | ||
420 | iface_negate: | |
421 | { this_ipn->positive = 1; } | |
422 | | '-' { this_ipn->positive = 0; } | |
423 | ; | |
424 | ||
425 | iface_patt_node: | |
04632fd7 | 426 | iface_patt_node_init iface_negate iface_patt_node_body |
20e94fb8 OZ |
427 | ; |
428 | ||
429 | ||
430 | iface_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 */ |
436 | iface_patt_list_nopx: iface_patt_list { iface_patt_check(); } | |
437 | ||
79b4e12e OZ |
438 | iface_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 | ||
445 | iface_patt: | |
446 | iface_patt_init iface_patt_list | |
447 | ; | |
448 | ||
ef4a50be | 449 | tos: |
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 | 456 | proto: dev_proto '}' ; |
50d8424a | 457 | |
7e5f5ffd | 458 | dev_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 | ||
464 | dev_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 | 472 | dev_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 |
480 | dev_iface_patt: |
481 | INTERFACE dev_iface_init iface_patt_list | |
8edf2361 MM |
482 | ; |
483 | ||
96d8e3bf MM |
484 | /* Debug flags */ |
485 | ||
486 | debug_mask: | |
487 | ALL { $$ = ~0; } | |
488 | | OFF { $$ = 0; } | |
489 | | '{' debug_list '}' { $$ = $2; } | |
490 | ; | |
491 | ||
492 | debug_list: | |
493 | debug_flag | |
494 | | debug_list ',' debug_flag { $$ = $1 | $3; } | |
495 | ; | |
496 | ||
497 | debug_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 | ||
508 | mrtdump_mask: | |
509 | ALL { $$ = ~0; } | |
510 | | OFF { $$ = 0; } | |
511 | | '{' mrtdump_list '}' { $$ = $2; } | |
512 | ; | |
513 | ||
514 | mrtdump_list: | |
515 | mrtdump_flag | |
516 | | mrtdump_list ',' mrtdump_flag { $$ = $1 | $3; } | |
517 | ; | |
518 | ||
519 | mrtdump_flag: | |
520 | STATES { $$ = MD_STATES; } | |
521 | | MESSAGES { $$ = MD_MESSAGES; } | |
522 | ; | |
523 | ||
8edf2361 MM |
524 | /* Password lists */ |
525 | ||
b21f68b4 | 526 | password_list: |
8eea396b OZ |
527 | password_list_body |
528 | ; | |
529 | ||
530 | password_list_body: | |
b21f68b4 OZ |
531 | PASSWORDS '{' password_items '}' |
532 | | password_item | |
533 | ; | |
534 | ||
9fcb9637 | 535 | password_items: |
5236fb03 OF |
536 | /* empty */ |
537 | | password_item ';' password_items | |
538 | ; | |
539 | ||
540 | password_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 |
545 | pass_key: PASSWORD | KEY; |
546 | ||
5236fb03 | 547 | password_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 | 552 | password_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 |
564 | password_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 |
581 | password_item_end: |
582 | { | |
583 | password_validate_length(this_p_item); | |
584 | }; | |
585 | ||
9d3fc306 OZ |
586 | |
587 | /* BFD options */ | |
588 | ||
589 | bfd_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 | ||
599 | bfd_items: | |
600 | /* empty */ | |
601 | | bfd_items bfd_item ';' | |
602 | ; | |
603 | ||
604 | bfd_opts: | |
3b56bf88 | 605 | '{' bfd_items '}' |
9d3fc306 OZ |
606 | ; |
607 | ||
bc2fb680 | 608 | /* Core commands */ |
fae0396e | 609 | CF_CLI_HELP(SHOW, ..., [[Show status information]]) |
ae97b946 | 610 | |
4b87e256 | 611 | CF_CLI(SHOW STATUS,,, [[Show router status]]) |
de10a974 | 612 | { cmd_show_status(); } ; |
ae97b946 | 613 | |
acb60628 OZ |
614 | CF_CLI(SHOW MEMORY,,, [[Show memory usage]]) |
615 | { cmd_show_memory(); } ; | |
616 | ||
e304fd4b | 617 | CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocols]]) |
e0a45fb4 | 618 | { proto_apply_cmd($3, proto_cmd_show, 0, 0); } ; |
0d3e6bce | 619 | |
e304fd4b | 620 | CF_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 | 623 | optproto: |
9eef9c64 | 624 | CF_SYM_KNOWN { cf_assert_symbol($1, SYM_PROTO); $$ = $1; } |
730f2e2c MM |
625 | | /* empty */ { $$ = NULL; } |
626 | ; | |
627 | ||
ae97b946 MM |
628 | CF_CLI(SHOW INTERFACES,,, [[Show network interfaces]]) |
629 | { if_show(); } ; | |
630 | ||
631 | CF_CLI(SHOW INTERFACES SUMMARY,,, [[Show summary of network interfaces]]) | |
632 | { if_show_summary(); } ; | |
633 | ||
c47d037e | 634 | CF_CLI_HELP(SHOW ROUTE, ..., [[Show routing table]]) |
231c6385 | 635 | CF_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 | ||
638 | r_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 |
745 | r_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 | ||
778 | r_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 |
784 | export_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 | 792 | channel_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 |
815 | channel_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 | 825 | CF_CLI_HELP(SHOW SYMBOLS, ..., [[Show all known symbolic names]]) |
d7661fbe | 826 | CF_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 |
829 | sym_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 |
842 | CF_CLI_HELP(DUMP, ..., [[Dump debugging information]]) |
843 | CF_CLI(DUMP RESOURCES,,, [[Dump all allocated resource]]) | |
34350a52 | 844 | { rdump(&root_pool); cli_msg(0, ""); } ; |
96d8e3bf | 845 | CF_CLI(DUMP SOCKETS,,, [[Dump open sockets]]) |
34350a52 | 846 | { sk_dump_all(); cli_msg(0, ""); } ; |
8bcb5fb1 OZ |
847 | CF_CLI(DUMP EVENTS,,, [[Dump event log]]) |
848 | { io_log_dump(); cli_msg(0, ""); } ; | |
96d8e3bf | 849 | CF_CLI(DUMP INTERFACES,,, [[Dump interface information]]) |
34350a52 | 850 | { if_dump_all(); cli_msg(0, ""); } ; |
96d8e3bf | 851 | CF_CLI(DUMP NEIGHBORS,,, [[Dump neighbor cache]]) |
34350a52 | 852 | { neigh_dump_all(); cli_msg(0, ""); } ; |
96d8e3bf | 853 | CF_CLI(DUMP ATTRIBUTES,,, [[Dump attribute cache]]) |
34350a52 | 854 | { rta_dump_all(); cli_msg(0, ""); } ; |
96d8e3bf | 855 | CF_CLI(DUMP ROUTES,,, [[Dump routing table]]) |
34350a52 | 856 | { rt_dump_all(); cli_msg(0, ""); } ; |
96d8e3bf | 857 | CF_CLI(DUMP PROTOCOLS,,, [[Dump protocol information]]) |
34350a52 | 858 | { protos_dump_all(); cli_msg(0, ""); } ; |
84ac62d3 MM |
859 | CF_CLI(DUMP FILTER ALL,,, [[Dump all filters in linearized form]]) |
860 | { filters_dump_all(); cli_msg(0, ""); } ; | |
34350a52 | 861 | |
508d9360 | 862 | CF_CLI(EVAL, term, <expr>, [[Evaluate an expression]]) |
a2527ee5 | 863 | { cmd_eval(f_linearize($2, 1)); } ; |
508d9360 OZ |
864 | |
865 | CF_CLI_HELP(ECHO, ..., [[Control echoing of log messages]]) | |
9df52a98 | 866 | 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 |
867 | cli_set_log_echo(this_cli, $2, $3); |
868 | cli_msg(0, ""); | |
869 | } ; | |
870 | ||
871 | echo_mask: | |
872 | ALL { $$ = ~0; } | |
873 | | OFF { $$ = 0; } | |
508d9360 | 874 | | '{' log_mask_list '}' { $$ = $2; } |
34350a52 MM |
875 | ; |
876 | ||
877 | echo_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 | 885 | CF_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 | 887 | CF_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 | 889 | CF_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 | 891 | CF_CLI(RELOAD, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol]]) |
e0a45fb4 | 892 | { proto_apply_cmd($2, proto_cmd_reload, 1, CMD_RELOAD); } ; |
8a7fb885 | 893 | CF_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 | 895 | CF_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 | 898 | CF_CLI_HELP(DEBUG, ..., [[Control protocol debugging via BIRD logs]]) |
61dae32b OZ |
899 | CF_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 | ||
902 | debug_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 | |
907 | CF_CLI_HELP(MRTDUMP, ..., [[Control protocol debugging via MRTdump files]]) | |
9df52a98 | 908 | CF_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 | ||
911 | CF_CLI(RESTRICT,,,[[Restrict current CLI session to safe commands]]) | |
912 | { this_cli->restricted = 1; cli_msg(16, "Access restricted"); } ; | |
96d8e3bf | 913 | |
f14a4bec | 914 | proto_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 | 920 | proto_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 | 926 | dynamic_attr: IGP_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_GEN_IGP_METRIC); } ; |
ba5e5940 | 927 | |
e304fd4b | 928 | |
da877822 MM |
929 | CF_CODE |
930 | ||
931 | CF_END |