Merge branch 'queue/osr/vtysh-generic'

WARNING: Merge contains nontrivial fixups in vrf_cmd handling.

Conflicts:
	lib/if.c
	zebra/interface.c
This commit is contained in:
David Lamparter 2016-12-05 20:04:08 +01:00
commit 7ddcfca4fb
25 changed files with 255 additions and 367 deletions

View File

@ -1418,12 +1418,7 @@ isis_circuit_init ()
/* Install interface node */ /* Install interface node */
install_node (&interface_node, isis_interface_config_write); install_node (&interface_node, isis_interface_config_write);
install_element (CONFIG_NODE, &interface_cmd); if_cmd_init ();
install_element (CONFIG_NODE, &no_interface_cmd);
install_default (INTERFACE_NODE);
install_element (INTERFACE_NODE, &interface_desc_cmd);
install_element (INTERFACE_NODE, &no_interface_desc_cmd);
isis_vty_init (); isis_vty_init ();
} }

View File

@ -1618,14 +1618,7 @@ ldp_vty_if_init(void)
{ {
/* Install interface node. */ /* Install interface node. */
install_node (&interface_node, interface_config_write); install_node (&interface_node, interface_config_write);
if_cmd_init ();
install_element(CONFIG_NODE, &interface_cmd);
install_element(CONFIG_NODE, &no_interface_cmd);
install_default(INTERFACE_NODE);
/* "description" commands. */
install_element(INTERFACE_NODE, &interface_desc_cmd);
install_element(INTERFACE_NODE, &no_interface_desc_cmd);
} }
struct iface * struct iface *

View File

