1998-11-28 03:37:57 +08:00
|
|
|
/*
|
|
|
|
* BIRD -- Core Configuration
|
|
|
|
*
|
2000-01-19 20:30:19 +08:00
|
|
|
* (c) 1998--2000 Martin Mares <mj@ucw.cz>
|
2004-07-13 22:46:14 +08:00
|
|
|
* (c) 2004 Ondrej Filip <feela@network.cz>
|
1998-11-28 03:37:57 +08:00
|
|
|
*
|
|
|
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
|
|
|
*/
|
|
|
|
|
|
|
|
CF_HDR
|
|
|
|
|
1998-11-30 06:03:58 +08:00
|
|
|
#include "nest/rt-dev.h"
|
1999-05-26 22:24:57 +08:00
|
|
|
#include "nest/password.h"
|
2000-01-19 20:30:19 +08:00
|
|
|
#include "nest/cmds.h"
|
2004-06-27 04:11:14 +08:00
|
|
|
#include "lib/lists.h"
|
1998-11-30 06:03:58 +08:00
|
|
|
|
2000-04-28 23:11:10 +08:00
|
|
|
CF_DEFINES
|
|
|
|
|
|
|
|
static struct proto_config *this_proto;
|
|
|
|
static struct iface_patt *this_ipatt;
|
2009-05-07 04:02:45 +08:00
|
|
|
static struct iface_patt_node *this_ipn;
|
2012-03-19 00:32:30 +08:00
|
|
|
static struct roa_table_config *this_roa_table;
|
2004-06-27 04:11:14 +08:00
|
|
|
static list *this_p_list;
|
|
|
|
static struct password_item *this_p_item;
|
2008-11-09 00:24:23 +08:00
|
|
|
static int password_id;
|
|
|
|
|
2009-04-09 02:15:01 +08:00
|
|
|
static inline void
|
|
|
|
reset_passwords(void)
|
|
|
|
{
|
2011-11-07 07:31:23 +08:00
|
|
|
this_p_list = NULL;
|
2009-04-09 02:15:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline list *
|
2008-11-09 00:24:23 +08:00
|
|
|
get_passwords(void)
|
|
|
|
{
|
|
|
|
list *rv = this_p_list;
|
|
|
|
this_p_list = NULL;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-11-07 07:31:23 +08:00
|
|
|
#define DIRECT_CFG ((struct rt_dev_config *) this_proto)
|
2000-04-28 23:11:10 +08:00
|
|
|
|
1998-11-28 03:37:57 +08:00
|
|
|
CF_DECLS
|
|
|
|
|
2011-11-07 07:31:23 +08:00
|
|
|
CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
|
2000-03-08 04:49:48 +08:00
|
|
|
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
|
2000-03-13 04:50:35 +08:00
|
|
|
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
|
2012-03-22 18:46:38 +08:00
|
|
|
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE, ROA, MAX, FLUSH)
|
2012-07-05 03:31:03 +08:00
|
|
|
CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION, SORTED)
|
2010-08-02 19:11:53 +08:00
|
|
|
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC)
|
1998-11-28 03:37:57 +08:00
|
|
|
|
1999-11-15 19:36:22 +08:00
|
|
|
CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
|
2004-06-26 00:39:53 +08:00
|
|
|
RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE)
|
2011-09-24 17:06:42 +08:00
|
|
|
CF_ENUM(T_ENUM_SCOPE, SCOPE_, HOST, LINK, SITE, ORGANIZATION, UNIVERSE, UNDEFINED)
|
2000-05-30 18:42:39 +08:00
|
|
|
CF_ENUM(T_ENUM_RTC, RTC_, UNICAST, BROADCAST, MULTICAST, ANYCAST)
|
2010-12-08 06:33:55 +08:00
|
|
|
CF_ENUM(T_ENUM_RTD, RTD_, ROUTER, DEVICE, BLACKHOLE, UNREACHABLE, PROHIBIT, MULTIPATH)
|
2012-03-19 00:32:30 +08:00
|
|
|
CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID)
|
1999-11-15 19:36:22 +08:00
|
|
|
|
1999-08-04 03:36:06 +08:00
|
|
|
%type <i32> idval
|
1999-04-06 04:15:31 +08:00
|
|
|
%type <f> imexport
|
1999-05-18 04:14:52 +08:00
|
|
|
%type <r> rtable
|
1999-11-25 23:35:30 +08:00
|
|
|
%type <s> optsym
|
1999-12-01 23:10:21 +08:00
|
|
|
%type <ra> r_args
|
2012-03-19 00:32:30 +08:00
|
|
|
%type <ro> roa_args
|
|
|
|
%type <rot> roa_table_arg
|
2012-03-16 19:47:12 +08:00
|
|
|
%type <sd> sym_args
|
2012-07-05 03:31:03 +08:00
|
|
|
%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_or_preexport roa_mode tab_sorted
|
2010-02-20 07:03:31 +08:00
|
|
|
%type <ps> proto_patt proto_patt2
|
1998-11-28 03:37:57 +08:00
|
|
|
|
|
|
|
CF_GRAMMAR
|
|
|
|
|
1998-11-28 05:09:57 +08:00
|
|
|
/* Setting of router ID */
|
|
|
|
|
1998-11-28 03:37:57 +08:00
|
|
|
CF_ADDTO(conf, rtrid)
|
1999-05-18 04:14:52 +08:00
|
|
|
|
1999-03-30 03:04:14 +08:00
|
|
|
rtrid: ROUTER ID idval ';' {
|
1999-02-06 05:37:34 +08:00
|
|
|
new_config->router_id = $3;
|
1998-11-28 05:09:57 +08:00
|
|
|
}
|
1998-11-28 03:37:57 +08:00
|
|
|
;
|
|
|
|
|
|
|
|
idval:
|
1999-08-04 03:36:06 +08:00
|
|
|
NUM { $$ = $1; }
|
|
|
|
| RTRID
|
|
|
|
| IPA {
|
|
|
|
#ifndef IPV6
|
|
|
|
$$ = ipa_to_u32($1);
|
|
|
|
#else
|
2000-05-16 23:08:43 +08:00
|
|
|
cf_error("Router IDs must be entered as hexadecimal numbers or IPv4 addresses in IPv6 version");
|
1999-08-04 03:36:06 +08:00
|
|
|
#endif
|
|
|
|
}
|
1998-11-28 03:37:57 +08:00
|
|
|
;
|
|
|
|
|
2009-06-19 01:20:07 +08:00
|
|
|
|
2009-06-23 17:08:30 +08:00
|
|
|
CF_ADDTO(conf, listen)
|
2009-06-19 01:20:07 +08:00
|
|
|
|
2009-06-23 17:08:30 +08:00
|
|
|
listen: LISTEN BGP listen_opts ';' ;
|
2009-06-19 01:20:07 +08:00
|
|
|
|
2009-06-23 17:08:30 +08:00
|
|
|
listen_opts:
|
2009-06-19 01:20:07 +08:00
|
|
|
/* Nothing */
|
2009-06-23 17:08:30 +08:00
|
|
|
| listen_opts listen_opt
|
2009-06-19 01:20:07 +08:00
|
|
|
;
|
|
|
|
|
2009-06-23 17:08:30 +08:00
|
|
|
listen_opt:
|
|
|
|
ADDRESS ipa { new_config->listen_bgp_addr = $2; }
|
|
|
|
| PORT expr { new_config->listen_bgp_port = $2; }
|
2010-11-03 17:02:24 +08:00
|
|
|
| V6ONLY { new_config->listen_bgp_flags = 0; }
|
|
|
|
| DUAL { new_config->listen_bgp_flags = 1; }
|
2009-06-19 01:20:07 +08:00
|
|
|
;
|
|
|
|
|
|
|
|
|
1999-05-18 04:14:52 +08:00
|
|
|
/* Creation of routing tables */
|
|
|
|
|
2012-07-05 03:31:03 +08:00
|
|
|
tab_sorted:
|
|
|
|
{ $$ = 0; }
|
|
|
|
| SORTED { $$ = 1; }
|
|
|
|
;
|
|
|
|
|
1999-05-18 04:14:52 +08:00
|
|
|
CF_ADDTO(conf, newtab)
|
|
|
|
|
2012-07-05 03:31:03 +08:00
|
|
|
newtab: TABLE SYM tab_sorted {
|
|
|
|
struct rtable_config *cf;
|
|
|
|
cf = rt_new_table($2);
|
|
|
|
cf->sorted = $3;
|
1999-05-18 04:14:52 +08:00
|
|
|
}
|
|
|
|
;
|
|
|
|
|
2012-03-19 00:32:30 +08:00
|
|
|
CF_ADDTO(conf, roa_table)
|
|
|
|
|
|
|
|
roa_table_start: ROA TABLE SYM {
|
|
|
|
this_roa_table = roa_new_table_config($3);
|
|
|
|
};
|
|
|
|
|
|
|
|
roa_table_opts:
|
|
|
|
/* empty */
|
|
|
|
| roa_table_opts ROA prefix MAX NUM AS NUM ';' {
|
|
|
|
roa_add_item_config(this_roa_table, $3.addr, $3.len, $5, $7);
|
|
|
|
}
|
|
|
|
;
|
|
|
|
|
|
|
|
roa_table:
|
|
|
|
roa_table_start
|
|
|
|
| roa_table_start '{' roa_table_opts '}'
|
|
|
|
;
|
|
|
|
|
1998-11-28 05:09:57 +08:00
|
|
|
/* Definition of protocols */
|
|
|
|
|
|
|
|
CF_ADDTO(conf, proto)
|
|
|
|
|
2011-11-07 07:31:23 +08:00
|
|
|
proto_start:
|
|
|
|
PROTOCOL { $$ = SYM_PROTO; }
|
|
|
|
| TEMPLATE { $$ = SYM_TEMPLATE; }
|
2002-11-13 16:46:12 +08:00
|
|
|
;
|
1998-11-28 05:09:57 +08:00
|
|
|
|
|
|
|
proto_name:
|
|
|
|
/* EMPTY */ {
|
2000-01-17 19:52:50 +08:00
|
|
|
struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter);
|
2011-11-07 07:31:23 +08:00
|
|
|
s->class = this_proto->class;
|
1998-11-28 05:09:57 +08:00
|
|
|
s->def = this_proto;
|
|
|
|
this_proto->name = s->name;
|
|
|
|
}
|
|
|
|
| SYM {
|
2011-11-07 07:31:23 +08:00
|
|
|
cf_define_symbol($1, this_proto->class, this_proto);
|
1998-11-28 05:09:57 +08:00
|
|
|
this_proto->name = $1->name;
|
|
|
|
}
|
2011-11-07 07:31:23 +08:00
|
|
|
| SYM FROM SYM {
|
|
|
|
if (($3->class != SYM_TEMPLATE) && ($3->class != SYM_PROTO)) cf_error("Template or protocol name expected");
|
|
|
|
|
|
|
|
cf_define_symbol($1, this_proto->class, this_proto);
|
|
|
|
this_proto->name = $1->name;
|
|
|
|
|
|
|
|
proto_copy_config(this_proto, $3->def);
|
|
|
|
}
|
1998-11-28 05:09:57 +08:00
|
|
|
;
|
|
|
|
|
|
|
|
proto_item:
|
|
|
|
/* EMPTY */
|
1998-11-28 05:32:45 +08:00
|
|
|
| PREFERENCE expr {
|
2009-09-17 19:35:37 +08:00
|
|
|
if ($2 < 0 || $2 > 0xFFFF) cf_error("Invalid preference");
|
1998-11-28 05:09:57 +08:00
|
|
|
this_proto->preference = $2;
|
|
|
|
}
|
2000-06-08 18:25:56 +08:00
|
|
|
| DISABLED bool { this_proto->disabled = $2; }
|
2000-03-08 04:49:48 +08:00
|
|
|
| DEBUG debug_mask { this_proto->debug = $2; }
|
2010-01-03 19:17:52 +08:00
|
|
|
| MRTDUMP mrtdump_mask { this_proto->mrtdump = $2; }
|
1999-04-06 04:15:31 +08:00
|
|
|
| IMPORT imexport { this_proto->in_filter = $2; }
|
|
|
|
| EXPORT imexport { this_proto->out_filter = $2; }
|
1999-05-18 04:14:52 +08:00
|
|
|
| TABLE rtable { this_proto->table = $2; }
|
2009-10-13 05:31:42 +08:00
|
|
|
| ROUTER ID idval { this_proto->router_id = $3; }
|
2009-11-19 03:32:36 +08:00
|
|
|
| DESCRIPTION TEXT { this_proto->dsc = $2; }
|
1999-04-06 04:15:31 +08:00
|
|
|
;
|
|
|
|
|
|
|
|
imexport:
|
|
|
|
FILTER filter { $$ = $2; }
|
2000-04-01 17:17:33 +08:00
|
|
|
| where_filter
|
1999-04-06 04:15:31 +08:00
|
|
|
| ALL { $$ = FILTER_ACCEPT; }
|
|
|
|
| NONE { $$ = FILTER_REJECT; }
|
1998-11-28 05:09:57 +08:00
|
|
|
;
|
|
|
|
|
1999-05-18 04:14:52 +08:00
|
|
|
rtable:
|
|
|
|
SYM {
|
|
|
|
if ($1->class != SYM_TABLE) cf_error("Table name expected");
|
|
|
|
$$ = $1->def;
|
|
|
|
}
|
|
|
|
;
|
|
|
|
|
2000-03-08 05:50:03 +08:00
|
|
|
CF_ADDTO(conf, debug_default)
|
|
|
|
|
|
|
|
debug_default:
|
|
|
|
DEBUG PROTOCOLS debug_mask { new_config->proto_default_debug = $3; }
|
2000-05-30 06:10:18 +08:00
|
|
|
| DEBUG COMMANDS expr { new_config->cli_debug = $3; }
|
2000-03-08 05:50:03 +08:00
|
|
|
;
|
|
|
|
|
2010-01-03 19:17:52 +08:00
|
|
|
/* MRTDUMP PROTOCOLS is in systep/unix/config.Y */
|
|
|
|
|
1999-08-04 03:30:49 +08:00
|
|
|
/* Interface patterns */
|
|
|
|
|
2009-05-07 04:02:45 +08:00
|
|
|
iface_patt_node_init:
|
|
|
|
/* EMPTY */ {
|
|
|
|
struct iface_patt_node *ipn = cfg_allocz(sizeof(struct iface_patt_node));
|
|
|
|
add_tail(&this_ipatt->ipn_list, NODE ipn);
|
|
|
|
this_ipn = ipn;
|
|
|
|
}
|
|
|
|
;
|
|
|
|
|
|
|
|
iface_patt_node_body:
|
|
|
|
TEXT { this_ipn->pattern = $1; this_ipn->prefix = IPA_NONE; this_ipn->pxlen = 0; }
|
2010-03-20 01:46:56 +08:00
|
|
|
| prefix_or_ipa { this_ipn->pattern = NULL; this_ipn->prefix = $1.addr; this_ipn->pxlen = $1.len; }
|
|
|
|
| TEXT prefix_or_ipa { this_ipn->pattern = $1; this_ipn->prefix = $2.addr; this_ipn->pxlen = $2.len; }
|
2009-05-07 04:02:45 +08:00
|
|
|
;
|
|
|
|
|
|
|
|
iface_negate:
|
|
|
|
{ this_ipn->positive = 1; }
|
|
|
|
| '-' { this_ipn->positive = 0; }
|
|
|
|
;
|
|
|
|
|
|
|
|
iface_patt_node:
|
|
|
|
iface_patt_node_init iface_negate iface_patt_node_body
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
iface_patt_list:
|
|
|
|
iface_patt_node
|
|
|
|
| iface_patt_list ',' iface_patt_node
|
1999-08-04 03:30:49 +08:00
|
|
|
;
|
|
|
|
|
2009-05-07 04:02:45 +08:00
|
|
|
|
1999-03-27 05:44:38 +08:00
|
|
|
/* Direct device route protocol */
|
1998-11-30 06:03:58 +08:00
|
|
|
|
|
|
|
CF_ADDTO(proto, dev_proto '}')
|
|
|
|
|
1999-03-27 05:44:38 +08:00
|
|
|
dev_proto_start: proto_start DIRECT {
|
2011-11-07 07:31:23 +08:00
|
|
|
this_proto = proto_config_new(&proto_device, sizeof(struct rt_dev_config), $1);
|
|
|
|
init_list(&DIRECT_CFG->iface_list);
|
1998-11-30 06:03:58 +08:00
|
|
|
}
|
|
|
|
;
|
|
|
|
|
|
|
|
dev_proto:
|
1999-03-27 05:44:38 +08:00
|
|
|
dev_proto_start proto_name '{'
|
1998-11-30 06:03:58 +08:00
|
|
|
| dev_proto proto_item ';'
|
2009-05-07 04:02:45 +08:00
|
|
|
| dev_proto dev_iface_patt ';'
|
1998-11-30 06:03:58 +08:00
|
|
|
;
|
|
|
|
|
2009-05-07 04:02:45 +08:00
|
|
|
dev_iface_init:
|
1999-08-04 03:30:49 +08:00
|
|
|
/* EMPTY */ {
|
2009-05-07 04:02:45 +08:00
|
|
|
this_ipatt = cfg_allocz(sizeof(struct iface_patt));
|
2011-11-07 07:31:23 +08:00
|
|
|
add_tail(&DIRECT_CFG->iface_list, NODE this_ipatt);
|
2009-05-07 04:02:45 +08:00
|
|
|
init_list(&this_ipatt->ipn_list);
|
1998-11-30 06:03:58 +08:00
|
|
|
}
|
|
|
|
;
|
|
|
|
|
2009-05-07 04:02:45 +08:00
|
|
|
dev_iface_patt:
|
|
|
|
INTERFACE dev_iface_init iface_patt_list
|
1999-08-04 03:30:49 +08:00
|
|
|
;
|
|
|
|
|
2000-03-08 04:49:48 +08:00
|
|
|
/* Debug flags */
|
|
|
|
|
|
|
|
debug_mask:
|
|
|
|
ALL { $$ = ~0; }
|
|
|
|
| OFF { $$ = 0; }
|
|
|
|
| '{' debug_list '}' { $$ = $2; }
|
|
|
|
;
|
|
|
|
|
|
|
|
debug_list:
|
|
|
|
debug_flag
|
|
|
|
| debug_list ',' debug_flag { $$ = $1 | $3; }
|
|
|
|
;
|
|
|
|
|
|
|
|
debug_flag:
|
|
|
|
STATES { $$ = D_STATES; }
|
|
|
|
| ROUTES { $$ = D_ROUTES; }
|
|
|
|
| FILTERS { $$ = D_FILTERS; }
|
2000-03-13 04:50:35 +08:00
|
|
|
| INTERFACES { $$ = D_IFACES; }
|
2000-03-08 04:49:48 +08:00
|
|
|
| EVENTS { $$ = D_EVENTS; }
|
|
|
|
| PACKETS { $$ = D_PACKETS; }
|
|
|
|
;
|
|
|
|
|
2010-01-03 19:17:52 +08:00
|
|
|
/* MRTDump flags */
|
|
|
|
|
|
|
|
mrtdump_mask:
|
|
|
|
ALL { $$ = ~0; }
|
|
|
|
| OFF { $$ = 0; }
|
|
|
|
| '{' mrtdump_list '}' { $$ = $2; }
|
|
|
|
;
|
|
|
|
|
|
|
|
mrtdump_list:
|
|
|
|
mrtdump_flag
|
|
|
|
| mrtdump_list ',' mrtdump_flag { $$ = $1 | $3; }
|
|
|
|
;
|
|
|
|
|
|
|
|
mrtdump_flag:
|
|
|
|
STATES { $$ = MD_STATES; }
|
|
|
|
| MESSAGES { $$ = MD_MESSAGES; }
|
|
|
|
;
|
|
|
|
|
1999-08-04 03:30:49 +08:00
|
|
|
/* Password lists */
|
|
|
|
|
2008-11-09 00:24:23 +08:00
|
|
|
password_list:
|
|
|
|
PASSWORDS '{' password_items '}'
|
|
|
|
| password_item
|
|
|
|
;
|
|
|
|
|
2004-06-27 04:11:14 +08:00
|
|
|
password_items:
|
|
|
|
/* empty */
|
|
|
|
| password_item ';' password_items
|
|
|
|
;
|
|
|
|
|
|
|
|
password_item:
|
|
|
|
password_item_begin '{' password_item_params '}'
|
|
|
|
| password_item_begin
|
|
|
|
;
|
|
|
|
|
|
|
|
password_item_begin:
|
1999-05-26 22:24:57 +08:00
|
|
|
PASSWORD TEXT {
|
2008-11-09 00:24:23 +08:00
|
|
|
if (!this_p_list) {
|
|
|
|
this_p_list = cfg_alloc(sizeof(list));
|
|
|
|
init_list(this_p_list);
|
|
|
|
password_id = 1;
|
|
|
|
}
|
2004-06-27 04:11:14 +08:00
|
|
|
this_p_item = cfg_alloc(sizeof (struct password_item));
|
|
|
|
this_p_item->password = $2;
|
|
|
|
this_p_item->genfrom = 0;
|
|
|
|
this_p_item->gento = TIME_INFINITY;
|
|
|
|
this_p_item->accfrom = 0;
|
|
|
|
this_p_item->accto = TIME_INFINITY;
|
2008-11-09 00:24:23 +08:00
|
|
|
this_p_item->id = password_id++;
|
2004-06-27 04:11:14 +08:00
|
|
|
add_tail(this_p_list, &this_p_item->n);
|
1999-05-26 22:24:57 +08:00
|
|
|
}
|
2004-06-27 04:11:14 +08:00
|
|
|
;
|
1999-05-26 22:24:57 +08:00
|
|
|
|
2004-06-27 04:11:14 +08:00
|
|
|
password_item_params:
|
1999-05-26 22:24:57 +08:00
|
|
|
/* empty */ { }
|
2004-06-27 04:11:14 +08:00
|
|
|
| GENERATE FROM datetime ';' password_item_params { this_p_item->genfrom = $3; }
|
|
|
|
| GENERATE TO datetime ';' password_item_params { this_p_item->gento = $3; }
|
|
|
|
| ACCEPT FROM datetime ';' password_item_params { this_p_item->accfrom = $3; }
|
|
|
|
| ACCEPT TO datetime ';' password_item_params { this_p_item->accto = $3; }
|
2004-07-13 22:46:14 +08:00
|
|
|
| ID expr ';' password_item_params { this_p_item->id = $2; if ($2 <= 0) cf_error("Password ID has to be greated than zero."); }
|
1999-05-26 22:24:57 +08:00
|
|
|
;
|
|
|
|
|
|
|
|
|
2009-08-17 04:36:41 +08:00
|
|
|
|
Parse CLI commands. We use the same parser as for configuration files (because
we want to allow filter and similar complex constructs to be used in commands
and we should avoid code duplication), only with CLI_MARKER token prepended
before the whole input.
Defined macro CF_CLI(cmd, args, help) for defining CLI commands in .Y files.
The first argument specifies the command itself, the remaining two arguments
are copied to the help file (er, will be copied after the help file starts
to exist). This macro automatically creates a skeleton rule for the command,
you only need to append arguments as in:
CF_CLI(STEAL MONEY, <$>, [[Steal <$> US dollars or equivalent in any other currency]]): NUM {
cli_msg(0, "%d$ stolen", $3);
} ;
Also don't forget to reset lexer state between inputs.
1999-11-01 01:47:47 +08:00
|
|
|
/* Core commands */
|
2000-02-18 07:37:16 +08:00
|
|
|
CF_CLI_HELP(SHOW, ..., [[Show status information]])
|
1999-11-25 23:35:30 +08:00
|
|
|
|
2000-01-19 20:30:19 +08:00
|
|
|
CF_CLI(SHOW STATUS,,, [[Show router status]])
|
2002-11-13 16:46:12 +08:00
|
|
|
{ cmd_show_status(); } ;
|
1999-11-25 23:35:30 +08:00
|
|
|
|
2010-06-03 04:20:40 +08:00
|
|
|
CF_CLI(SHOW MEMORY,,, [[Show memory usage]])
|
|
|
|
{ cmd_show_memory(); } ;
|
|
|
|
|
2010-02-20 07:03:31 +08:00
|
|
|
CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocols]])
|
2010-02-21 16:57:26 +08:00
|
|
|
{ proto_apply_cmd($3, proto_cmd_show, 0, 0); } ;
|
1999-11-30 20:57:14 +08:00
|
|
|
|
2010-02-20 07:03:31 +08:00
|
|
|
CF_CLI(SHOW PROTOCOLS ALL, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocol details]])
|
2010-02-21 16:57:26 +08:00
|
|
|
{ proto_apply_cmd($4, proto_cmd_show, 0, 1); } ;
|
1999-11-25 23:35:30 +08:00
|
|
|
|
1999-12-01 23:10:21 +08:00
|
|
|
optsym:
|
|
|
|
SYM
|
|
|
|
| /* empty */ { $$ = NULL; }
|
|
|
|
;
|
|
|
|
|
1999-11-25 23:35:30 +08:00
|
|
|
CF_CLI(SHOW INTERFACES,,, [[Show network interfaces]])
|
|
|
|
{ if_show(); } ;
|
|
|
|
|
|
|
|
CF_CLI(SHOW INTERFACES SUMMARY,,, [[Show summary of network interfaces]])
|
|
|
|
{ if_show_summary(); } ;
|
|
|
|
|
2012-03-22 18:46:38 +08:00
|
|
|
CF_CLI_HELP(SHOW ROUTE, ..., [[Show routing table]])
|
2009-05-22 23:12:15 +08:00
|
|
|
CF_CLI(SHOW ROUTE, r_args, [[[<prefix>|for <prefix>|for <ip>] [table <t>] [filter <f>|where <cond>] [all] [primary] [(export|preexport) <p>] [protocol <p>] [stats|count]]], [[Show routing table]])
|
1999-12-01 23:10:21 +08:00
|
|
|
{ rt_show($3); } ;
|
|
|
|
|
|
|
|
r_args:
|
|
|
|
/* empty */ {
|
|
|
|
$$ = cfg_allocz(sizeof(struct rt_show_data));
|
|
|
|
$$->pxlen = 256;
|
|
|
|
$$->filter = FILTER_ACCEPT;
|
|
|
|
$$->table = config->master_rtc->table;
|
|
|
|
}
|
2000-05-13 19:17:49 +08:00
|
|
|
| r_args prefix {
|
1999-12-01 23:10:21 +08:00
|
|
|
$$ = $1;
|
|
|
|
if ($$->pxlen != 256) cf_error("Only one prefix expected");
|
2000-05-13 19:17:49 +08:00
|
|
|
$$->prefix = $2.addr;
|
|
|
|
$$->pxlen = $2.len;
|
1999-12-01 23:10:21 +08:00
|
|
|
}
|
2000-05-13 19:42:42 +08:00
|
|
|
| r_args FOR prefix_or_ipa {
|
|
|
|
$$ = $1;
|
|
|
|
if ($$->pxlen != 256) cf_error("Only one prefix expected");
|
|
|
|
$$->prefix = $3.addr;
|
|
|
|
$$->pxlen = $3.len;
|
|
|
|
$$->show_for = 1;
|
|
|
|
}
|
1999-12-01 23:10:21 +08:00
|
|
|
| r_args TABLE SYM {
|
|
|
|
$$ = $1;
|
|
|
|
if ($3->class != SYM_TABLE) cf_error("%s is not a table", $3->name);
|
|
|
|
$$->table = ((struct rtable_config *)$3->def)->table;
|
|
|
|
}
|
|
|
|
| r_args FILTER filter {
|
|
|
|
$$ = $1;
|
1999-12-02 22:04:44 +08:00
|
|
|
if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice");
|
1999-12-01 23:10:21 +08:00
|
|
|
$$->filter = $3;
|
|
|
|
}
|
1999-12-02 22:04:44 +08:00
|
|
|
| r_args where_filter {
|
|
|
|
$$ = $1;
|
|
|
|
if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice");
|
|
|
|
$$->filter = $2;
|
|
|
|
}
|
1999-12-01 23:10:21 +08:00
|
|
|
| r_args ALL {
|
|
|
|
$$ = $1;
|
|
|
|
$$->verbose = 1;
|
|
|
|
}
|
2000-05-07 06:57:39 +08:00
|
|
|
| r_args PRIMARY {
|
|
|
|
$$ = $1;
|
|
|
|
$$->primary_only = 1;
|
|
|
|
}
|
2009-05-22 23:12:15 +08:00
|
|
|
| r_args export_or_preexport SYM {
|
2000-05-07 06:57:39 +08:00
|
|
|
struct proto_config *c = (struct proto_config *) $3->def;
|
|
|
|
$$ = $1;
|
2009-05-22 23:12:15 +08:00
|
|
|
if ($$->export_mode) cf_error("Protocol specified twice");
|
2000-05-07 06:57:39 +08:00
|
|
|
if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
|
2009-05-22 23:12:15 +08:00
|
|
|
$$->export_mode = $2;
|
2000-05-07 06:57:39 +08:00
|
|
|
$$->primary_only = 1;
|
2009-05-22 23:12:15 +08:00
|
|
|
$$->export_protocol = c->proto;
|
2000-05-07 06:57:39 +08:00
|
|
|
$$->running_on_config = c->proto->cf->global;
|
|
|
|
}
|
2009-05-11 08:01:11 +08:00
|
|
|
| r_args PROTOCOL SYM {
|
|
|
|
struct proto_config *c = (struct proto_config *) $3->def;
|
|
|
|
$$ = $1;
|
|
|
|
if ($$->show_protocol) cf_error("Protocol specified twice");
|
|
|
|
if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
|
|
|
|
$$->show_protocol = c->proto;
|
|
|
|
$$->running_on_config = c->proto->cf->global;
|
2000-05-07 06:57:39 +08:00
|
|
|
}
|
2000-05-07 19:28:59 +08:00
|
|
|
| r_args STATS {
|
|
|
|
$$ = $1;
|
|
|
|
$$->stats = 1;
|
|
|
|
}
|
2000-05-08 22:58:00 +08:00
|
|
|
| r_args COUNT {
|
|
|
|
$$ = $1;
|
|
|
|
$$->stats = 2;
|
|
|
|
}
|
2000-05-07 06:57:39 +08:00
|
|
|
;
|
|
|
|
|
2009-05-22 23:12:15 +08:00
|
|
|
export_or_preexport:
|
|
|
|
PREEXPORT { $$ = 1; }
|
|
|
|
| EXPORT { $$ = 2; }
|
1999-12-01 23:10:21 +08:00
|
|
|
;
|
|
|
|
|
2012-03-19 00:32:30 +08:00
|
|
|
|
2012-03-22 18:46:38 +08:00
|
|
|
CF_CLI_HELP(SHOW ROA, ..., [[Show ROA table]])
|
|
|
|
CF_CLI(SHOW ROA, roa_args, [<prefix> | in <prefix> | for <prefix>] [as <num>] [table <t>], [[Show ROA table]])
|
2012-03-19 00:32:30 +08:00
|
|
|
{ roa_show($3); } ;
|
|
|
|
|
|
|
|
roa_args:
|
|
|
|
/* empty */ {
|
|
|
|
$$ = cfg_allocz(sizeof(struct roa_show_data));
|
|
|
|
$$->mode = ROA_SHOW_ALL;
|
|
|
|
$$->table = roa_table_default;
|
|
|
|
if (roa_table_default == NULL)
|
|
|
|
cf_error("No ROA table defined");
|
|
|
|
}
|
|
|
|
| roa_args roa_mode prefix {
|
|
|
|
$$ = $1;
|
|
|
|
if ($$->mode != ROA_SHOW_ALL) cf_error("Only one prefix expected");
|
|
|
|
$$->prefix = $3.addr;
|
|
|
|
$$->pxlen = $3.len;
|
|
|
|
$$->mode = $2;
|
|
|
|
}
|
|
|
|
| roa_args AS NUM {
|
|
|
|
$$ = $1;
|
|
|
|
$$->asn = $3;
|
|
|
|
}
|
|
|
|
| roa_args TABLE SYM {
|
|
|
|
$$ = $1;
|
|
|
|
if ($3->class != SYM_ROA) cf_error("%s is not a ROA table", $3->name);
|
|
|
|
$$->table = ((struct roa_table_config *)$3->def)->table;
|
|
|
|
}
|
|
|
|
;
|
|
|
|
|
|
|
|
roa_mode:
|
|
|
|
{ $$ = ROA_SHOW_PX; }
|
|
|
|
| IN { $$ = ROA_SHOW_IN; }
|
|
|
|
| FOR { $$ = ROA_SHOW_FOR; }
|
|
|
|
;
|
|
|
|
|
|
|
|
|
2012-03-22 18:46:38 +08:00
|
|
|
CF_CLI_HELP(SHOW SYMBOLS, ..., [[Show all known symbolic names]])
|
2012-03-19 00:32:30 +08:00
|
|
|
CF_CLI(SHOW SYMBOLS, sym_args, [table|filter|function|protocol|template|roa|<symbol>], [[Show all known symbolic names]])
|
2000-01-19 20:30:19 +08:00
|
|
|
{ cmd_show_symbols($3); } ;
|
|
|
|
|
2012-03-16 19:47:12 +08:00
|
|
|
sym_args:
|
|
|
|
/* empty */ {
|
|
|
|
$$ = cfg_allocz(sizeof(struct sym_show_data));
|
|
|
|
}
|
|
|
|
| sym_args TABLE { $$ = $1; $$->type = SYM_TABLE; }
|
|
|
|
| sym_args FUNCTION { $$ = $1; $$->type = SYM_FUNCTION; }
|
|
|
|
| sym_args FILTER { $$ = $1; $$->type = SYM_FILTER; }
|
|
|
|
| sym_args PROTOCOL { $$ = $1; $$->type = SYM_PROTO; }
|
|
|
|
| sym_args TEMPLATE { $$ = $1; $$->type = SYM_TEMPLATE; }
|
2012-03-19 00:32:30 +08:00
|
|
|
| sym_args ROA { $$ = $1; $$->type = SYM_ROA; }
|
2012-03-16 19:47:12 +08:00
|
|
|
| sym_args SYM { $$ = $1; $$->sym = $2; }
|
|
|
|
;
|
|
|
|
|
2012-03-19 00:32:30 +08:00
|
|
|
|
|
|
|
roa_table_arg:
|
|
|
|
/* empty */ {
|
|
|
|
if (roa_table_default == NULL)
|
|
|
|
cf_error("No ROA table defined");
|
|
|
|
$$ = roa_table_default;
|
|
|
|
}
|
|
|
|
| TABLE SYM {
|
|
|
|
if ($2->class != SYM_ROA)
|
|
|
|
cf_error("%s is not a ROA table", $2->name);
|
|
|
|
$$ = ((struct roa_table_config *)$2->def)->table;
|
|
|
|
}
|
|
|
|
;
|
|
|
|
|
2012-03-22 18:46:38 +08:00
|
|
|
CF_CLI_HELP(ADD, roa ..., [[Add ROA record]])
|
2012-03-19 00:32:30 +08:00
|
|
|
CF_CLI(ADD ROA, prefix MAX NUM AS NUM roa_table_arg, <prefix> max <num> as <num> [table <name>], [[Add ROA record]])
|
2012-03-22 18:46:38 +08:00
|
|
|
{
|
|
|
|
if (! cli_access_restricted())
|
|
|
|
{ roa_add_item($8, $3.addr, $3.len, $5, $7, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
|
|
|
|
};
|
2012-03-19 00:32:30 +08:00
|
|
|
|
2012-03-22 18:46:38 +08:00
|
|
|
CF_CLI_HELP(DELETE, roa ..., [[Delete ROA record]])
|
2012-03-19 00:32:30 +08:00
|
|
|
CF_CLI(DELETE ROA, prefix MAX NUM AS NUM roa_table_arg, <prefix> max <num> as <num> [table <name>], [[Delete ROA record]])
|
2012-03-22 18:46:38 +08:00
|
|
|
{
|
|
|
|
if (! cli_access_restricted())
|
|
|
|
{ roa_delete_item($8, $3.addr, $3.len, $5, $7, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
|
|
|
|
};
|
2012-03-19 00:32:30 +08:00
|
|
|
|
2012-03-22 18:46:38 +08:00
|
|
|
CF_CLI_HELP(FLUSH, roa [table <name>], [[Removes all dynamic ROA records]])
|
2012-03-19 00:32:30 +08:00
|
|
|
CF_CLI(FLUSH ROA, roa_table_arg, [table <name>], [[Removes all dynamic ROA records]])
|
2012-03-22 18:46:38 +08:00
|
|
|
{
|
|
|
|
if (! cli_access_restricted())
|
|
|
|
{ roa_flush($3, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
|
|
|
|
};
|
2012-03-19 00:32:30 +08:00
|
|
|
|
|
|
|
|
2000-03-08 04:49:48 +08:00
|
|
|
CF_CLI_HELP(DUMP, ..., [[Dump debugging information]])
|
|
|
|
CF_CLI(DUMP RESOURCES,,, [[Dump all allocated resource]])
|
1999-12-06 20:34:45 +08:00
|
|
|
{ rdump(&root_pool); cli_msg(0, ""); } ;
|
2000-03-08 04:49:48 +08:00
|
|
|
CF_CLI(DUMP SOCKETS,,, [[Dump open sockets]])
|
1999-12-06 20:34:45 +08:00
|
|
|
{ sk_dump_all(); cli_msg(0, ""); } ;
|
2000-03-08 04:49:48 +08:00
|
|
|
CF_CLI(DUMP INTERFACES,,, [[Dump interface information]])
|
1999-12-06 20:34:45 +08:00
|
|
|
{ if_dump_all(); cli_msg(0, ""); } ;
|
2000-03-08 04:49:48 +08:00
|
|
|
CF_CLI(DUMP NEIGHBORS,,, [[Dump neighbor cache]])
|
1999-12-06 20:34:45 +08:00
|
|
|
{ neigh_dump_all(); cli_msg(0, ""); } ;
|
2000-03-08 04:49:48 +08:00
|
|
|
CF_CLI(DUMP ATTRIBUTES,,, [[Dump attribute cache]])
|
1999-12-06 20:34:45 +08:00
|
|
|
{ rta_dump_all(); cli_msg(0, ""); } ;
|
2000-03-08 04:49:48 +08:00
|
|
|
CF_CLI(DUMP ROUTES,,, [[Dump routing table]])
|
1999-12-06 20:34:45 +08:00
|
|
|
{ rt_dump_all(); cli_msg(0, ""); } ;
|
2000-03-08 04:49:48 +08:00
|
|
|
CF_CLI(DUMP PROTOCOLS,,, [[Dump protocol information]])
|
1999-12-06 20:34:45 +08:00
|
|
|
{ protos_dump_all(); cli_msg(0, ""); } ;
|
|
|
|
|
|
|
|
CF_CLI(ECHO, echo_mask echo_size, [all | off | <mask>] [<buffer-size>], [[Configure echoing of log messages]]) {
|
|
|
|
cli_set_log_echo(this_cli, $2, $3);
|
|
|
|
cli_msg(0, "");
|
|
|
|
} ;
|
|
|
|
|
|
|
|
echo_mask:
|
|
|
|
ALL { $$ = ~0; }
|
|
|
|
| OFF { $$ = 0; }
|
|
|
|
| NUM
|
|
|
|
;
|
|
|
|
|
|
|
|
echo_size:
|
|
|
|
/* empty */ { $$ = 4096; }
|
|
|
|
| NUM {
|
|
|
|
if ($1 < 256 || $1 > 65536) cf_error("Invalid log buffer size");
|
|
|
|
$$ = $1;
|
|
|
|
}
|
|
|
|
;
|
Parse CLI commands. We use the same parser as for configuration files (because
we want to allow filter and similar complex constructs to be used in commands
and we should avoid code duplication), only with CLI_MARKER token prepended
before the whole input.
Defined macro CF_CLI(cmd, args, help) for defining CLI commands in .Y files.
The first argument specifies the command itself, the remaining two arguments
are copied to the help file (er, will be copied after the help file starts
to exist). This macro automatically creates a skeleton rule for the command,
you only need to append arguments as in:
CF_CLI(STEAL MONEY, <$>, [[Steal <$> US dollars or equivalent in any other currency]]): NUM {
cli_msg(0, "%d$ stolen", $3);
} ;
Also don't forget to reset lexer state between inputs.
1999-11-01 01:47:47 +08:00
|
|
|
|
2000-06-08 18:48:35 +08:00
|
|
|
CF_CLI(DISABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Disable protocol]])
|
2010-02-21 16:57:26 +08:00
|
|
|
{ proto_apply_cmd($2, proto_cmd_disable, 1, 0); } ;
|
2000-06-08 18:48:35 +08:00
|
|
|
CF_CLI(ENABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Enable protocol]])
|
2010-02-21 16:57:26 +08:00
|
|
|
{ proto_apply_cmd($2, proto_cmd_enable, 1, 0); } ;
|
2000-06-08 18:48:35 +08:00
|
|
|
CF_CLI(RESTART, proto_patt, <protocol> | \"<pattern>\" | all, [[Restart protocol]])
|
2010-02-21 16:57:26 +08:00
|
|
|
{ proto_apply_cmd($2, proto_cmd_restart, 1, 0); } ;
|
2009-11-27 03:47:59 +08:00
|
|
|
CF_CLI(RELOAD, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol]])
|
2010-02-21 16:57:26 +08:00
|
|
|
{ proto_apply_cmd($2, proto_cmd_reload, 1, CMD_RELOAD); } ;
|
2009-12-14 08:32:37 +08:00
|
|
|
CF_CLI(RELOAD IN, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just imported routes)]])
|
2010-02-21 16:57:26 +08:00
|
|
|
{ proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_IN); } ;
|
2009-12-14 08:32:37 +08:00
|
|
|
CF_CLI(RELOAD OUT, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just exported routes)]])
|
2010-02-21 16:57:26 +08:00
|
|
|
{ proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_OUT); } ;
|
2000-01-17 07:30:06 +08:00
|
|
|
|
2010-01-03 19:17:52 +08:00
|
|
|
CF_CLI_HELP(DEBUG, ..., [[Control protocol debugging via BIRD logs]])
|
2010-02-11 17:23:35 +08:00
|
|
|
CF_CLI(DEBUG, proto_patt debug_mask, (<protocol> | <pattern> | all) (all | off | { states | routes | filters | interfaces | events | packets }), [[Control protocol debugging via BIRD logs]])
|
2010-02-21 16:57:26 +08:00
|
|
|
{ proto_apply_cmd($2, proto_cmd_debug, 1, $3); } ;
|
2010-01-03 19:17:52 +08:00
|
|
|
|
|
|
|
CF_CLI_HELP(MRTDUMP, ..., [[Control protocol debugging via MRTdump files]])
|
|
|
|
CF_CLI(MRTDUMP, proto_patt mrtdump_mask, (<protocol> | <pattern> | all) (all | off | { states | messages }), [[Control protocol debugging via MRTdump format]])
|
2010-02-21 16:57:26 +08:00
|
|
|
{ proto_apply_cmd($2, proto_cmd_mrtdump, 1, $3); } ;
|
|
|
|
|
|
|
|
CF_CLI(RESTRICT,,,[[Restrict current CLI session to safe commands]])
|
|
|
|
{ this_cli->restricted = 1; cli_msg(16, "Access restricted"); } ;
|
2000-03-08 04:49:48 +08:00
|
|
|
|
2000-01-17 07:30:06 +08:00
|
|
|
proto_patt:
|
2010-02-20 07:03:31 +08:00
|
|
|
SYM { $$.ptr = $1; $$.patt = 0; }
|
|
|
|
| ALL { $$.ptr = NULL; $$.patt = 1; }
|
|
|
|
| TEXT { $$.ptr = $1; $$.patt = 1; }
|
2000-01-17 07:30:06 +08:00
|
|
|
;
|
|
|
|
|
2010-02-20 07:03:31 +08:00
|
|
|
proto_patt2:
|
|
|
|
SYM { $$.ptr = $1; $$.patt = 0; }
|
|
|
|
| { $$.ptr = NULL; $$.patt = 1; }
|
|
|
|
| TEXT { $$.ptr = $1; $$.patt = 1; }
|
|
|
|
;
|
|
|
|
|
2010-08-02 19:11:53 +08:00
|
|
|
CF_ADDTO(dynamic_attr, IGP_METRIC
|
|
|
|
{ $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_GEN_IGP_METRIC); })
|
|
|
|
|
2010-02-20 07:03:31 +08:00
|
|
|
|
1998-11-28 03:37:57 +08:00
|
|
|
CF_CODE
|
|
|
|
|
|
|
|
CF_END
|