1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
|
/* Command handler node_type stuff -- header
* Copyright (C) 1997, 98 Kunihiro Ishiguro
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2, or (at your
* option) any later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_COMMAND_COMMON_H
#define _ZEBRA_COMMAND_COMMON_H
#include "misc.h"
#include "vector.h"
/*------------------------------------------------------------------------------
* These are the command nodes/contexts.
*
* In this context, "context" means any state which may be associated with a
* command node. In particular, the vty->index field contains state whose
* meaning depends on the current node -- but there may be any amount of other
* state elsewhere, the command system does not know. The rules governing
* that context are described below.
*
* There are "bands" of nodes with their own properties:
*
* * SPECIAL -- used, if at all, temporarily
*
* EXIT_NODE -- temporary state on the way out
*
* ie at EOF on a file or pipe, or about to close VTY
* TERMINAL, VTYSH SERVER or VTYSH itself.
*
* META_NODE -- contains the meta-commands. Will never be in this
* node.
*
* These nodes have no node changing commands, including no "end" and
* "exit".
*
* These nodes have no context of their own.
*
* * VIEW -- used in VTY Terminal
*
* AUTH_NODE -- default initial state.
*
* May move up to VIEW_NODE or ENABLE node once has
* authenticated.
*
* VIEW_NODE -- default state after AUTH_NODE, and optional initial
* state.
*
* May move up to an ENABLE or a CONFIG node on command,
* usually via AUTH_ENABLE_NODE.
*
* RESTRICTED_NODE -- optional initial state.
*
* Similar to VIEW_NODE, but with fewer commands.
*
* AUTH_ENABLE_NODE -- state for authentication prior to ENABLE or
* CONFIG nodes.
*
* Can change up to ENABLE or CONFIG, but "end" does not return here,
* so VIEW is not treated as the parent of those nodes.
*
* These nodes have no parents and no children:
*
* "end" has no effect.
*
* "exit" means goto "EXIT_NODE".
*
* These nodes have no context of their own.
*
* * ENABLE -- general, but privileged, commands
*
* For all but VTY Terminal, these are the basic nodes. For VTY Terminal,
* may reach here by command from a VIEW node, but in may start here.
*
* There is currently only one ENABLE_NODE, but it would be possible to
* have more than one, and even one or more trees of such nodes.
*
* These nodes have no parents, except where they are descendants of
* other ENABLE nodes:
*
* "end" means goto parent ENABLE node, if any, otherwise do nothing.
*
* "exit" means goto parent ENABLE node, if any, otherwise goto EXIT_NODE.
*
* These nodes may have children: CONFIG or other ENABLE nodes.
*
* These nodes have no context of their own.
*
* The ENABLE nodes have the property that commands may run in ANY CONTEXT.
* In particular, all children of a given ENABLE node may execute all
* the commands in that node, implicitly and without changing node before
* hand (but the command may change node itself).
*
* * CONFIG -- general configuration commands
*
* Require the configuration symbol of power.
*
* CONFIG nodes are reached by command from ENABLE (or VIEW).
*
* There is currently only one CONFIG_NODE, but it would be possible to
* have more than one, and even one or more trees of such nodes.
*
* These nodes have parents, CONFIG or ENABLE nodes:
*
* "end" means goto parent (or grandparent etc) ENABLE node
*
* "exit" means goto parent node
*
* These nodes may have children: SPECIFIC or other CONFIG.
*
* These nodes have no context of their own.
*
* * SPECIFIC -- configuration nodes which may have their own context.
*
* Require the configuration symbol of power.
*
* SPECIFIC nodes are reached by command from CONFIG.
*
* There are many SPECIFIC nodes and trees of such nodes.
*
* These nodes have parents, CONFIG or other SPECIFIC nodes:
*
* "end" means goto ancestor ENABLE node (the immediate parent of the
* most senior CONFIG ancestor).
*
* "exit" means goto parent node
*
* These nodes may have children: other SPECIFIC nodes.
*
* These nodes may have context of their own, but the context of a parent
* node MUST be a subset of any descendant's. So that:
*
* * when moving down the tree (from parent to child) extra context
* (state) may be set/created -- usually by the command that changes
* the node -- provided the parent context is preserved.
*
* * when moving up the tree (from child to parent) nothing special need
* be done.
*
* NB: configuration is written out in the order of the underlying node numbers.
*/
enum node_type
{
NULL_NODE = 0, /* For when need "not a node" */
/* The SPECIAL nodes ---------------------------------------------------------
*/
MIN_SPECIAL_NODE = NULL_NODE + 1,
EXIT_NODE, /* Temporary node on the way to the door */
META_NODE, /* Temporary node for meta command execution */
MAX_SPECIAL_NODE = META_NODE,
/* The VIEW nodes ------------------------------------------------------------
*/
MIN_VIEW_NODE = MAX_SPECIAL_NODE + 1,
AUTH_NODE, /* VTY login -> VIEW_NODE */
RESTRICTED_NODE, /* if no login required, may use this node */
VIEW_NODE, /* aka user EXEC */
AUTH_ENABLE_NODE, /* enable login -> ENABLE_NODE/CONFIG_NODE */
MAX_VIEW_NODE = AUTH_ENABLE_NODE,
/* The ENABLE nodes-----------------------------------------------------------
*/
MIN_ENABLE_NODE = MAX_VIEW_NODE + 1,
ENABLE_NODE, /* aka privileged EXEC */
MAX_ENABLE_NODE = ENABLE_NODE,
/* Only the one, ATM */
/* The CONFIG nodes-----------------------------------------------------------
*/
MIN_CONFIG_NODE = MAX_ENABLE_NODE + 1,
CONFIG_NODE, /* aka global configuration mode */
MAX_CONFIG_NODE = CONFIG_NODE,
/* Only the one, ATM */
/* The SPECIFIC nodes---------------------------------------------------------
*/
MIN_SPECIFIC_NODE = MAX_CONFIG_NODE + 1,
SERVICE_NODE, /* unused ! */
DEBUG_NODE, /* debug config write only */
AAA_NODE, /* unused ! */
KEYCHAIN_NODE, /* see: keychain.c */
KEYCHAIN_KEY_NODE, /* see: keychain.c -- child of KEYCHAIN_NODE */
INTERFACE_NODE, /* interface commands */
ZEBRA_NODE, /* router zebra commands */
TABLE_NODE, /* rtm_table config write -- see zserv.c */
RIP_NODE, /* router rip commands */
RIPNG_NODE, /* router ripng commands */
BGP_NODE, /* router bgp commands */
BGP_VPNV4_NODE, /* address-family vpnv4 -- child of BGP_NODE */
BGP_IPV4_NODE, /* address-family ipv4 (unicast) -- child of BGP_NODE */
BGP_IPV4M_NODE, /* address-family ipv4 multicast -- child of BGP_NODE */
BGP_IPV6_NODE, /* address-family ipv6 (unicast) -- child of BGP_NODE */
BGP_IPV6M_NODE, /* address-family ipv6 multicast -- child of BGP_NODE */
OSPF_NODE, /* router ospf commands */
OSPF6_NODE, /* router ospf6 commands */
ISIS_NODE, /* router isis commands */
MASC_NODE, /* unused ! RFC 2909 Multicast Address-Set Claim */
IRDP_NODE, /* unused ! ICMP Router Discovery Protocol */
IP_NODE, /* zebra_ip_config write only -- see zebra_vty.c */
ACCESS_NODE, /* access list config write only -- see filter.c */
PREFIX_NODE, /* prefix list config write only -- see plist.c */
ACCESS_IPV6_NODE, /* access list config write only -- see filter.c */
PREFIX_IPV6_NODE, /* prefix list config write only -- see plist.c */
AS_LIST_NODE, /* AS list config write only -- see bgp_filter.c */
COMMUNITY_LIST_NODE, /* Community list config write only -- see bgp_vty.c */
RMAP_NODE, /* route-map commands */
SMUX_NODE, /* SNMP config write only -- see smux.c */
DUMP_NODE, /* BGP dump config write only -- see bgp_dump.c */
FORWARDING_NODE, /* forwarding config write -- see zserv.c */
PROTOCOL_NODE, /* protocol config write -- see zebra_vty.c */
VTY_NODE, /* line vty commands */
MAX_SPECIFIC_NODE = VTY_NODE,
/* All real nodes + the NULL_NODE are in the range MIN_NODE..MAX_NODE
* and the NULL_NODE == MIN_NODE.
*
* So any new real node MUST precede this.
*/
NUMBER_OF_NODES,
MIN_NODE = 0, /* unsigned value ! */
MAX_NODE = NUMBER_OF_NODES - 1,
} ;
typedef enum node_type node_type_t ;
CONFIRM((NULL_NODE == MIN_NODE) && (MIN_NODE == 0)) ;
/* We may assume:
*
* that: SPECIAL < VIEW < ENABLE < CONFIG < SPECIFIC
*
* and: there is nothing between, before or after
*
* and: (therefore) that everything >= MIN_CONFIG_NODE requires the
* configuration symbol of power.
*
* and: (therefore) that everything > MAX_CONFIG_NODE may have specific
* context.
*/
CONFIRM(MIN_SPECIAL_NODE == (MIN_NODE + 1)) ; /* First not NULL ! */
CONFIRM(MIN_VIEW_NODE == (MAX_SPECIAL_NODE + 1)) ;
CONFIRM(MIN_ENABLE_NODE == (MAX_VIEW_NODE + 1)) ;
CONFIRM(MIN_CONFIG_NODE == (MAX_ENABLE_NODE + 1)) ;
CONFIRM(MIN_SPECIFIC_NODE == (MAX_CONFIG_NODE + 1)) ;
CONFIRM(MAX_SPECIFIC_NODE == MAX_NODE) ;
/*------------------------------------------------------------------------------
* The daemons known to the command handling
*
* The "real" daemons are the ones known to vtysh !
*
* These ordinals specify the order in which daemons are called by vtysh.
*/
typedef enum DAEMON_ORD
{
BGPD_ORD = 0,
OSPFD_ORD = 1,
OSPF6D_ORD = 2,
ISISD_ORD = 3,
RIPD_ORD = 4,
RIPNGD_ORD = 5,
ZEBRA_ORD = 6,
DAEMON_COUNT = 7, /* Number of real daemons */
BASIC_ORD = 13, /* Basic "virtual daemon" */
VTYSH_ORD = 14, /* vtysh "virtual daemon" */
TERM_ORD = 15, /* magic marker */
DAEMON_INVALID_ORD,
DAEMON_MAX_ORD = DAEMON_INVALID_ORD - 1,
} daemon_ord_t ;
typedef enum DAEMON
{
DAEMON_NONE = 0,
ZEBRA = BIT(ZEBRA_ORD),
RIPD = BIT(RIPD_ORD),
RIPNGD = BIT(RIPNGD_ORD),
OSPFD = BIT(OSPFD_ORD),
OSPF6D = BIT(OSPF6D_ORD),
BGPD = BIT(BGPD_ORD),
ISISD = BIT(ISISD_ORD),
ALL_RDS = ZEBRA | RIPD | RIPNGD | OSPFD | OSPF6D | BGPD | ISISD,
RMAP_DS = ZEBRA | RIPD | RIPNGD | OSPFD | OSPF6D | BGPD,
INTERFACE_DS = ZEBRA | RIPD | RIPNGD | OSPFD | OSPF6D | ISISD,
BASIC_VD = BIT(BASIC_ORD),
VTYSH_VD = BIT(VTYSH_ORD),
ALL_VDS = BASIC_VD | VTYSH_VD,
TERM = BIT(TERM_ORD), /* magic marker bit */
} daemon_bit_t ;
typedef daemon_bit_t daemon_set_t ;
/*------------------------------------------------------------------------------
* Return values for command handling.
*
* NB: when a command is executed it may return CMD_SUCCESS, CMD_WARNING
* or CMD_ERROR.
*
* In all cases any output required (including any warning or error
* messages) must already have been output.
*
* CMD_WARNING will stop configuration reader, unless ignore warning
* option is set.
*
* CMD_ERROR will always stop the configuration reader.
*
* If there is no output and either CMD_WARNING or CMD_ERROR, then will
* output a general warning message.
*
* All other return codes are for use within the command handler.
*/
enum cmd_return_code
{
CMD_SUCCESS = 0, /* used generally */
/* Return codes suitable for command execution functions
*/
CMD_WARNING = 1, /* command: not 100% successful */
CMD_ERROR, /* command: failed badly */
/* Return codes from the command parser
*/
CMD_ERR_PARSING, /* parser: general parser error */
CMD_ERR_NO_MATCH, /* parser: command/argument not recognised */
CMD_ERR_AMBIGUOUS, /* parser: matched more than one command */
CMD_ERR_INCOMPLETE,
/* Return codes used in command loop
*/
CMD_STOP, /* loop: stop and close vty (final) */
CMD_CANCEL, /* loop: stop and close down to base
* vin/vout and discard output. */
/* Return codes from I/O layers
*/
CMD_HIATUS, /* I/O: enter hiatus because some vin/vout
* is not vf_open as required/expected
* or because some other attention is
* required. */
CMD_WAITING, /* I/O: waiting for more input */
CMD_IO_ERROR, /* I/O: error or time-out */
/* Meta values
*/
CMD_RET_COUNT, /* number of return codes */
CMD_RET_MIN = 0, /* unsigned value */
CMD_RET_MAX = CMD_RET_COUNT - 1
} ;
typedef enum cmd_return_code cmd_ret_t ;
/*------------------------------------------------------------------------------
* Structure for each node -- root of all commands for the node.
*
* See cmd_install_node().
*/
struct vty ; /* Forward reference */
struct cmd_node
{
const node_type_t node ; /* who we are */
const char const* name ; /* who we are as text */
daemon_set_t daemons ; /* restricted to this set of daemons */
const char const* prompt ; /* prompt string for vty
* NULL => no commands in this node */
bool config_to_vtysh ; /* configuration goes to vtysh ? */
bool installed ; /* set by cmd_install_node() */
int (*config_write) (struct vty*) ; /* configuration write function */
vector cmd_vector ; /* node's commands, if any. */
const bool parse_strict ; /* all of node's commands are "strict" */
bool executable ; /* node which may contain commands */
node_type_t parent ; /* parent when parsing commands */
node_type_t exit_to ; /* where to go on "exit" */
node_type_t end_to ; /* where to go on "end" or "^Z" */
} ;
typedef struct cmd_node cmd_node_t ;
typedef struct cmd_node* cmd_node ;
/*------------------------------------------------------------------------------
* Commands -- contents of the nodes' cmd_vector(s).
*
* A cmd_command is a static structure, which contains dynamic elements
* which are set when a command is installed. Note that is not uncommon for
* one cmd_command to appear in more than one node.
*
* The command attributes affect:
*
* * the parsing of the command -- in particular how the next_node is
* established.
*
* * whether the command is shown in help (or some forms of help if
* deprecated.
*
* * whether the command can be executed directly in the cli thread
* (avoiding having to wait for the cmd thread's attention -- this may be
* less useful now that all commands are treated a "priority" messages
* going into the cmd thread).
*
* If the command is marked CMD_ATTR_NODE, then the CMD_ATTR_MASK will
* extract the node_type_t that the command will set, if CMD_SUCCESS. This
* means that can parse commands without executing them.
*
* If the command is not marked CMD_ATTR_NODE, then the CMD_ATTR_MASK will
* extract the cmd_special_t value for the command -- which will be
* interesting if it isn't cmd_sp_simple.
*/
enum cmd_attr
{
CMD_ATTR_SIMPLE = 0,
CMD_ATTR_NODE = BIT(7), /* sets given node */
CMD_ATTR_MASK = CMD_ATTR_NODE - 1,
CMD_ATTR_DEPRECATED = BIT( 8),
CMD_ATTR_HIDDEN = BIT( 9), /* not shown in help */
CMD_ATTR_DIRECT = BIT(10), /* can run in cli thread */
CMD_ATTR_FIRST = BIT(11), /* a "first_config_command" */
};
typedef enum cmd_attr cmd_attr_t ;
CONFIRM(CMD_ATTR_MASK >= (cmd_attr_t)MAX_NODE) ;
/* Special commands, which require extra processing at parse time.
*/
enum cmd_special
{
cmd_sp_simple = 0,
cmd_sp_end,
cmd_sp_exit,
cmd_sp_enable,
cmd_sp_configure,
cmd_sp_max_plus_1,
cmd_sp_max = cmd_sp_max_plus_1 - 1
} ;
typedef enum cmd_special cmd_special_t ;
CONFIRM(CMD_ATTR_MASK >= (cmd_attr_t)cmd_sp_max) ;
/* Command functions and macros to define same */
struct cmd_command ;
typedef struct cmd_command cmd_command_t ;
typedef struct cmd_command* cmd_command ;
typedef const char* const argv_t[] ;
#define DEFUN_CMD_ARG_UNUSED __attribute__ ((unused))
#define DEFUN_CMD_FUNCTION(name) \
cmd_ret_t name(cmd_command self DEFUN_CMD_ARG_UNUSED, \
struct vty* vty DEFUN_CMD_ARG_UNUSED, \
int argc DEFUN_CMD_ARG_UNUSED, \
argv_t argv DEFUN_CMD_ARG_UNUSED)
typedef DEFUN_CMD_FUNCTION((cmd_function)) ;
/* The cmd_command structure itself */
struct cmd_item ; /* Defined in command_parse.h */
typedef struct cmd_item* cmd_item ;
struct cmd_command
{
const char* string ; /* Command specification by string. */
cmd_function* func ;
const char* doc ; /* Documentation of this command. */
daemon_set_t daemons ; /* Daemons this command applies to */
cmd_attr_t attr ; /* Command attributes */
vector items ; /* Vector of pointers to cmd_item(s) */
uint nt_min ; /* excluding [option](s) */
uint nt ; /* count of all items */
uint nt_max ; /* "infinite" if .vararg */
cmd_item vararg ; /* if there is a vararg item */
char* r_doc ; /* rendered documentation */
//char* config ; /* Configuration string */
//vector subconfig ; /* Sub configuration string */
} ;
/*------------------------------------------------------------------------------
* Structures for tables of commands to be installed
*
* NB: The order of entries in the cmd_install_table_item is FIXED, because
* the initialisers for hundreds of commands depend on this !
*
* The mechanism also depends on the initialiser setting unspecified fields
* to zero -- as per standard C.
*
* See notes on cmd_install_table()
*/
typedef const struct cmd_table_item
{
const node_type_t node ;
const cmd_command cmd ;
const daemon_set_t add_daemons ; /* local for command */
const daemon_set_t del_daemons ; /* local for command */
} cmd_table_body[], * cmd_table_item ;
struct cmd_table
{
cmd_table_item body ; /* pointer to body */
const daemon_set_t daemons ; /* global for table */
} ;
typedef const struct cmd_table cmd_table_t ;
typedef cmd_table_t cmd_table[] ;
/*------------------------------------------------------------------------------
* Where daemon uses pthreads, it must provide a second stage initialisation
* function -- see cmd_host_config_set() & vty_read_config()
*/
typedef void (*init_second_stage)(bool pthreaded) ;
#endif /* _ZEBRA_COMMAND_COMMON_H */
|