@ -39,7 +39,6 @@
#include "workqueue.h" #include "workqueue.h"
#include "vrf.h" #include "vrf.h"
#include "command_match.h" #include "command_match.h"
#include "command_parse.h"
#include "qobj.h" #include "qobj.h"
DEFINE_MTYPE( LIB, HOST, "Host config") DEFINE_MTYPE( LIB, HOST, "Host config")
@ -1050,6 +1049,13 @@ DEFUN (config_exit,
config_exit_cmd, config_exit_cmd,
"exit", "exit",
"Exit current mode and down to previous mode\n") "Exit current mode and down to previous mode\n")
{
cmd_exit (vty);
return CMD_SUCCESS;
}
void
cmd_exit (struct vty *vty)
{ {
switch (vty->node) switch (vty->node)
{ {
@ -1118,7 +1124,6 @@ DEFUN (config_exit,
default: default:
break; break;
} }
return CMD_SUCCESS;
} }
/* ALIAS_FIXME */ /* ALIAS_FIXME */
@ -1264,17 +1269,12 @@ permute (struct graph_node *start, struct vty *vty)
list_delete_node (position, listtail(position)); list_delete_node (position, listtail(position));
} }
/* Help display function for all node. */ int
DEFUN (config_list, cmd_list_cmds (struct vty *vty, int do_permute)
config_list_cmd,
"list [permutations]",
"Print command list\n"
"Print all possible command permutations\n")
{ {
struct cmd_node *node = vector_slot (cmdvec, vty->node); struct cmd_node *node = vector_slot (cmdvec, vty->node);
if ((strmatch (argv[0]->text, "list") && argc == 2) || if (do_permute)
(strmatch (argv[0]->text, "show") && argc == 3))
permute (vector_slot (node->cmdgraph->nodes, 0), vty); permute (vector_slot (node->cmdgraph->nodes, 0), vty);
else else
{ {
@ -1289,13 +1289,23 @@ DEFUN (config_list,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
/* Help display function for all node. */
DEFUN (config_list,
config_list_cmd,
"list [permutations]",
"Print command list\n"
"Print all possible command permutations\n")
{
return cmd_list_cmds (vty, argc == 2);
}
DEFUN (show_commandtree, DEFUN (show_commandtree,
show_commandtree_cmd, show_commandtree_cmd,
"show commandtree [permutations]", "show commandtree [permutations]",
SHOW_STR SHOW_STR
"Show command tree\n") "Show command tree\n")
{ {
return config_list (self, vty, argc, argv); return cmd_list_cmds (vty, argc == 3);
} }
/* Write current configuration into file. */ /* Write current configuration into file. */
@ -2352,10 +2362,8 @@ cmd_init (int terminal)
install_element (ENABLE_NODE, &config_logmsg_cmd); install_element (ENABLE_NODE, &config_logmsg_cmd);
install_default (CONFIG_NODE); install_default (CONFIG_NODE);
install_element (VIEW_NODE, &show_thread_cpu_cmd); thread_cmd_init ();
install_element (ENABLE_NODE, &clear_thread_cpu_cmd); workqueue_cmd_init ();
install_element (VIEW_NODE, &show_work_queues_cmd);
} }
install_element (CONFIG_NODE, &hostname_cmd); install_element (CONFIG_NODE, &hostname_cmd);
@ -2437,27 +2445,6 @@ copy_cmd_token (struct cmd_token *token)
return copy; return copy;
} }
void
del_cmd_element(struct cmd_element *cmd)
{
if (!cmd) return;
free ((char *) cmd->string);
free ((char *) cmd->doc);
free (cmd);
}
struct cmd_element *
copy_cmd_element(const struct cmd_element *cmd)
{
struct cmd_element *el = XMALLOC(MTYPE_CMD_TOKENS, sizeof (struct cmd_element));
el->string = cmd->string ? XSTRDUP(MTYPE_CMD_TOKENS, cmd->string) : NULL;
el->func = cmd->func;
el->doc = cmd->doc ? XSTRDUP(MTYPE_CMD_TOKENS, cmd->doc) : NULL;
el->daemon = cmd->daemon;
el->attr = cmd->attr;
return el;
}
void void
cmd_terminate () cmd_terminate ()
{ {

View File

@ -237,7 +237,7 @@ struct cmd_element
/* helper defines for end-user DEFUN* macros */ /* helper defines for end-user DEFUN* macros */
#define DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \ #define DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \
struct cmd_element cmdname = \ static struct cmd_element cmdname = \
{ \ { \
.string = cmdstr, \ .string = cmdstr, \
.func = funcname, \ .func = funcname, \
@ -414,12 +414,8 @@ extern int cmd_execute_command (vector, struct vty *, const struct cmd_element *
extern int cmd_execute_command_strict (vector, struct vty *, const struct cmd_element **); extern int cmd_execute_command_strict (vector, struct vty *, const struct cmd_element **);
extern void cmd_init (int); extern void cmd_init (int);
extern void cmd_terminate (void); extern void cmd_terminate (void);
extern void cmd_exit (struct vty *vty);
/* memory management for cmd_element */ extern int cmd_list_cmds (struct vty *vty, int do_permute);
void
del_cmd_element(struct cmd_element *);
struct cmd_element *
copy_cmd_element(const struct cmd_element *cmd);
/* memory management for cmd_token */ /* memory management for cmd_token */
struct cmd_token * struct cmd_token *
@ -429,12 +425,9 @@ del_cmd_token (struct cmd_token *);
struct cmd_token * struct cmd_token *
copy_cmd_token (struct cmd_token *); copy_cmd_token (struct cmd_token *);
extern void command_parse_format (struct graph *graph, struct cmd_element *cmd);
/* Export typical functions. */ /* Export typical functions. */
extern struct cmd_element config_end_cmd;
extern struct cmd_element config_exit_cmd;
extern struct cmd_element config_quit_cmd;
extern struct cmd_element config_help_cmd;
extern struct cmd_element config_list_cmd;
extern const char *host_config_get (void); extern const char *host_config_get (void);
extern void host_config_set (const char *); extern void host_config_set (const char *);

View File

@ -24,10 +24,7 @@
%{ %{
#include "command_parse.h" #include "command_parse.h"
#define YYSTYPE CMD_YYSTYPE
extern void set_lexer_string (const char *);
extern void cleanup_lexer (void);
YY_BUFFER_STATE buffer;
%} %}
WORD (\-|\+)?[a-z\*][-+_a-zA-Z0-9\*]* WORD (\-|\+)?[a-z\*][-+_a-zA-Z0-9\*]*
@ -45,27 +42,34 @@ RANGE \({NUMBER}[ ]?\-[ ]?{NUMBER}\)
%option nounput %option nounput
%option noinput %option noinput
%option outfile="command_lex.c" %option outfile="command_lex.c"
%option header-file="command_lex.h"
%option prefix="cmd_yy"
%option reentrant
%option bison-bridge
%% %%
[ /t] /* ignore whitespace */; [ /t] /* ignore whitespace */;
{WORD} {yylval.string = XSTRDUP(MTYPE_TMP, yytext); return WORD;} {WORD} {yylval->string = XSTRDUP(MTYPE_TMP, yytext); return WORD;}
{IPV4} {yylval.string = XSTRDUP(MTYPE_TMP, yytext); return IPV4;} {IPV4} {yylval->string = XSTRDUP(MTYPE_TMP, yytext); return IPV4;}
{IPV4_PREFIX} {yylval.string = XSTRDUP(MTYPE_TMP, yytext); return IPV4_PREFIX;} {IPV4_PREFIX} {yylval->string = XSTRDUP(MTYPE_TMP, yytext); return IPV4_PREFIX;}
{IPV6} {yylval.string = XSTRDUP(MTYPE_TMP, yytext); return IPV6;} {IPV6} {yylval->string = XSTRDUP(MTYPE_TMP, yytext); return IPV6;}
{IPV6_PREFIX} {yylval.string = XSTRDUP(MTYPE_TMP, yytext); return IPV6_PREFIX;} {IPV6_PREFIX} {yylval->string = XSTRDUP(MTYPE_TMP, yytext); return IPV6_PREFIX;}
{VARIABLE} {yylval.string = XSTRDUP(MTYPE_TMP, yytext); return VARIABLE;} {VARIABLE} {yylval->string = XSTRDUP(MTYPE_TMP, yytext); return VARIABLE;}
{RANGE} {yylval.string = XSTRDUP(MTYPE_TMP, yytext); return RANGE;} {RANGE} {yylval->string = XSTRDUP(MTYPE_TMP, yytext); return RANGE;}
. {return yytext[0];} . {return yytext[0];}
%% %%
void YY_BUFFER_STATE buffer;
set_lexer_string (const char *string)
void set_lexer_string (yyscan_t *scn, const char *string)
{ {
buffer = yy_scan_string (string); *scn = NULL;
yylex_init(scn);
buffer = yy_scan_string (string, *scn);
} }
void void cleanup_lexer (yyscan_t *scn)
cleanup_lexer ()
{ {
yy_delete_buffer (buffer); // yy_delete_buffer (buffer, *scn);
yylex_destroy(*scn);
} }

View File

@ -25,9 +25,17 @@
#include <zebra.h> #include <zebra.h>
#include "command_match.h" #include "command_match.h"
#include "command_parse.h"
#include "memory.h" #include "memory.h"
#ifdef TRACE_MATCHER
#define TM 1
#else
#define TM 0
#endif
#define trace_matcher(...) \
do { if (TM) fprintf (stderr, __VA_ARGS__); } while (0);
DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command Tokens") DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command Tokens")
/* matcher helper prototypes */ /* matcher helper prototypes */
@ -116,12 +124,12 @@ command_match (struct graph *cmdgraph,
assert (*el); assert (*el);
} }
#ifdef TRACE_MATCHER if (!*el) {
if (!*el) trace_matcher ("No match");
fprintf (stdout, "No match\n"); }
else else {
fprintf (stdout, "Matched command\n->string %s\n->desc %s\n", (*el)->string, (*el)->doc); trace_matcher ("Matched command\n->string %s\n->desc %s\n", (*el)->string, (*el)->doc);
#endif }
// free the leader token we alloc'd // free the leader token we alloc'd
XFREE (MTYPE_TMP, vector_slot (vvline, 0)); XFREE (MTYPE_TMP, vector_slot (vvline, 0));
@ -194,28 +202,26 @@ command_match_r (struct graph_node *start, vector vline, unsigned int n)
// get the current operating input token // get the current operating input token
char *input_token = vector_slot (vline, n); char *input_token = vector_slot (vline, n);
#ifdef TRACE_MATCHER trace_matcher ("\"%-20s\" matches \"%-30s\" ? ", input_token, token->text);
fprintf (stdout, "\"%-20s\" matches \"%-30s\" ? ", input_token, token->text);
enum match_type mt = match_token (token, input_token); enum match_type mt = match_token (token, input_token);
fprintf (stdout, "min: %d - ", minmatch); trace_matcher ("min: %d - ", minmatch);
switch (mt) switch (mt)
{ {
case trivial_match: case trivial_match:
fprintf (stdout, "trivial_match "); trace_matcher ("trivial_match ");
break; break;
case no_match: case no_match:
fprintf (stdout, "no_match "); trace_matcher ("no_match ");
break; break;
case partly_match: case partly_match:
fprintf (stdout, "partly_match "); trace_matcher ("partly_match ");
break; break;
case exact_match: case exact_match:
fprintf (stdout, "exact_match "); trace_matcher ("exact_match ");
break; break;
} }
if (mt >= minmatch) fprintf (stdout, " MATCH"); if (mt >= minmatch) { trace_matcher (" MATCH") };
fprintf (stdout, "\n"); trace_matcher ("\n");
#endif
// if we don't match this node, die // if we don't match this node, die
if (match_token (token, input_token) < minmatch) if (match_token (token, input_token) < minmatch)
@ -345,37 +351,35 @@ command_complete (struct graph *graph,
continue; continue;
enum match_type minmatch = min_match_level (token->type); enum match_type minmatch = min_match_level (token->type);
#ifdef TRACE_MATCHER trace_matcher ("\"%s\" matches \"%s\" (%d) ? ", input_token, token->text, token->type);
fprintf (stdout, "\"%s\" matches \"%s\" (%d) ? ", input_token, token->text, token->type);
#endif
switch (match_token (token, input_token)) switch (match_token (token, input_token))
{ {
case trivial_match: case trivial_match:
#ifdef TRACE_MATCHER trace_matcher ("trivial_match\n");
fprintf (stdout, "trivial_match\n"); assert(idx == vector_active (vline) - 1);
#endif listnode_add (next, gn);
break;
case partly_match: case partly_match:
#ifdef TRACE_MATCHER trace_matcher ("partly_match\n");
fprintf (stdout, "partly_match\n"); // last token on line is partial and
#endif // not a space
if (idx == vector_active (vline) - 1) if (idx == vector_active (vline) - 1)
{ {
listnode_add (next, gn); listnode_add (next, gn);
break; break;
} }
if (minmatch > partly_match) if (minmatch <= partly_match)
break; add_nexthops (next, gn);
break;
case exact_match: case exact_match:
#ifdef TRACE_MATCHER trace_matcher ("exact_match\n");
fprintf (stdout, "exact_match\n");
#endif
add_nexthops (next, gn); add_nexthops (next, gn);
listnode_add (next, gn);
break; break;
default: default:
#ifdef TRACE_MATCHER trace_matcher ("no_match\n");
fprintf (stdout, "no_match\n");
#endif
break; break;
} }
} }
@ -855,14 +859,9 @@ match_word (struct cmd_token *token, const char *word)
return no_match; return no_match;
} }
#define VARIABLE_ALPHABET \
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890:/._-"
static enum match_type static enum match_type
match_variable (struct cmd_token *token, const char *word) match_variable (struct cmd_token *token, const char *word)
{ {
assert (token->type == VARIABLE_TKN); assert (token->type == VARIABLE_TKN);
return exact_match;
return strlen (word) == strspn(word, VARIABLE_ALPHABET) ?
exact_match : no_match;
} }

View File

@ -23,10 +23,18 @@
*/ */
%{ %{
typedef union CMD_YYSTYPE CMD_YYSTYPE;
#define YYSTYPE CMD_YYSTYPE
#include "command_lex.h"
// compile with debugging facilities // compile with debugging facilities
#define YYDEBUG 1 #define YYDEBUG 1
%} %}
%define api.pure full
%define api.prefix {cmd_yy}
/* names for generated header and parser files */ /* names for generated header and parser files */
%defines "command_parse.h" %defines "command_parse.h"
%output "command_parse.c" %output "command_parse.c"
@ -39,21 +47,24 @@
#include "log.h" #include "log.h"
#include "graph.h" #include "graph.h"
extern int struct parser_ctx {
yylex (void); yyscan_t scanner;
extern void struct cmd_element *el;
set_lexer_string (const char *);
extern void struct graph *graph;
cleanup_lexer (void); struct graph_node *currnode, *startnode;
/* pointers to copy of command docstring */
char *docstr_start, *docstr;
};
extern void set_lexer_string (yyscan_t *scn, const char *string);
extern void cleanup_lexer (yyscan_t *scn);
} }
/* functionality this unit exports */ /* functionality this unit exports */
%code provides { %code provides {
void
command_parse_format (struct graph *, struct cmd_element *);
/* maximum length of a number, lexer will not match anything longer */ /* maximum length of a number, lexer will not match anything longer */
#define DECIMAL_STRLEN_MAX 20 #define DECIMAL_STRLEN_MAX 20
} }
@ -91,23 +102,19 @@
%type <subgraph> compound_token %type <subgraph> compound_token
%code { %code {
/* bison declarations */ /* bison declarations */
void void
yyerror (struct graph *, struct cmd_element *el, char const *msg); cmd_yyerror (struct parser_ctx *ctx, char const *msg);
/* subgraph semantic value */ /* subgraph semantic value */
struct subgraph { struct subgraph {
struct graph_node *start, *end; struct graph_node *start, *end;
}; };
struct graph_node *currnode, *startnode;
/* pointers to copy of command docstring */
char *docstr_start, *docstr;
/* helper functions for parser */ /* helper functions for parser */
static char * static char *
doc_next (struct cmd_element *); doc_next (struct parser_ctx *ctx);
static struct graph_node * static struct graph_node *
node_adjacent (struct graph_node *, struct graph_node *); node_adjacent (struct graph_node *, struct graph_node *);
@ -119,47 +126,45 @@
cmp_token (struct cmd_token *, struct cmd_token *); cmp_token (struct cmd_token *, struct cmd_token *);
static struct graph_node * static struct graph_node *
new_token_node (struct graph *, new_token_node (struct parser_ctx *,
enum cmd_token_type type, enum cmd_token_type type,
u_char attr, char *text, char *text,
char *doc); char *doc);
static void static void
terminate_graph (struct graph *, terminate_graph (struct parser_ctx *ctx,
struct graph_node *, struct graph_node *);
struct cmd_element *);
static void static void
cleanup (void); cleanup (struct parser_ctx *ctx);
#define scanner ctx->scanner
} }
/* yyparse parameters */ /* yyparse parameters */
%parse-param { struct graph *graph } %lex-param {yyscan_t scanner}
%parse-param { struct cmd_element *el } %parse-param {struct parser_ctx *ctx}
/* called automatically before yyparse */ /* called automatically before yyparse */
%initial-action { %initial-action {
/* clear state pointers */ /* clear state pointers */
currnode = startnode = NULL; ctx->currnode = ctx->startnode = NULL;
startnode = vector_slot (graph->nodes, 0); ctx->startnode = vector_slot (ctx->graph->nodes, 0);
/* set string to parse */
set_lexer_string (el->string);
/* copy docstring and keep a pointer to the copy */ /* copy docstring and keep a pointer to the copy */
if (el->doc) if (ctx->el->doc)
{ {
// allocate a new buffer, making room for a flag // allocate a new buffer, making room for a flag
size_t length = (size_t) strlen (el->doc) + 2; size_t length = (size_t) strlen (ctx->el->doc) + 2;
docstr = malloc (length); ctx->docstr = malloc (length);
memcpy (docstr, el->doc, strlen (el->doc)); memcpy (ctx->docstr, ctx->el->doc, strlen (ctx->el->doc));
// set the flag so doc_next knows when to print a warning // set the flag so doc_next knows when to print a warning
docstr[length - 2] = 0x03; ctx->docstr[length - 2] = 0x03;
// null terminate // null terminate
docstr[length - 1] = 0x00; ctx->docstr[length - 1] = 0x00;
} }
docstr_start = docstr; ctx->docstr_start = ctx->docstr;
} }
%% %%
@ -168,32 +173,32 @@ start:
sentence_root cmd_token_seq sentence_root cmd_token_seq
{ {
// tack on the command element // tack on the command element
terminate_graph (graph, currnode, el); terminate_graph (ctx, ctx->currnode);
} }
| sentence_root cmd_token_seq placeholder_token '.' '.' '.' | sentence_root cmd_token_seq placeholder_token '.' '.' '.'
{ {
if ((currnode = add_edge_dedup (currnode, $3)) != $3) if ((ctx->currnode = add_edge_dedup (ctx->currnode, $3)) != $3)
graph_delete_node (graph, $3); graph_delete_node (ctx->graph, $3);
// adding a node as a child of itself accepts any number // adding a node as a child of itself accepts any number
// of the same token, which is what we want for variadics // of the same token, which is what we want for variadics
add_edge_dedup (currnode, currnode); add_edge_dedup (ctx->currnode, ctx->currnode);
// tack on the command element // tack on the command element
terminate_graph (graph, currnode, el); terminate_graph (ctx, ctx->currnode);
} }
; ;
sentence_root: WORD sentence_root: WORD
{ {
struct graph_node *root = struct graph_node *root =
new_token_node (graph, WORD_TKN, el->attr, strdup ($1), doc_next(el)); new_token_node (ctx, WORD_TKN, strdup ($1), doc_next(ctx));
if ((currnode = add_edge_dedup (startnode, root)) != root) if ((ctx->currnode = add_edge_dedup (ctx->startnode, root)) != root)
graph_delete_node (graph, root); graph_delete_node (ctx->graph, root);
free ($1); free ($1);
$$ = currnode; $$ = ctx->currnode;
} }
; ;
@ -205,13 +210,13 @@ cmd_token_seq:
cmd_token: cmd_token:
simple_token simple_token
{ {
if ((currnode = add_edge_dedup (currnode, $1)) != $1) if ((ctx->currnode = add_edge_dedup (ctx->currnode, $1)) != $1)
graph_delete_node (graph, $1); graph_delete_node (ctx->graph, $1);
} }
| compound_token | compound_token
{ {
graph_add_edge (currnode, $1->start); graph_add_edge (ctx->currnode, $1->start);
currnode = $1->end; ctx->currnode = $1->end;
free ($1); free ($1);
} }
; ;
@ -228,7 +233,7 @@ compound_token:
literal_token: WORD literal_token: WORD
{ {
$$ = new_token_node (graph, WORD_TKN, el->attr, strdup($1), doc_next(el)); $$ = new_token_node (ctx, WORD_TKN, strdup($1), doc_next(ctx));
free ($1); free ($1);
} }
; ;
@ -236,32 +241,32 @@ literal_token: WORD
placeholder_token: placeholder_token:
IPV4 IPV4
{ {
$$ = new_token_node (graph, IPV4_TKN, el->attr, strdup($1), doc_next(el)); $$ = new_token_node (ctx, IPV4_TKN, strdup($1), doc_next(ctx));
free ($1); free ($1);
} }
| IPV4_PREFIX | IPV4_PREFIX
{ {
$$ = new_token_node (graph, IPV4_PREFIX_TKN, el->attr, strdup($1), doc_next(el)); $$ = new_token_node (ctx, IPV4_PREFIX_TKN, strdup($1), doc_next(ctx));
free ($1); free ($1);
} }
| IPV6 | IPV6
{ {
$$ = new_token_node (graph, IPV6_TKN, el->attr, strdup($1), doc_next(el)); $$ = new_token_node (ctx, IPV6_TKN, strdup($1), doc_next(ctx));
free ($1); free ($1);
} }
| IPV6_PREFIX | IPV6_PREFIX
{ {
$$ = new_token_node (graph, IPV6_PREFIX_TKN, el->attr, strdup($1), doc_next(el)); $$ = new_token_node (ctx, IPV6_PREFIX_TKN, strdup($1), doc_next(ctx));
free ($1); free ($1);
} }
| VARIABLE | VARIABLE
{ {
$$ = new_token_node (graph, VARIABLE_TKN, el->attr, strdup($1), doc_next(el)); $$ = new_token_node (ctx, VARIABLE_TKN, strdup($1), doc_next(ctx));
free ($1); free ($1);
} }
| RANGE | RANGE
{ {
$$ = new_token_node (graph, RANGE_TKN, el->attr, strdup($1), doc_next(el)); $$ = new_token_node (ctx, RANGE_TKN, strdup($1), doc_next(ctx));
struct cmd_token *token = $$->data; struct cmd_token *token = $$->data;
// get the numbers out // get the numbers out
@ -271,7 +276,7 @@ placeholder_token:
token->max = strtoll (yylval.string, &yylval.string, 10); token->max = strtoll (yylval.string, &yylval.string, 10);
// validate range // validate range
if (token->min > token->max) yyerror (graph, el, "Invalid range."); if (token->min > token->max) cmd_yyerror (ctx, "Invalid range.");
free ($1); free ($1);
} }
@ -280,8 +285,8 @@ placeholder_token:
selector: '<' selector_seq_seq '>' selector: '<' selector_seq_seq '>'
{ {
$$ = malloc (sizeof (struct subgraph)); $$ = malloc (sizeof (struct subgraph));
$$->start = new_token_node (graph, SELECTOR_TKN, el->attr, NULL, NULL); $$->start = new_token_node (ctx, SELECTOR_TKN, NULL, NULL);
$$->end = new_token_node (graph, NUL_TKN, el->attr, NULL, NULL); $$->end = new_token_node (ctx, NUL_TKN, NULL, NULL);
for (unsigned int i = 0; i < vector_active ($2->start->to); i++) for (unsigned int i = 0; i < vector_active ($2->start->to); i++)
{ {
struct graph_node *sn = vector_slot ($2->start->to, i), struct graph_node *sn = vector_slot ($2->start->to, i),
@ -289,8 +294,8 @@ selector: '<' selector_seq_seq '>'
graph_add_edge ($$->start, sn); graph_add_edge ($$->start, sn);
graph_add_edge (en, $$->end); graph_add_edge (en, $$->end);
} }
graph_delete_node (graph, $2->start); graph_delete_node (ctx->graph, $2->start);
graph_delete_node (graph, $2->end); graph_delete_node (ctx->graph, $2->end);
free ($2); free ($2);
}; };
@ -298,8 +303,8 @@ selector_seq_seq:
selector_seq_seq '|' selector_token_seq selector_seq_seq '|' selector_token_seq
{ {
$$ = malloc (sizeof (struct subgraph)); $$ = malloc (sizeof (struct subgraph));
$$->start = graph_new_node (graph, NULL, NULL); $$->start = graph_new_node (ctx->graph, NULL, NULL);
$$->end = graph_new_node (graph, NULL, NULL); $$->end = graph_new_node (ctx->graph, NULL, NULL);
// link in last sequence // link in last sequence
graph_add_edge ($$->start, $3->start); graph_add_edge ($$->start, $3->start);
@ -312,16 +317,16 @@ selector_seq_seq:
graph_add_edge ($$->start, sn); graph_add_edge ($$->start, sn);
graph_add_edge (en, $$->end); graph_add_edge (en, $$->end);
} }
graph_delete_node (graph, $1->start); graph_delete_node (ctx->graph, $1->start);
graph_delete_node (graph, $1->end); graph_delete_node (ctx->graph, $1->end);
free ($1); free ($1);
free ($3); free ($3);
} }
| selector_token_seq '|' selector_token_seq | selector_token_seq '|' selector_token_seq
{ {
$$ = malloc (sizeof (struct subgraph)); $$ = malloc (sizeof (struct subgraph));
$$->start = graph_new_node (graph, NULL, NULL); $$->start = graph_new_node (ctx->graph, NULL, NULL);
$$->end = graph_new_node (graph, NULL, NULL); $$->end = graph_new_node (ctx->graph, NULL, NULL);
graph_add_edge ($$->start, $1->start); graph_add_edge ($$->start, $1->start);
graph_add_edge ($1->end, $$->end); graph_add_edge ($1->end, $$->end);
graph_add_edge ($$->start, $3->start); graph_add_edge ($$->start, $3->start);
@ -363,8 +368,8 @@ option: '[' option_token_seq ']'
{ {
// make a new option // make a new option
$$ = malloc (sizeof (struct subgraph)); $$ = malloc (sizeof (struct subgraph));
$$->start = new_token_node (graph, OPTION_TKN, el->attr, NULL, NULL); $$->start = new_token_node (ctx, OPTION_TKN, NULL, NULL);
$$->end = new_token_node (graph, NUL_TKN, el->attr, NULL, NULL); $$->end = new_token_node (ctx, NUL_TKN, NULL, NULL);
// add a path through the sequence to the end // add a path through the sequence to the end
graph_add_edge ($$->start, $2->start); graph_add_edge ($$->start, $2->start);
graph_add_edge ($2->end, $$->end); graph_add_edge ($2->end, $$->end);
@ -398,72 +403,77 @@ option_token:
%% %%
#undef scanner
void void
command_parse_format (struct graph *graph, struct cmd_element *cmd) command_parse_format (struct graph *graph, struct cmd_element *cmd)
{ {
struct parser_ctx ctx = { .graph = graph, .el = cmd };
// set to 1 to enable parser traces // set to 1 to enable parser traces
yydebug = 0; yydebug = 0;
set_lexer_string (&ctx.scanner, cmd->string);
// parse command into DFA // parse command into DFA
yyparse (graph, cmd); cmd_yyparse (&ctx);
/* cleanup lexer */
cleanup_lexer (&ctx.scanner);
// cleanup // cleanup
cleanup (); cleanup (&ctx);
} }
/* parser helper functions */ /* parser helper functions */
void void
yyerror (struct graph *graph, struct cmd_element *el, char const *msg) yyerror (struct parser_ctx *ctx, char const *msg)
{ {
zlog_err ("%s: FATAL parse error: %s", __func__, msg); zlog_err ("%s: FATAL parse error: %s", __func__, msg);
zlog_err ("while parsing this command definition: \n\t%s\n", el->string); zlog_err ("while parsing this command definition: \n\t%s\n", ctx->el->string);
//exit(EXIT_FAILURE); //exit(EXIT_FAILURE);
} }
static void static void
cleanup() cleanup (struct parser_ctx *ctx)
{ {
/* free resources */ /* free resources */
free (docstr_start); free (ctx->docstr_start);
/* cleanup lexer */
cleanup_lexer ();
/* clear state pointers */ /* clear state pointers */
currnode = NULL; ctx->currnode = NULL;
docstr_start = docstr = NULL; ctx->docstr_start = ctx->docstr = NULL;
} }
static void static void
terminate_graph (struct graph *graph, struct graph_node *finalnode, terminate_graph (struct parser_ctx *ctx, struct graph_node *finalnode)
struct cmd_element *element)
{ {
// end of graph should look like this // end of graph should look like this
// * -> finalnode -> END_TKN -> cmd_element // * -> finalnode -> END_TKN -> cmd_element
struct cmd_element *element = ctx->el;
struct graph_node *end_token_node = struct graph_node *end_token_node =
new_token_node (graph, new_token_node (ctx,
END_TKN, END_TKN,
element->attr,
strdup (CMD_CR_TEXT), strdup (CMD_CR_TEXT),
strdup ("")); strdup (""));
struct graph_node *end_element_node = struct graph_node *end_element_node =
graph_new_node (graph, element, (void (*)(void *)) &del_cmd_element); graph_new_node (ctx->graph, element, NULL);
if (node_adjacent (finalnode, end_token_node)) if (node_adjacent (finalnode, end_token_node))
yyerror (graph, element, "Duplicate command."); cmd_yyerror (ctx, "Duplicate command.");
graph_add_edge (finalnode, end_token_node); graph_add_edge (finalnode, end_token_node);
graph_add_edge (end_token_node, end_element_node); graph_add_edge (end_token_node, end_element_node);
} }
static char * static char *
doc_next (struct cmd_element *el) doc_next (struct parser_ctx *ctx)
{ {
const char *piece = docstr ? strsep (&docstr, "\n") : ""; const char *piece = ctx->docstr ? strsep (&ctx->docstr, "\n") : "";
if (*piece == 0x03) if (*piece == 0x03)
{ {
zlog_debug ("Ran out of docstring while parsing '%s'", el->string); zlog_debug ("Ran out of docstring while parsing '%s'", ctx->el->string);
piece = ""; piece = "";
} }
@ -471,11 +481,11 @@ doc_next (struct cmd_element *el)
} }
static struct graph_node * static struct graph_node *
new_token_node (struct graph *graph, enum cmd_token_type type, new_token_node (struct parser_ctx *ctx, enum cmd_token_type type,
u_char attr, char *text, char *doc) char *text, char *doc)
{ {
struct cmd_token *token = new_cmd_token (type, attr, text, doc); struct cmd_token *token = new_cmd_token (type, ctx->el->attr, text, doc);
return graph_new_node (graph, token, (void (*)(void *)) &del_cmd_token); return graph_new_node (ctx->graph, token, (void (*)(void *)) &del_cmd_token);
} }
/** /**

View File

@ -827,6 +827,17 @@ DEFUN_NOSH (no_interface,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
void
if_cmd_init (void)
{
install_element (CONFIG_NODE, &interface_cmd);
install_element (CONFIG_NODE, &no_interface_cmd);
install_default (INTERFACE_NODE);
install_element (INTERFACE_NODE, &interface_desc_cmd);
install_element (INTERFACE_NODE, &no_interface_desc_cmd);
}
/* For debug purpose. */ /* For debug purpose. */
DEFUN (show_address, DEFUN (show_address,
show_address_cmd, show_address_cmd,

View File

@ -447,6 +447,7 @@ extern int if_is_pointopoint (struct interface *);
extern int if_is_multicast (struct interface *); extern int if_is_multicast (struct interface *);
extern void if_add_hook (int, int (*)(struct interface *)); extern void if_add_hook (int, int (*)(struct interface *));
extern void if_init (struct list **); extern void if_init (struct list **);
extern void if_cmd_init (void);
extern void if_terminate (struct list **); extern void if_terminate (struct list **);
extern void if_dump_all (void); extern void if_dump_all (void);
extern const char *if_flag_dump(unsigned long); extern const char *if_flag_dump(unsigned long);
@ -485,19 +486,4 @@ struct nbr_connected *nbr_connected_check (struct interface *, struct prefix *);
struct if_link_params *if_link_params_get (struct interface *); struct if_link_params *if_link_params_get (struct interface *);
void if_link_params_free (struct interface *); void if_link_params_free (struct interface *);
/* Exported variables. */
extern struct cmd_element interface_desc_cmd;
extern struct cmd_element no_interface_desc_cmd;
extern struct cmd_element interface_cmd;
extern struct cmd_element no_interface_cmd;
extern struct cmd_element interface_vrf_cmd;
extern struct cmd_element no_interface_vrf_cmd;
extern struct cmd_element interface_pseudo_cmd;
extern struct cmd_element no_interface_pseudo_cmd;
extern struct cmd_element show_address_cmd;
extern struct cmd_element show_address_vrf_cmd;
extern struct cmd_element show_address_vrf_all_cmd;
extern struct cmd_element vrf_cmd;
extern struct cmd_element no_vrf_cmd;
#endif /* _ZEBRA_IF_H */ #endif /* _ZEBRA_IF_H */

View File

@ -423,6 +423,13 @@ DEFUN (clear_thread_cpu,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
void
thread_cmd_init (void)
{
install_element (VIEW_NODE, &show_thread_cpu_cmd);
install_element (ENABLE_NODE, &clear_thread_cpu_cmd);
}
static int static int
thread_timer_cmp(void *a, void *b) thread_timer_cmp(void *a, void *b)
{ {

View File

@ -244,8 +244,7 @@ extern void thread_set_yield_time (struct thread *, unsigned long);
/* Internal libzebra exports */ /* Internal libzebra exports */
extern void thread_getrusage (RUSAGE_T *); extern void thread_getrusage (RUSAGE_T *);
extern struct cmd_element show_thread_cpu_cmd; extern void thread_cmd_init (void);
extern struct cmd_element clear_thread_cpu_cmd;
/* replacements for the system gettimeofday(), clock_gettime() and /* replacements for the system gettimeofday(), clock_gettime() and
* time() functions, providing support for non-decrementing clock on * time() functions, providing support for non-decrementing clock on

View File

@ -531,6 +531,13 @@ DEFUN_NOSH (no_vrf,
} }
struct cmd_node vrf_node =
{
VRF_NODE,
"%s(config-vrf)# ",
1
};
/* /*
* Debug CLI for vrf's * Debug CLI for vrf's
*/ */
@ -582,7 +589,13 @@ vrf_install_commands (void)
install_element (ENABLE_NODE, &vrf_debug_cmd); install_element (ENABLE_NODE, &vrf_debug_cmd);
install_element (CONFIG_NODE, &no_vrf_debug_cmd); install_element (CONFIG_NODE, &no_vrf_debug_cmd);
install_element (ENABLE_NODE, &no_vrf_debug_cmd); install_element (ENABLE_NODE, &no_vrf_debug_cmd);
}
void
vrf_cmd_init (int (*writefunc)(struct vty *vty))
{
install_element (CONFIG_NODE, &vrf_cmd); install_element (CONFIG_NODE, &vrf_cmd);
install_element (CONFIG_NODE, &no_vrf_cmd); install_element (CONFIG_NODE, &no_vrf_cmd);
install_node (&vrf_node, writefunc);
install_default (VRF_NODE);
} }

View File

@ -26,6 +26,7 @@
#include "openbsd-tree.h" #include "openbsd-tree.h"
#include "linklist.h" #include "linklist.h"
#include "qobj.h" #include "qobj.h"
#include "vty.h"
/* The default NS ID */ /* The default NS ID */
#define NS_DEFAULT 0 #define NS_DEFAULT 0
@ -171,6 +172,8 @@ extern int vrf_bitmap_check (vrf_bitmap_t, vrf_id_t);
extern void vrf_init (void); extern void vrf_init (void);
extern void vrf_terminate (void); extern void vrf_terminate (void);
extern void vrf_cmd_init (int (*writefunc)(struct vty *vty));
/* /*
* VRF utilities * VRF utilities
*/ */

View File

@ -715,7 +715,7 @@ static void
vty_down_level (struct vty *vty) vty_down_level (struct vty *vty)
{ {
vty_out (vty, "%s", VTY_NEWLINE); vty_out (vty, "%s", VTY_NEWLINE);
(*config_exit_cmd.func)(NULL, vty, 0, NULL); cmd_exit (vty);
vty_prompt (vty); vty_prompt (vty);
vty->cp = 0; vty->cp = 0;
} }

View File

@ -222,6 +222,12 @@ DEFUN (show_work_queues,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
void
workqueue_cmd_init (void)
{
install_element (VIEW_NODE, &show_work_queues_cmd);
}
/* 'plug' a queue: Stop it from being scheduled, /* 'plug' a queue: Stop it from being scheduled,
* ie: prevent the queue from draining. * ie: prevent the queue from draining.
*/ */

View File

@ -129,5 +129,7 @@ bool work_queue_is_scheduled (struct work_queue *);
/* Helpers, exported for thread.c and command.c */ /* Helpers, exported for thread.c and command.c */
extern int work_queue_run (struct thread *); extern int work_queue_run (struct thread *);
extern struct cmd_element show_work_queues_cmd;
extern void workqueue_cmd_init (void);
#endif /* _QUAGGA_WORK_QUEUE_H */ #endif /* _QUAGGA_WORK_QUEUE_H */

View File

@ -1845,15 +1845,12 @@ ospf6_interface_init (void)
{ {
/* Install interface node. */ /* Install interface node. */
install_node (&interface_node, config_write_ospf6_interface); install_node (&interface_node, config_write_ospf6_interface);
if_cmd_init ();
install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd); install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd); install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd); install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd);
install_element (CONFIG_NODE, &interface_cmd);
install_default (INTERFACE_NODE);
install_element (INTERFACE_NODE, &interface_desc_cmd);
install_element (INTERFACE_NODE, &no_interface_desc_cmd);
install_element (INTERFACE_NODE, &ipv6_ospf6_cost_cmd); install_element (INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
install_element (INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd); install_element (INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
install_element (INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd); install_element (INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);

View File

@ -9255,14 +9255,7 @@ ospf_vty_if_init (void)
{ {
/* Install interface node. */ /* Install interface node. */
install_node (&interface_node, config_write_interface); install_node (&interface_node, config_write_interface);
if_cmd_init ();
install_element (CONFIG_NODE, &interface_cmd);
install_element (CONFIG_NODE, &no_interface_cmd);
install_default (INTERFACE_NODE);
/* "description" commands. */
install_element (INTERFACE_NODE, &interface_desc_cmd);
install_element (INTERFACE_NODE, &no_interface_desc_cmd);
/* "ip ospf authentication" commands. */ /* "ip ospf authentication" commands. */
install_element (INTERFACE_NODE, &ip_ospf_authentication_args_addr_cmd); install_element (INTERFACE_NODE, &ip_ospf_authentication_args_addr_cmd);

View File

@ -1527,47 +1527,6 @@ static void clear_interfaces()
clear_pim_interfaces(); clear_pim_interfaces();
} }
DEFUN (pim_interface,
pim_interface_cmd,
"interface IFNAME",
"Select an interface to configure\n"
"Interface's name\n")
{
int idx_ifname = 1;
struct interface *ifp;
const char *ifname = argv[idx_ifname]->arg;
size_t sl;
sl = strlen(ifname);
if (sl > INTERFACE_NAMSIZ) {
vty_out(vty, "%% Interface name %s is invalid: length exceeds "
"%d characters%s",
ifname, INTERFACE_NAMSIZ, VTY_NEWLINE);
return CMD_WARNING;
}
ifp = if_lookup_by_name_len(ifname, sl);
if (!ifp) {
vty_out(vty, "%% Interface %s does not exist%s", ifname, VTY_NEWLINE);
/* Returning here would prevent pimd from booting when there are
interface commands in pimd.conf, since all interfaces are
unknown at pimd boot time (the zebra daemon has not been
contacted for interface discovery). */
ifp = if_get_by_name_len(ifname, sl);
if (!ifp) {
vty_out(vty, "%% Could not create interface %s%s", ifname, VTY_NEWLINE);
return CMD_WARNING;
}
}
vty->index = ifp;
vty->node = INTERFACE_NODE;
return CMD_SUCCESS;
}
DEFUN (clear_ip_interfaces, DEFUN (clear_ip_interfaces,
clear_ip_interfaces_cmd, clear_ip_interfaces_cmd,
"clear ip interfaces", "clear ip interfaces",
@ -4832,6 +4791,7 @@ void pim_cmd_init()
{ {
install_node (&pim_global_node, pim_global_config_write); /* PIM_NODE */ install_node (&pim_global_node, pim_global_config_write); /* PIM_NODE */
install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */ install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */
if_cmd_init ();
install_element (CONFIG_NODE, &ip_multicast_routing_cmd); install_element (CONFIG_NODE, &ip_multicast_routing_cmd);
install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd); install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
@ -4839,14 +4799,7 @@ void pim_cmd_init()
install_element (CONFIG_NODE, &no_ip_pim_rp_cmd); install_element (CONFIG_NODE, &no_ip_pim_rp_cmd);
install_element (CONFIG_NODE, &ip_ssmpingd_cmd); install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd); install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd);
#if 0
install_element (CONFIG_NODE, &interface_cmd); /* from if.h */
#else
install_element (CONFIG_NODE, &pim_interface_cmd);
#endif
install_element (CONFIG_NODE, &no_interface_cmd); /* from if.h */
install_default (INTERFACE_NODE);
install_element (INTERFACE_NODE, &interface_ip_igmp_cmd); install_element (INTERFACE_NODE, &interface_ip_igmp_cmd);
install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd); install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd);
install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd); install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd);

View File

@ -2051,13 +2051,9 @@ rip_if_init (void)
/* Install interface node. */ /* Install interface node. */
install_node (&interface_node, rip_interface_config_write); install_node (&interface_node, rip_interface_config_write);
if_cmd_init ();
/* Install commands. */ /* Install commands. */
install_element (CONFIG_NODE, &interface_cmd);
install_element (CONFIG_NODE, &no_interface_cmd);
install_default (INTERFACE_NODE);
install_element (INTERFACE_NODE, &interface_desc_cmd);
install_element (INTERFACE_NODE, &no_interface_desc_cmd);
install_element (RIP_NODE, &rip_network_cmd); install_element (RIP_NODE, &rip_network_cmd);
install_element (RIP_NODE, &no_rip_network_cmd); install_element (RIP_NODE, &no_rip_network_cmd);
install_element (RIP_NODE, &rip_neighbor_cmd); install_element (RIP_NODE, &rip_neighbor_cmd);

View File

@ -1190,13 +1190,7 @@ ripng_if_init ()
/* Install interface node. */ /* Install interface node. */
install_node (&interface_node, interface_config_write); install_node (&interface_node, interface_config_write);
if_cmd_init ();
/* Install commands. */
install_element (CONFIG_NODE, &interface_cmd);
install_element (CONFIG_NODE, &no_interface_cmd);
install_default (INTERFACE_NODE);
install_element (INTERFACE_NODE, &interface_desc_cmd);
install_element (INTERFACE_NODE, &no_interface_desc_cmd);
install_element (RIPNG_NODE, &ripng_network_cmd); install_element (RIPNG_NODE, &ripng_network_cmd);
install_element (RIPNG_NODE, &no_ripng_network_cmd); install_element (RIPNG_NODE, &no_ripng_network_cmd);

View File

@ -23,7 +23,6 @@
#include "command.h" #include "command.h"
#include "graph.h" #include "graph.h"
#include "command_parse.h"
#include "vector.h" #include "vector.h"
#define USAGE "usage: permutations <cmdstr>" #define USAGE "usage: permutations <cmdstr>"

View File

@ -2796,6 +2796,15 @@ DEFUN (vtysh_start_zsh,
} }
#endif #endif
DEFUN (config_list,
config_list_cmd,
"list [permutations]",
"Print command list\n"
"Print all possible command permutations\n")
{
return cmd_list_cmds (vty, argc == 2);
}
static void static void
vtysh_install_default (enum node_type node) vtysh_install_default (enum node_type node)
{ {

View File

@ -1237,32 +1237,6 @@ if_dump_vty (struct vty *vty, struct interface *ifp)
#endif /* HAVE_NET_RT_IFLIST */ #endif /* HAVE_NET_RT_IFLIST */
} }
/* Wrapper hook point for zebra daemon so that ifindex can be set
* DEFUN macro not used as extract.pl HAS to ignore this
* See also interface_cmd in lib/if.c
*/
DEFUN_NOSH (zebra_interface,
zebra_interface_cmd,
"interface IFNAME",
"Select an interface to configure\n"
"Interface's name\n")
{
int ret;
/* Call lib interface() */
if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
return ret;
VTY_DECLVAR_CONTEXT (interface, ifp);
if (ifp->ifindex == IFINDEX_INTERNAL)
/* Is this really necessary? Shouldn't status be initialized to 0
in that case? */
UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
return ret;
}
static void static void
interface_update_stats (void) interface_update_stats (void)
{ {
@ -2903,6 +2877,7 @@ zebra_if_init (void)
/* Install configuration write function. */ /* Install configuration write function. */
install_node (&interface_node, if_config_write); install_node (&interface_node, if_config_write);
install_node (&link_params_node, NULL); install_node (&link_params_node, NULL);
if_cmd_init ();
install_element (VIEW_NODE, &show_interface_cmd); install_element (VIEW_NODE, &show_interface_cmd);
install_element (VIEW_NODE, &show_interface_vrf_all_cmd); install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
@ -2911,11 +2886,6 @@ zebra_if_init (void)
install_element (ENABLE_NODE, &show_interface_desc_cmd); install_element (ENABLE_NODE, &show_interface_desc_cmd);
install_element (ENABLE_NODE, &show_interface_desc_vrf_all_cmd); install_element (ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
install_element (CONFIG_NODE, &zebra_interface_cmd);
install_element (CONFIG_NODE, &no_interface_cmd);
install_default (INTERFACE_NODE);
install_element (INTERFACE_NODE, &interface_desc_cmd);
install_element (INTERFACE_NODE, &no_interface_desc_cmd);
install_element (INTERFACE_NODE, &multicast_cmd); install_element (INTERFACE_NODE, &multicast_cmd);
install_element (INTERFACE_NODE, &no_multicast_cmd); install_element (INTERFACE_NODE, &no_multicast_cmd);
install_element (INTERFACE_NODE, &linkdetect_cmd); install_element (INTERFACE_NODE, &linkdetect_cmd);

View File

@ -520,26 +520,6 @@ zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id)
return zvrf->table[afi][SAFI_UNICAST]; return zvrf->table[afi][SAFI_UNICAST];
} }
/* Wrapper hook point for zebra daemon so that ifindex can be set
* DEFUN macro not used as extract.pl HAS to ignore this
* See also interface_cmd in lib/if.c
*/
DEFUN_NOSH (zebra_vrf,
zebra_vrf_cmd,
"vrf NAME",
"Select a VRF to configure\n"
"VRF's name\n")
{
// VTY_DECLVAR_CONTEXT (vrf, vrfp);
int ret;
/* Call lib vrf() */
if ((ret = vrf_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
return ret;
return ret;
}
static int static int
vrf_config_write (struct vty *vty) vrf_config_write (struct vty *vty)
{ {
@ -558,13 +538,6 @@ vrf_config_write (struct vty *vty)
return 0; return 0;
} }
struct cmd_node vrf_node =
{
VRF_NODE,
"%s(config-vrf)# ",
1
};
/* Zebra VRF initialization. */ /* Zebra VRF initialization. */
void void
zebra_vrf_init (void) zebra_vrf_init (void)
@ -575,9 +548,5 @@ zebra_vrf_init (void)
vrf_add_hook (VRF_DELETE_HOOK, zebra_vrf_delete); vrf_add_hook (VRF_DELETE_HOOK, zebra_vrf_delete);
vrf_init (); vrf_init ();
vrf_cmd_init (vrf_config_write);
install_node (&vrf_node, vrf_config_write);
install_default (VRF_NODE);
install_element (CONFIG_NODE, &zebra_vrf_cmd);
install_element (CONFIG_NODE, &no_vrf_cmd);
} }