mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 18:01:54 +00:00
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:
commit
7ddcfca4fb
@ -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 ();
|
||||||
}
|
}
|
||||||
|
@ -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 *
|
||||||
|
@ -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 ()
|
||||||
{
|
{
|
||||||
|
@ -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 *);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
11
lib/if.c
11
lib/if.c
@ -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,
|
||||||
|
16
lib/if.h
16
lib/if.h
@ -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 */
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
13
lib/vrf.c
13
lib/vrf.c
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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>"
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user