diff --git a/lib/command.h b/lib/command.h index 57e3b9cda0b7..cb105c656c18 100644 --- a/lib/command.h +++ b/lib/command.h @@ -252,9 +252,11 @@ struct cmd_node { /* Argc max counts. */ #define CMD_ARGC_MAX 256 +/* clang-format off */ + /* helper defines for end-user DEFUN* macros */ #define DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \ - static const struct cmd_element cmdname = { \ + const struct cmd_element cmdname = { \ .string = cmdstr, \ .func = funcname, \ .doc = helpstr, \ @@ -281,7 +283,7 @@ struct cmd_node { /* DEFPY variants */ #define DEFPY_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \ - DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0) \ + static DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0) \ funcdecl_##funcname #define DEFPY(funcname, cmdname, cmdstr, helpstr) \ @@ -308,7 +310,7 @@ struct cmd_node { #define DEFUN_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \ DEFUN_CMD_FUNC_DECL(funcname) \ - DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0) \ + static DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0) \ DEFUN_CMD_FUNC_TEXT(funcname) #define DEFUN(funcname, cmdname, cmdstr, helpstr) \ @@ -345,7 +347,8 @@ struct cmd_node { /* DEFUN + DEFSH */ #define DEFUNSH_ATTR(daemon, funcname, cmdname, cmdstr, helpstr, attr) \ DEFUN_CMD_FUNC_DECL(funcname) \ - DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, daemon) \ + static DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, \ + daemon) \ DEFUN_CMD_FUNC_TEXT(funcname) #define DEFUNSH(daemon, funcname, cmdname, cmdstr, helpstr) \ @@ -357,7 +360,7 @@ struct cmd_node { /* ALIAS macro which define existing command's alias. */ #define ALIAS_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \ - DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0) + static DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0) #define ALIAS(funcname, cmdname, cmdstr, helpstr) \ ALIAS_ATTR(funcname, cmdname, cmdstr, helpstr, 0) @@ -376,6 +379,8 @@ struct cmd_node { #define ALIAS_YANG(funcname, cmdname, cmdstr, helpstr) \ ALIAS_ATTR(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_YANG) +/* clang-format on */ + /* Some macroes */ /* diff --git a/lib/command_graph.c b/lib/command_graph.c index ff3c11db69b5..20ab6b321b5c 100644 --- a/lib/command_graph.c +++ b/lib/command_graph.c @@ -267,6 +267,9 @@ static bool cmd_nodes_equal(struct graph_node *ga, struct graph_node *gb) case NEG_ONLY_TKN: case WORD_TKN: case ASNUM_TKN: +#ifdef BUILDING_CLIPPY + case CMD_ELEMENT_TKN: +#endif return true; } diff --git a/lib/command_graph.h b/lib/command_graph.h index 25aa47db7b65..313c97fe879e 100644 --- a/lib/command_graph.h +++ b/lib/command_graph.h @@ -54,6 +54,9 @@ enum cmd_token_type { END_TKN, // last token in line NEG_ONLY_TKN, // filter token, match if "no ..." command +#ifdef BUILDING_CLIPPY + CMD_ELEMENT_TKN, // python bindings only +#endif SPECIAL_TKN = FORK_TKN, }; /* clang-format on */ diff --git a/lib/command_py.c b/lib/command_py.c index f8abcf8ef401..a77adcd7dc68 100644 --- a/lib/command_py.c +++ b/lib/command_py.c @@ -29,6 +29,7 @@ struct wrap_graph; static PyObject *graph_to_pyobj(struct wrap_graph *graph, struct graph_node *gn); +static PyObject *graph_to_pyobj_idx(struct wrap_graph *wgraph, size_t i); /* * nodes are wrapped as follows: @@ -44,13 +45,6 @@ struct wrap_graph_node { bool allowrepeat; const char *type; - bool deprecated; - bool hidden; - const char *text; - const char *desc; - const char *varname; - long long min, max; - struct graph_node *node; struct wrap_graph *wgraph; size_t idx; @@ -68,6 +62,7 @@ struct wrap_graph { char *definition; struct graph *graph; + size_t n_nodewrappers; struct wrap_graph_node **nodewrappers; }; @@ -84,11 +79,75 @@ static PyObject *refuse_new(PyTypeObject *type, PyObject *args, PyObject *kwds) READONLY, (char *)#name " (" #type ")" \ } static PyMemberDef members_graph_node[] = { - member(allowrepeat, T_BOOL), member(type, T_STRING), - member(deprecated, T_BOOL), member(hidden, T_BOOL), - member(text, T_STRING), member(desc, T_STRING), - member(min, T_LONGLONG), member(max, T_LONGLONG), - member(varname, T_STRING), {}, + /* clang-format off */ + member(type, T_STRING), + member(idx, T_ULONG), + {}, + /* clang-format on */ +}; +#undef member + +static PyObject *graph_node_get_str(PyObject *self, void *poffset) +{ + struct wrap_graph_node *wrap = (struct wrap_graph_node *)self; + void *offset = (char *)wrap->node->data + (ptrdiff_t)poffset; + const char *val = *(const char **)offset; + + if (!val) + Py_RETURN_NONE; + return PyUnicode_FromString(val); +} + +static PyObject *graph_node_get_bool(PyObject *self, void *poffset) +{ + struct wrap_graph_node *wrap = (struct wrap_graph_node *)self; + void *offset = (char *)wrap->node->data + (ptrdiff_t)poffset; + bool val = *(bool *)offset; + + return PyBool_FromLong(val); +} + +static PyObject *graph_node_get_ll(PyObject *self, void *poffset) +{ + struct wrap_graph_node *wrap = (struct wrap_graph_node *)self; + void *offset = (char *)wrap->node->data + (ptrdiff_t)poffset; + long long val = *(long long *)offset; + + return PyLong_FromLongLong(val); +} + +static PyObject *graph_node_get_u8(PyObject *self, void *poffset) +{ + struct wrap_graph_node *wrap = (struct wrap_graph_node *)self; + void *offset = (char *)wrap->node->data + (ptrdiff_t)poffset; + uint8_t val = *(uint8_t *)offset; + + return PyLong_FromUnsignedLong(val); +} + +/* clang-format off */ +#define member(name, variant) \ + { \ + (char *)#name, \ + graph_node_get_##variant, \ + NULL, \ + (char *)#name " (" #variant ")", \ + (void *)offsetof(struct cmd_token, name), \ + } +/* clang-format on */ + +static PyGetSetDef getset_graph_node[] = { + /* clang-format off */ + member(attr, u8), + member(allowrepeat, bool), + member(varname_src, u8), + member(text, str), + member(desc, str), + member(min, ll), + member(max, ll), + member(varname, str), + {}, + /* clang-format on */ }; #undef member @@ -101,12 +160,30 @@ static PyObject *graph_node_next(PyObject *self, PyObject *args) struct wrap_graph_node *wrap = (struct wrap_graph_node *)self; PyObject *pylist; - if (wrap->node->data - && ((struct cmd_token *)wrap->node->data)->type == END_TKN) + if (wrap->node->data && + ((struct cmd_token *)wrap->node->data)->type == CMD_ELEMENT_TKN) return PyList_New(0); pylist = PyList_New(vector_active(wrap->node->to)); for (size_t i = 0; i < vector_active(wrap->node->to); i++) { struct graph_node *gn = vector_slot(wrap->node->to, i); + + PyList_SetItem(pylist, i, graph_to_pyobj(wrap->wgraph, gn)); + } + return pylist; +}; + +static PyObject *graph_node_prev(PyObject *self, PyObject *args) +{ + struct wrap_graph_node *wrap = (struct wrap_graph_node *)self; + PyObject *pylist; + + if (wrap->node->data && + ((struct cmd_token *)wrap->node->data)->type == START_TKN) + return PyList_New(0); + pylist = PyList_New(vector_active(wrap->node->from)); + for (size_t i = 0; i < vector_active(wrap->node->from); i++) { + struct graph_node *gn = vector_slot(wrap->node->from, i); + PyList_SetItem(pylist, i, graph_to_pyobj(wrap->wgraph, gn)); } return pylist; @@ -118,30 +195,60 @@ static PyObject *graph_node_next(PyObject *self, PyObject *args) static PyObject *graph_node_join(PyObject *self, PyObject *args) { struct wrap_graph_node *wrap = (struct wrap_graph_node *)self; + struct cmd_token *tok; if (!wrap->node->data || ((struct cmd_token *)wrap->node->data)->type == END_TKN) Py_RETURN_NONE; - struct cmd_token *tok = wrap->node->data; + tok = wrap->node->data; if (tok->type != FORK_TKN) Py_RETURN_NONE; return graph_to_pyobj(wrap->wgraph, tok->forkjoin); }; +static PyObject *graph_node_fork(PyObject *self, PyObject *args) +{ + struct wrap_graph_node *wrap = (struct wrap_graph_node *)self; + struct cmd_token *tok; + + if (!wrap->node->data || + ((struct cmd_token *)wrap->node->data)->type == END_TKN) + Py_RETURN_NONE; + + tok = wrap->node->data; + if (tok->type != JOIN_TKN) + Py_RETURN_NONE; + + return graph_to_pyobj(wrap->wgraph, tok->forkjoin); +}; + static PyMethodDef methods_graph_node[] = { - {"next", graph_node_next, METH_NOARGS, "outbound graph edge list"}, - {"join", graph_node_join, METH_NOARGS, "outbound join node"}, - {}}; + { "next", graph_node_next, METH_NOARGS, "outbound graph edge list" }, + { "prev", graph_node_prev, METH_NOARGS, "inbound graph edge list" }, + { "join", graph_node_join, METH_NOARGS, "outbound join node" }, + { "fork", graph_node_fork, METH_NOARGS, "inbound fork node" }, + {} +}; static void graph_node_wrap_free(void *arg) { struct wrap_graph_node *wrap = arg; + + assert(wrap->idx < wrap->wgraph->n_nodewrappers); wrap->wgraph->nodewrappers[wrap->idx] = NULL; Py_DECREF(wrap->wgraph); } +static PyObject *repr_graph_node(PyObject *arg) +{ + struct wrap_graph_node *wrap = (struct wrap_graph_node *)arg; + + return PyUnicode_FromFormat("<_clippy.GraphNode %p [%zu] %s>", + wrap->node, wrap->idx, wrap->type); +} + static PyTypeObject typeobj_graph_node = { PyVarObject_HEAD_INIT(NULL, 0).tp_name = "_clippy.GraphNode", .tp_basicsize = sizeof(struct wrap_graph_node), @@ -150,13 +257,14 @@ static PyTypeObject typeobj_graph_node = { .tp_new = refuse_new, .tp_free = graph_node_wrap_free, .tp_members = members_graph_node, + .tp_getset = getset_graph_node, .tp_methods = methods_graph_node, + .tp_repr = repr_graph_node, }; static PyObject *graph_to_pyobj(struct wrap_graph *wgraph, struct graph_node *gn) { - struct wrap_graph_node *wrap; size_t i; for (i = 0; i < vector_active(wgraph->graph->nodes); i++) @@ -166,6 +274,24 @@ static PyObject *graph_to_pyobj(struct wrap_graph *wgraph, PyErr_SetString(PyExc_ValueError, "cannot find node in graph"); return NULL; } + + return graph_to_pyobj_idx(wgraph, i); +} + +static PyObject *graph_to_pyobj_idx(struct wrap_graph *wgraph, size_t i) +{ + struct wrap_graph_node *wrap; + struct graph_node *gn = vector_slot(wgraph->graph->nodes, i); + + if (i >= wgraph->n_nodewrappers) { + wgraph->nodewrappers = + realloc(wgraph->nodewrappers, + (i + 1) * sizeof(wgraph->nodewrappers[0])); + memset(wgraph->nodewrappers + wgraph->n_nodewrappers, 0, + sizeof(wgraph->nodewrappers[0]) * + (i + 1 - wgraph->n_nodewrappers)); + wgraph->n_nodewrappers = i + 1; + } if (wgraph->nodewrappers[i]) { PyObject *obj = (PyObject *)wgraph->nodewrappers[i]; Py_INCREF(obj); @@ -209,19 +335,11 @@ static PyObject *graph_to_pyobj(struct wrap_graph *wgraph, item(START_TKN); item(END_TKN); item(NEG_ONLY_TKN); + item(CMD_ELEMENT_TKN); #undef item default: wrap->type = "???"; } - - wrap->deprecated = !!(tok->attr & CMD_ATTR_DEPRECATED); - wrap->hidden = !!(tok->attr & CMD_ATTR_HIDDEN); - wrap->text = tok->text; - wrap->desc = tok->desc; - wrap->varname = tok->varname; - wrap->min = tok->min; - wrap->max = tok->max; - wrap->allowrepeat = tok->allowrepeat; } return (PyObject *)wrap; @@ -246,9 +364,13 @@ static PyObject *graph_first(PyObject *self, PyObject *args) return graph_to_pyobj(gwrap, gn); }; +static PyObject *graph_merge(PyObject *self, PyObject *args); + static PyMethodDef methods_graph[] = { - {"first", graph_first, METH_NOARGS, "first graph node"}, - {}}; + { "first", graph_first, METH_NOARGS, "first graph node" }, + { "merge", graph_merge, METH_VARARGS, "merge graphs" }, + {} +}; static PyObject *graph_parse(PyTypeObject *type, PyObject *args, PyObject *kwds); @@ -262,6 +384,30 @@ static void graph_wrap_free(void *arg) free(wgraph->definition); } +static Py_ssize_t graph_length(PyObject *self) +{ + struct wrap_graph *gwrap = (struct wrap_graph *)self; + + return vector_active(gwrap->graph->nodes); +} + +static PyObject *graph_item(PyObject *self, Py_ssize_t idx) +{ + struct wrap_graph *gwrap = (struct wrap_graph *)self; + + if (idx >= vector_active(gwrap->graph->nodes)) + return PyErr_Format(PyExc_IndexError, + "index %zd past graph size %u", idx, + vector_active(gwrap->graph->nodes)); + + return graph_to_pyobj_idx(gwrap, idx); +} + +static PySequenceMethods seq_graph = { + .sq_length = graph_length, + .sq_item = graph_item, +}; + static PyTypeObject typeobj_graph = { PyVarObject_HEAD_INIT(NULL, 0).tp_name = "_clippy.Graph", .tp_basicsize = sizeof(struct wrap_graph), @@ -271,35 +417,62 @@ static PyTypeObject typeobj_graph = { .tp_free = graph_wrap_free, .tp_members = members_graph, .tp_methods = methods_graph, + .tp_as_sequence = &seq_graph, }; +static PyObject *graph_merge(PyObject *self, PyObject *args) +{ + PyObject *py_other; + struct wrap_graph *gwrap = (struct wrap_graph *)self; + struct wrap_graph *gother; + + if (!PyArg_ParseTuple(args, "O!", &typeobj_graph, &py_other)) + return NULL; + + gother = (struct wrap_graph *)py_other; + cmd_graph_merge(gwrap->graph, gother->graph, +1); + Py_RETURN_NONE; +} + /* top call / entrypoint for python code */ static PyObject *graph_parse(PyTypeObject *type, PyObject *args, PyObject *kwds) { - const char *def, *doc = NULL; + const char *def, *doc = NULL, *name = NULL; struct wrap_graph *gwrap; - static const char *kwnames[] = {"cmddef", "doc", NULL}; + static const char *const kwnames[] = { "cmddef", "doc", "name", NULL }; gwrap = (struct wrap_graph *)typeobj_graph.tp_alloc(&typeobj_graph, 0); if (!gwrap) return NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", (char **)kwnames, - &def, &doc)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "z|ss", (char **)kwnames, + &def, &doc, &name)) return NULL; struct graph *graph = graph_new(); struct cmd_token *token = cmd_token_new(START_TKN, 0, NULL, NULL); graph_new_node(graph, token, (void (*)(void *)) & cmd_token_del); - struct cmd_element cmd = {.string = def, .doc = doc}; - cmd_graph_parse(graph, &cmd); - cmd_graph_names(graph); + if (def) { + struct cmd_element cmd = { .string = def, .doc = doc }; + struct graph_node *last; + + cmd_graph_parse(graph, &cmd); + cmd_graph_names(graph); + + last = vector_slot(graph->nodes, + vector_active(graph->nodes) - 1); + assert(last->data == &cmd); + + last->data = cmd_token_new(CMD_ELEMENT_TKN, 0, name, def); + last->del = (void (*)(void *))cmd_token_del; + + gwrap->definition = strdup(def); + } else { + gwrap->definition = strdup("NULL"); + } gwrap->graph = graph; - gwrap->definition = strdup(def); - gwrap->nodewrappers = calloc(vector_active(graph->nodes), - sizeof(gwrap->nodewrappers[0])); return (PyObject *)gwrap; } diff --git a/lib/subdir.am b/lib/subdir.am index 3264f31af7a4..4bcce9a2b05a 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -504,20 +504,41 @@ SUFFIXES += .xref %.xref: % $(CLIPPY) $(AM_V_XRELFO) $(CLIPPY) $(top_srcdir)/python/xrelfo.py $(WERROR) $(XRELFO_FLAGS) -o $@ $< +# these run up to a total of 350k lines at the time of writing. That's a lot +# for the compiler to chug down - enough to warrant splitting it up so it can +# benefit from parallel build. +vtysh_cmd_split = \ + vtysh/vtysh_cmd.1.c \ + vtysh/vtysh_cmd.2.c \ + vtysh/vtysh_cmd.3.c \ + vtysh/vtysh_cmd.4.c \ + vtysh/vtysh_cmd.5.c \ + vtysh/vtysh_cmd.6.c \ + vtysh/vtysh_cmd.7.c \ + vtysh/vtysh_cmd.8.c \ + # end + # dependencies added in python/makefile.py frr.xref: - $(AM_V_XRELFO) $(CLIPPY) $(top_srcdir)/python/xrelfo.py -o $@ -c vtysh/vtysh_cmd.c $^ + $(AM_V_XRELFO) $(CLIPPY) $(top_srcdir)/python/xrelfo.py -o $@ $^ \ + -c vtysh/vtysh_cmd.c $(vtysh_cmd_split) all-am: frr.xref clean-xref: -rm -rf $(xrefs) frr.xref clean-local: clean-xref -CLEANFILES += vtysh/vtysh_cmd.c vtysh/vtysh_cmd.c: frr.xref @test -f $@ || rm -f frr.xref || true @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) frr.xref +vtysh/vtysh_cmd.%.c: vtysh/vtysh_cmd.c + @test -f $@ || rm -f vtysh/vtysh_cmd.c || true + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) vtysh/vtysh_cmd.c + +nodist_vtysh_vtysh_SOURCES = vtysh/vtysh_cmd.c $(vtysh_cmd_split) +CLEANFILES += vtysh/vtysh_cmd.c $(vtysh_cmd_split) + ## automake's "ylwrap" is a great piece of GNU software... not. .l.c: $(AM_V_LEX)$(am__skiplex) $(LEXCOMPILE) $< diff --git a/lib/vector.c b/lib/vector.c index 60d383101ac6..06361549607f 100644 --- a/lib/vector.c +++ b/lib/vector.c @@ -24,45 +24,44 @@ vector vector_init(unsigned int size) v->alloced = size; v->active = 0; v->count = 0; + v->dynamic = true; v->index = XCALLOC(MTYPE_VECTOR_INDEX, sizeof(void *) * size); return v; } void vector_free(vector v) { - XFREE(MTYPE_VECTOR_INDEX, v->index); - XFREE(MTYPE_VECTOR, v); + if (v->alloced) + XFREE(MTYPE_VECTOR_INDEX, v->index); + if (v->dynamic) + XFREE(MTYPE_VECTOR, v); } -vector vector_copy(vector v) -{ - unsigned int size; - vector new = XCALLOC(MTYPE_VECTOR, sizeof(struct _vector)); - - new->active = v->active; - new->alloced = v->alloced; - new->count = v->count; - - size = sizeof(void *) * (v->alloced); - new->index = XCALLOC(MTYPE_VECTOR_INDEX, size); - memcpy(new->index, v->index, size); - - return new; -} - -/* Check assigned index, and if it runs short double index pointer */ +/* resize vector to a minimum of num + * may resize larger to avoid excessive realloc overhead + */ void vector_ensure(vector v, unsigned int num) { + unsigned int newsz; + if (v->alloced > num) return; - v->index = XREALLOC(MTYPE_VECTOR_INDEX, v->index, - sizeof(void *) * (v->alloced * 2)); - memset(&v->index[v->alloced], 0, sizeof(void *) * v->alloced); - v->alloced *= 2; + newsz = MAX(v->active * 2, num + 1); + + if (!v->alloced && v->index) { + /* currently using global variable, not malloc'd memory */ + void **orig_index = v->index; - if (v->alloced <= num) - vector_ensure(v, num); + v->index = XMALLOC(MTYPE_VECTOR_INDEX, sizeof(void *) * newsz); + memcpy(v->index, orig_index, v->active * sizeof(void *)); + v->alloced = v->active; + } else + v->index = XREALLOC(MTYPE_VECTOR_INDEX, v->index, + sizeof(void *) * newsz); + + memset(&v->index[v->alloced], 0, sizeof(void *) * (newsz - v->alloced)); + v->alloced = newsz; } /* This function only returns next empty slot index. It dose not mean @@ -140,7 +139,7 @@ void *vector_lookup_ensure(vector v, unsigned int i) /* Unset value at specified index slot. */ void vector_unset(vector v, unsigned int i) { - if (i >= v->alloced) + if (i >= v->active) return; if (v->index[i]) diff --git a/lib/vector.h b/lib/vector.h index fcbc13257a17..ae05d4d3e049 100644 --- a/lib/vector.h +++ b/lib/vector.h @@ -15,9 +15,26 @@ extern "C" { /* struct for vector */ struct _vector { - unsigned int active; /* number of active slots */ - unsigned int alloced; /* number of allocated slot */ + /* active: index of last non-NULL item (+1) + * count: number of non-NULL items (+1) + * + * the two will be different if a slot is set to NULL (without pulling + * up later items in the array). Whether this happens depends on + * which vector functions are used. If no empty slots are used, the + * two fields will be identical. + * + * alloced: size of array pointed to by index. If this is 0, index + * points at a global variable rather than a malloc'd bit of memory. + * The vector code will convert to malloc'd memory if necessary to + * perform updates. + */ + unsigned int active; + unsigned int alloced; unsigned int count; + + /* whether struct _vector itself is dynamically allocated */ + bool dynamic; + void **index; /* index to data */ }; typedef struct _vector *vector; @@ -51,7 +68,6 @@ static inline unsigned int vector_count(vector v) } extern void vector_free(vector v); -extern vector vector_copy(vector v); extern void *vector_lookup(vector, unsigned int); extern void *vector_lookup_ensure(vector, unsigned int); diff --git a/python/xref2vtysh.py b/python/xref2vtysh.py index 75d9ccf367df..0cfb11e72111 100644 --- a/python/xref2vtysh.py +++ b/python/xref2vtysh.py @@ -26,6 +26,8 @@ except ImportError: pass +import _clippy + frr_top_src = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # vtysh needs to know which daemon(s) to send commands to. For lib/, this is @@ -58,6 +60,16 @@ #include "linklist.h" #include "vtysh/vtysh.h" + +#pragma GCC visibility push(internal) + +#define MAKE_VECTOR(name, len, ...) \\ + static void * name ## _vitems[] = { __VA_ARGS__ }; \\ + static struct _vector name = { \\ + .active = len, \\ + .count = len, \\ + .index = name ## _vitems, \\ + } """ if sys.stderr.isatty(): @@ -335,23 +347,159 @@ def output_defs(cls, ofd): ofd.write(entry.get_def()) @classmethod - def output_install(cls, ofd, nodes): - ofd.write("\nvoid vtysh_init_cmd(void)\n{\n") + def output_node_graph(cls, ofd, node, cmds, splitfile): + graph = _clippy.Graph(None) + + for _, cmd in sorted(cmds.items()): + cg = _clippy.Graph(cmd.cmd, cmd._spec["doc"], cmd.name) + graph.merge(cg) + + if len(graph) <= 2: + return [] + + ofd.write("\n") + ofd.write(f"static struct cmd_token ctkn_{node}[];\n") + ofd.write(f"static struct graph_node gn_{node}[];\n") + ofd.write("\n") + + vectors = [] + cmdels = set() + + ofd.write(f"static struct cmd_token ctkn_{node}[] = {'{'}\n") + for i, token in enumerate(graph): + vectors.append( + ( + list(i.idx for i in token.next()), + list(i.idx for i in token.prev()), + ) + ) - for name, items in sorted(nodes.items_named()): - for item in sorted(items.values(), key=lambda i: i.name): - ofd.write("\tinstall_element(%s, &%s_vtysh);\n" % (name, item.name)) + if token.type == "CMD_ELEMENT_TKN": + ofd.write(f"\t{'{'} /* [{i}] = {token.text} */ {'}'},\n") + cmdels.add(token.text) + continue + + ofd.write(f"\t{'{'} /* [{i}] */\n\t\t.type = {token.type},\n") + if token.attr: + ofd.write(f"\t\t.attr = {token.attr},\n") + if token.allowrepeat: + ofd.write(f"\t\t.allowrepeat = true,\n") + if token.varname_src: + ofd.write(f"\t\t.varname_src = {token.varname_src},\n") + if token.text: + ofd.write(f'\t\t.text = (char *)"{c_escape(token.text)}",\n') + if token.desc: + ofd.write(f'\t\t.desc = (char *)"{c_escape(token.desc)}",\n') + if token.min: + ofd.write(f"\t\t.min = {token.min},\n") + if token.max: + ofd.write(f"\t\t.max = {token.max},\n") + if token.varname: + ofd.write(f'\t\t.varname = (char *)"{c_escape(token.varname)}",\n') + + if token.type == "FORK_TKN": + fj = token.join() + ofd.write(f"\t\t.forkjoin = &gn_{node}[{fj.idx}],\n") + if token.type == "JOIN_TKN": + fj = token.fork() + ofd.write(f"\t\t.forkjoin = &gn_{node}[{fj.idx}],\n") + + ofd.write(f"\t{'}'},\n") + + ofd.write("};\n\n") + + if splitfile: + for cmdel in sorted(cmdels): + ofd.write(f"extern struct cmd_element {cmdel}_vtysh;\n") + ofd.write("\n") + + for i, next_prev in enumerate(vectors): + n, p = next_prev + items = ", ".join(f"&gn_{node}[{i}]" for i in n) + ofd.write(f"MAKE_VECTOR(gn_{node}_{i}_next, {len(n)}, {items});\n") + items = ", ".join(f"&gn_{node}[{i}]" for i in p) + ofd.write(f"MAKE_VECTOR(gn_{node}_{i}_prev, {len(p)}, {items});\n") + + ofd.write(f"\nstatic struct graph_node gn_{node}[] = {'{'}\n") + for i, token in enumerate(graph): + ofd.write("\t{\n") + ofd.write(f"\t\t.from = &gn_{node}_{i}_prev,\n") + ofd.write(f"\t\t.to = &gn_{node}_{i}_next,\n") + if token.type == "CMD_ELEMENT_TKN": + ofd.write(f"\t\t.data = (void *)&{token.text}_vtysh,\n") + else: + ofd.write(f"\t\t.data = &ctkn_{node}[{i}],\n") + ofd.write("\t},\n") + ofd.write("};\n") + + items = ", ".join(f"&gn_{node}[{i}]" for i in range(0, len(graph))) + ofd.write(f"MAKE_VECTOR(gvec_{node}, {len(graph)}, {items});\n") + + ofd.write( + f""" +{"extern " if splitfile else "static "}void install_{node}(void);\n +{"" if splitfile else "static "}void install_{node}(void)\n +{'{'} + unsigned node_id = {node}; + struct cmd_node *node; + + assert(node_id < vector_active(cmdvec)); + node = vector_slot(cmdvec, node_id); + assert(node); + assert(vector_active(node->cmdgraph->nodes) == 1); + graph_delete_node(node->cmdgraph, vector_slot(node->cmdgraph->nodes, 0)); + vector_free(node->cmdgraph->nodes); + node->cmdgraph->nodes = &gvec_{node}; +{'}'} +""" + ) - ofd.write("}\n") + return [node] @classmethod - def run(cls, xref, ofd): - ofd.write(vtysh_cmd_head) + def run(cls, xref, ofds): + for ofd in ofds: + ofd.write(vtysh_cmd_head) + + ofd = ofds.pop(0) NodeDict.load_nodenames() nodes = cls.load(xref) cls.output_defs(ofd) - cls.output_install(ofd, nodes) + + out_nodes = [] + for nodeid, cmds in nodes.items(): + node = nodes.nodename(nodeid) + + if ofds: + gfd, splitfile = ofds[nodeid % len(ofds)], True + else: + gfd, splitfile = ofd, False + + # install_element(VIEW_NODE, x) implies install_element(ENABLE_NODE, x) + # this needs to be handled here. + if node == "ENABLE_NODE": + nodeid_view = list( + k for k, v in nodes.nodenames.items() if v == "VIEW_NODE" + ) + assert len(nodeid_view) == 1 + cmds.update(nodes[nodeid_view[0]]) + + out_nodes.extend(cls.output_node_graph(gfd, node, cmds, splitfile)) + + out_nodes.sort() + + if ofds: + ofd.write("\n") + for name in out_nodes: + ofd.write(f"extern void install_{name}(void);\n") + + ofd.write("\nvoid vtysh_init_cmd(void)\n{\n") + + for name in out_nodes: + ofd.write(f"\tinstall_{name}();\n") + + ofd.write("}\n") def main(): diff --git a/python/xrelfo.py b/python/xrelfo.py index 07cd74071f8e..5f7616f25093 100644 --- a/python/xrelfo.py +++ b/python/xrelfo.py @@ -447,7 +447,9 @@ def main(): argp = argparse.ArgumentParser(description="FRR xref ELF extractor") argp.add_argument("-o", dest="output", type=str, help="write JSON output") argp.add_argument("--out-by-file", type=str, help="write by-file JSON output") - argp.add_argument("-c", dest="vtysh_cmds", type=str, help="write vtysh_cmd.c") + argp.add_argument( + "-c", dest="vtysh_cmds", type=str, help="write vtysh_cmd.c", nargs="*" + ) argp.add_argument("-Wlog-format", action="store_const", const=True) argp.add_argument("-Wlog-args", action="store_const", const=True) argp.add_argument("-Werror", action="store_const", const=True) @@ -528,9 +530,17 @@ def _main(args): os.rename(args.out_by_file + ".tmp", args.out_by_file) if args.vtysh_cmds: - with open(args.vtysh_cmds + ".tmp", "w") as fd: - CommandEntry.run(out, fd) - os.rename(args.vtysh_cmds + ".tmp", args.vtysh_cmds) + fds = [] + for filename in args.vtysh_cmds: + fds.append(open(filename + ".tmp", "w")) + + CommandEntry.run(out, fds) + + while fds: + fds.pop(0).close() + for filename in args.vtysh_cmds: + os.rename(filename + ".tmp", filename) + if args.Werror and CommandEntry.warn_counter: sys.exit(1) diff --git a/tests/lib/subdir.am b/tests/lib/subdir.am index 185b89507932..1a21684f16ca 100644 --- a/tests/lib/subdir.am +++ b/tests/lib/subdir.am @@ -100,7 +100,7 @@ check_PROGRAMS += tests/lib/cli/test_commands tests_lib_cli_test_commands_CFLAGS = $(TESTS_CFLAGS) tests_lib_cli_test_commands_CPPFLAGS = $(TESTS_CPPFLAGS) tests_lib_cli_test_commands_LDADD = $(ALL_TESTS_LDADD) -nodist_tests_lib_cli_test_commands_SOURCES = tests/lib/cli/test_commands_defun.c +nodist_tests_lib_cli_test_commands_SOURCES = tests/lib/cli/test_commands_defun.c $(vtysh_cmd_split) tests_lib_cli_test_commands_SOURCES = tests/lib/cli/test_commands.c tests/helpers/c/prng.c tests/lib/cli/test_commands_defun.c: vtysh/vtysh_cmd.c @$(MKDIR_P) tests/lib/cli diff --git a/tools/checkpatch.pl b/tools/checkpatch.pl index 3e7abeda3962..2c773f7fbcb3 100755 --- a/tools/checkpatch.pl +++ b/tools/checkpatch.pl @@ -5150,7 +5150,7 @@ sub process { # none after. May be left adjacent to another # unary operator, or a cast } elsif ($op eq '!' || $op eq '~' || - $opv eq '*U' || $opv eq '-U' || + $opv eq '*U' || $opv eq '-U' || $opv eq '+U' || $opv eq '&U' || $opv eq '&&U') { if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { if (ERROR("SPACING", diff --git a/vtysh/.gitignore b/vtysh/.gitignore index a6c3d4abc6ca..9cbd248f2f72 100644 --- a/vtysh/.gitignore +++ b/vtysh/.gitignore @@ -1,5 +1,6 @@ vtysh vtysh_cmd.c +vtysh_cmd.*.c # does not exist anymore - remove 2023-10-04 or so extract.pl diff --git a/vtysh/subdir.am b/vtysh/subdir.am index 2eae16d6291c..d39987eb83c8 100644 --- a/vtysh/subdir.am +++ b/vtysh/subdir.am @@ -17,9 +17,6 @@ vtysh_vtysh_SOURCES = \ vtysh/vtysh_user.c \ vtysh/vtysh_config.c \ # end -nodist_vtysh_vtysh_SOURCES = \ - vtysh/vtysh_cmd.c \ - # end noinst_HEADERS += \ vtysh/vtysh.h \ diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index e657aa8af0ac..c43e1909e3e1 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -1161,14 +1161,12 @@ static char **new_completion(const char *text, int start, int end) } /* Vty node structures. */ -#ifdef HAVE_BGPD static struct cmd_node bgp_node = { .name = "bgp", .node = BGP_NODE, .parent_node = CONFIG_NODE, .prompt = "%s(config-router)# ", }; -#endif /* HAVE_BGPD */ static struct cmd_node rip_node = { .name = "rip", @@ -1177,7 +1175,6 @@ static struct cmd_node rip_node = { .prompt = "%s(config-router)# ", }; -#ifdef HAVE_ISISD static struct cmd_node isis_node = { .name = "isis", .node = ISIS_NODE, @@ -1205,16 +1202,13 @@ static struct cmd_node isis_srv6_node_msd_node = { .parent_node = ISIS_SRV6_NODE, .prompt = "%s(config-router-srv6-node-msd)# ", }; -#endif /* HAVE_ISISD */ -#ifdef HAVE_FABRICD static struct cmd_node openfabric_node = { .name = "openfabric", .node = OPENFABRIC_NODE, .parent_node = CONFIG_NODE, .prompt = "%s(config-router)# ", }; -#endif /* HAVE_FABRICD */ static struct cmd_node interface_node = { .name = "interface", @@ -1237,7 +1231,6 @@ static struct cmd_node segment_routing_node = { .prompt = "%s(config-sr)# ", }; -#if defined(HAVE_PATHD) static struct cmd_node sr_traffic_eng_node = { .name = "sr traffic-eng", .node = SR_TRAFFIC_ENG_NODE, @@ -1293,7 +1286,6 @@ static struct cmd_node pcep_pce_config_node = { .parent_node = PCEP_NODE, .prompt = "%s(pcep-sr-te-pcep-pce-config)# ", }; -#endif /* HAVE_PATHD */ static struct cmd_node vrf_node = { .name = "vrf", @@ -1365,14 +1357,12 @@ static struct cmd_node srv6_sid_format_uncompressed_f4024_node = { .prompt = "%s(config-srv6-format)# " }; -#ifdef HAVE_PBRD static struct cmd_node pbr_map_node = { .name = "pbr-map", .node = PBRMAP_NODE, .parent_node = CONFIG_NODE, .prompt = "%s(config-pbr-map)# ", }; -#endif /* HAVE_PBRD */ static struct cmd_node zebra_node = { .name = "zebra", @@ -1381,7 +1371,6 @@ static struct cmd_node zebra_node = { .prompt = "%s(config-router)# ", }; -#ifdef HAVE_BGPD static struct cmd_node bgp_vpnv4_node = { .name = "bgp vpnv4", .node = BGP_VPNV4_NODE, @@ -1477,7 +1466,6 @@ static struct cmd_node bgp_ipv6l_node = { .no_xpath = true, }; -#ifdef ENABLE_BGP_VNC static struct cmd_node bgp_vnc_defaults_node = { .name = "bgp vnc defaults", .node = BGP_VNC_DEFAULTS_NODE, @@ -1505,7 +1493,6 @@ static struct cmd_node bgp_vnc_l2_group_node = { .parent_node = BGP_NODE, .prompt = "%s(config-router-vnc-l2-group)# ", }; -#endif /* ENABLE_BGP_VNC */ static struct cmd_node bmp_node = { .name = "bmp", @@ -1520,34 +1507,27 @@ static struct cmd_node bgp_srv6_node = { .parent_node = BGP_NODE, .prompt = "%s(config-router-srv6)# ", }; -#endif /* HAVE_BGPD */ -#ifdef HAVE_OSPFD static struct cmd_node ospf_node = { .name = "ospf", .node = OSPF_NODE, .parent_node = CONFIG_NODE, .prompt = "%s(config-router)# ", }; -#endif /* HAVE_OSPFD */ -#ifdef HAVE_EIGRPD static struct cmd_node eigrp_node = { .name = "eigrp", .node = EIGRP_NODE, .parent_node = CONFIG_NODE, .prompt = "%s(config-router)# ", }; -#endif /* HAVE_EIGRPD */ -#ifdef HAVE_BABELD static struct cmd_node babel_node = { .name = "babel", .node = BABEL_NODE, .parent_node = CONFIG_NODE, .prompt = "%s(config-router)# ", }; -#endif /* HAVE_BABELD */ static struct cmd_node ripng_node = { .name = "ripng", @@ -1556,16 +1536,13 @@ static struct cmd_node ripng_node = { .prompt = "%s(config-router)# ", }; -#ifdef HAVE_OSPF6D static struct cmd_node ospf6_node = { .name = "ospf6", .node = OSPF6_NODE, .parent_node = CONFIG_NODE, .prompt = "%s(config-ospf6)# ", }; -#endif /* HAVE_OSPF6D */ -#ifdef HAVE_LDPD static struct cmd_node ldp_node = { .name = "ldp", .node = LDP_NODE, @@ -1614,7 +1591,6 @@ static struct cmd_node ldp_pseudowire_node = { .parent_node = LDP_L2VPN_NODE, .prompt = "%s(config-l2vpn-pw)# ", }; -#endif /* HAVE_LDPD */ static struct cmd_node keychain_node = { .name = "keychain", @@ -1637,7 +1613,6 @@ struct cmd_node link_params_node = { .prompt = "%s(config-link-params)# ", }; -#ifdef HAVE_BGPD static struct cmd_node rpki_node = { .name = "rpki", .node = RPKI_NODE, @@ -1652,9 +1627,6 @@ static struct cmd_node rpki_vrf_node = { .prompt = "%s(config-vrf-rpki)# ", }; -#endif /* HAVE_BGPD */ - -#if HAVE_BFDD > 0 static struct cmd_node bfd_node = { .name = "bfd", .node = BFD_NODE, @@ -1675,25 +1647,20 @@ static struct cmd_node bfd_profile_node = { .parent_node = BFD_NODE, .prompt = "%s(config-bfd-profile)# ", }; -#endif /* HAVE_BFDD */ -#ifdef HAVE_PIMD static struct cmd_node pim_node = { .name = "pim", .node = PIM_NODE, .parent_node = CONFIG_NODE, .prompt = "%s(config-pim)# ", }; -#endif /* HAVE_PIMD */ -#ifdef HAVE_PIM6D static struct cmd_node pim6_node = { .name = "pim6", .node = PIM6_NODE, .parent_node = CONFIG_NODE, .prompt = "%s(config-pim6)# ", }; -#endif /* HAVE_PIM6D */ /* Defined in lib/vty.c */ extern struct cmd_node vty_node; @@ -4954,15 +4921,87 @@ void vtysh_init_vty(void) cmd_init(0); cmd_variable_handler_register(vtysh_var_handler); + install_node(&bgp_node); + install_node(&babel_node); + install_node(&bgp_vpnv4_node); + install_node(&bgp_vpnv6_node); + install_node(&bgp_flowspecv4_node); + install_node(&bgp_flowspecv6_node); + install_node(&bgp_ipv4_node); + install_node(&bgp_ipv4m_node); + install_node(&bgp_ipv4l_node); + install_node(&bgp_ipv6_node); + install_node(&bgp_ipv6m_node); + install_node(&bgp_ipv6l_node); + install_node(&bgp_vrf_policy_node); + install_node(&bgp_vnc_defaults_node); + install_node(&bgp_vnc_nve_group_node); + install_node(&bgp_vnc_l2_group_node); + install_node(&bgp_evpn_node); + install_node(&bgp_evpn_vni_node); + install_node(&rpki_node); + install_node(&bmp_node); + install_node(&bgp_srv6_node); + install_node(&rip_node); + install_node(&ripng_node); + install_node(&ospf_node); + install_node(&ospf6_node); + install_node(&ldp_node); + install_node(&ldp_ipv4_node); + install_node(&ldp_ipv6_node); + install_node(&ldp_ipv4_iface_node); + install_node(&ldp_ipv6_iface_node); + install_node(&ldp_l2vpn_node); + install_node(&ldp_pseudowire_node); + install_node(&eigrp_node); + install_node(&isis_node); + install_node(&isis_flex_algo_node); + install_node(&isis_srv6_node); + install_node(&isis_srv6_node_msd_node); + install_node(&openfabric_node); + install_node(&pbr_map_node); + install_node(&bfd_node); + install_node(&bfd_peer_node); + install_node(&bfd_profile_node); + install_node(&segment_routing_node); + install_node(&sr_traffic_eng_node); + install_node(&srte_segment_list_node); + install_node(&srte_policy_node); + install_node(&srte_candidate_dyn_node); + install_node(&pcep_node); + install_node(&pcep_pcc_node); + install_node(&pcep_pce_node); + install_node(&pcep_pce_config_node); + install_node(&keychain_node); + install_node(&keychain_key_node); + install_node(&nh_group_node); + install_node(&zebra_node); + install_node(&interface_node); + install_node(&pim_node); + install_node(&pim6_node); + install_node(&link_params_node); + install_node(&pw_node); + install_node(&vrf_node); + install_node(&rpki_vrf_node); + install_node(&rmap_node); + install_node(&vty_node); + install_node(&srv6_node); + install_node(&srv6_locs_node); + install_node(&srv6_loc_node); + install_node(&srv6_encap_node); + install_node(&srv6_sid_formats_node); + install_node(&srv6_sid_format_usid_f3216_node); + install_node(&srv6_sid_format_uncompressed_f4024_node); + + vtysh_init_cmd(); + /* bgpd */ #ifdef HAVE_BGPD - install_node(&bgp_node); install_element(CONFIG_NODE, &router_bgp_cmd); install_element(BGP_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_NODE, &vtysh_quit_bgpd_cmd); install_element(BGP_NODE, &vtysh_end_all_cmd); - install_node(&bgp_vpnv4_node); install_element(BGP_NODE, &address_family_ipv4_vpn_cmd); #ifdef KEEP_OLD_VPN_COMMANDS install_element(BGP_NODE, &address_family_vpnv4_cmd); @@ -4972,7 +5011,6 @@ void vtysh_init_vty(void) install_element(BGP_VPNV4_NODE, &vtysh_end_all_cmd); install_element(BGP_VPNV4_NODE, &exit_address_family_cmd); - install_node(&bgp_vpnv6_node); install_element(BGP_NODE, &address_family_ipv6_vpn_cmd); #ifdef KEEP_OLD_VPN_COMMANDS install_element(BGP_NODE, &address_family_vpnv6_cmd); @@ -4982,56 +5020,48 @@ void vtysh_init_vty(void) install_element(BGP_VPNV6_NODE, &vtysh_end_all_cmd); install_element(BGP_VPNV6_NODE, &exit_address_family_cmd); - install_node(&bgp_flowspecv4_node); install_element(BGP_NODE, &address_family_flowspecv4_cmd); install_element(BGP_FLOWSPECV4_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_FLOWSPECV4_NODE, &vtysh_quit_bgpd_cmd); install_element(BGP_FLOWSPECV4_NODE, &vtysh_end_all_cmd); install_element(BGP_FLOWSPECV4_NODE, &exit_address_family_cmd); - install_node(&bgp_flowspecv6_node); install_element(BGP_NODE, &address_family_flowspecv6_cmd); install_element(BGP_FLOWSPECV6_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_FLOWSPECV6_NODE, &vtysh_quit_bgpd_cmd); install_element(BGP_FLOWSPECV6_NODE, &vtysh_end_all_cmd); install_element(BGP_FLOWSPECV6_NODE, &exit_address_family_cmd); - install_node(&bgp_ipv4_node); install_element(BGP_NODE, &address_family_ipv4_cmd); install_element(BGP_IPV4_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_IPV4_NODE, &vtysh_quit_bgpd_cmd); install_element(BGP_IPV4_NODE, &vtysh_end_all_cmd); install_element(BGP_IPV4_NODE, &exit_address_family_cmd); - install_node(&bgp_ipv4m_node); install_element(BGP_NODE, &address_family_ipv4_multicast_cmd); install_element(BGP_IPV4M_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_IPV4M_NODE, &vtysh_quit_bgpd_cmd); install_element(BGP_IPV4M_NODE, &vtysh_end_all_cmd); install_element(BGP_IPV4M_NODE, &exit_address_family_cmd); - install_node(&bgp_ipv4l_node); install_element(BGP_NODE, &address_family_ipv4_labeled_unicast_cmd); install_element(BGP_IPV4L_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_IPV4L_NODE, &vtysh_quit_bgpd_cmd); install_element(BGP_IPV4L_NODE, &vtysh_end_all_cmd); install_element(BGP_IPV4L_NODE, &exit_address_family_cmd); - install_node(&bgp_ipv6_node); install_element(BGP_NODE, &address_family_ipv6_cmd); install_element(BGP_IPV6_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_IPV6_NODE, &vtysh_quit_bgpd_cmd); install_element(BGP_IPV6_NODE, &vtysh_end_all_cmd); install_element(BGP_IPV6_NODE, &exit_address_family_cmd); - install_node(&bgp_ipv6m_node); install_element(BGP_NODE, &address_family_ipv6_multicast_cmd); install_element(BGP_IPV6M_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_IPV6M_NODE, &vtysh_quit_bgpd_cmd); install_element(BGP_IPV6M_NODE, &vtysh_end_all_cmd); install_element(BGP_IPV6M_NODE, &exit_address_family_cmd); - install_node(&bgp_ipv6l_node); install_element(BGP_NODE, &address_family_ipv6_labeled_unicast_cmd); install_element(BGP_IPV6L_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_IPV6L_NODE, &vtysh_quit_bgpd_cmd); @@ -5039,28 +5069,24 @@ void vtysh_init_vty(void) install_element(BGP_IPV6L_NODE, &exit_address_family_cmd); #if defined(ENABLE_BGP_VNC) - install_node(&bgp_vrf_policy_node); install_element(BGP_NODE, &vnc_vrf_policy_cmd); install_element(BGP_VRF_POLICY_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_VRF_POLICY_NODE, &vtysh_quit_bgpd_cmd); install_element(BGP_VRF_POLICY_NODE, &vtysh_end_all_cmd); install_element(BGP_VRF_POLICY_NODE, &exit_vrf_policy_cmd); - install_node(&bgp_vnc_defaults_node); install_element(BGP_NODE, &vnc_defaults_cmd); install_element(BGP_VNC_DEFAULTS_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_VNC_DEFAULTS_NODE, &vtysh_quit_bgpd_cmd); install_element(BGP_VNC_DEFAULTS_NODE, &vtysh_end_all_cmd); install_element(BGP_VNC_DEFAULTS_NODE, &exit_vnc_config_cmd); - install_node(&bgp_vnc_nve_group_node); install_element(BGP_NODE, &vnc_nve_group_cmd); install_element(BGP_VNC_NVE_GROUP_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_VNC_NVE_GROUP_NODE, &vtysh_quit_bgpd_cmd); install_element(BGP_VNC_NVE_GROUP_NODE, &vtysh_end_all_cmd); install_element(BGP_VNC_NVE_GROUP_NODE, &exit_vnc_config_cmd); - install_node(&bgp_vnc_l2_group_node); install_element(BGP_NODE, &vnc_l2_group_cmd); install_element(BGP_VNC_L2_GROUP_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_VNC_L2_GROUP_NODE, &vtysh_quit_bgpd_cmd); @@ -5068,33 +5094,28 @@ void vtysh_init_vty(void) install_element(BGP_VNC_L2_GROUP_NODE, &exit_vnc_config_cmd); #endif - install_node(&bgp_evpn_node); install_element(BGP_NODE, &address_family_evpn_cmd); install_element(BGP_EVPN_NODE, &vtysh_quit_bgpd_cmd); install_element(BGP_EVPN_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_EVPN_NODE, &vtysh_end_all_cmd); install_element(BGP_EVPN_NODE, &exit_address_family_cmd); - install_node(&bgp_evpn_vni_node); install_element(BGP_EVPN_NODE, &bgp_evpn_vni_cmd); install_element(BGP_EVPN_VNI_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_EVPN_VNI_NODE, &vtysh_quit_bgpd_cmd); install_element(BGP_EVPN_VNI_NODE, &vtysh_end_all_cmd); install_element(BGP_EVPN_VNI_NODE, &exit_vni_cmd); - install_node(&rpki_node); install_element(CONFIG_NODE, &rpki_cmd); install_element(RPKI_NODE, &rpki_exit_cmd); install_element(RPKI_NODE, &rpki_quit_cmd); install_element(RPKI_NODE, &vtysh_end_all_cmd); - install_node(&bmp_node); install_element(BGP_NODE, &bmp_targets_cmd); install_element(BMP_NODE, &bmp_exit_cmd); install_element(BMP_NODE, &bmp_quit_cmd); install_element(BMP_NODE, &vtysh_end_all_cmd); - install_node(&bgp_srv6_node); install_element(BGP_NODE, &bgp_srv6_cmd); install_element(BGP_SRV6_NODE, &exit_bgp_srv6_cmd); install_element(BGP_SRV6_NODE, &quit_bgp_srv6_cmd); @@ -5102,7 +5123,6 @@ void vtysh_init_vty(void) #endif /* HAVE_BGPD */ /* ripd */ - install_node(&rip_node); #ifdef HAVE_RIPD install_element(CONFIG_NODE, &router_rip_cmd); install_element(RIP_NODE, &vtysh_exit_ripd_cmd); @@ -5111,7 +5131,6 @@ void vtysh_init_vty(void) #endif /* HAVE_RIPD */ /* ripngd */ - install_node(&ripng_node); #ifdef HAVE_RIPNGD install_element(CONFIG_NODE, &router_ripng_cmd); install_element(RIPNG_NODE, &vtysh_exit_ripngd_cmd); @@ -5121,7 +5140,6 @@ void vtysh_init_vty(void) /* ospfd */ #ifdef HAVE_OSPFD - install_node(&ospf_node); install_element(CONFIG_NODE, &router_ospf_cmd); install_element(OSPF_NODE, &vtysh_exit_ospfd_cmd); install_element(OSPF_NODE, &vtysh_quit_ospfd_cmd); @@ -5130,7 +5148,6 @@ void vtysh_init_vty(void) /* ospf6d */ #ifdef HAVE_OSPF6D - install_node(&ospf6_node); install_element(CONFIG_NODE, &router_ospf6_cmd); install_element(OSPF6_NODE, &vtysh_exit_ospf6d_cmd); install_element(OSPF6_NODE, &vtysh_quit_ospf6d_cmd); @@ -5139,45 +5156,38 @@ void vtysh_init_vty(void) /* ldpd */ #if defined(HAVE_LDPD) - install_node(&ldp_node); install_element(CONFIG_NODE, &ldp_mpls_ldp_cmd); install_element(LDP_NODE, &vtysh_exit_ldpd_cmd); install_element(LDP_NODE, &vtysh_quit_ldpd_cmd); install_element(LDP_NODE, &vtysh_end_all_cmd); - install_node(&ldp_ipv4_node); install_element(LDP_NODE, &ldp_address_family_ipv4_cmd); install_element(LDP_IPV4_NODE, &vtysh_exit_ldpd_cmd); install_element(LDP_IPV4_NODE, &vtysh_quit_ldpd_cmd); install_element(LDP_IPV4_NODE, &ldp_exit_address_family_cmd); install_element(LDP_IPV4_NODE, &vtysh_end_all_cmd); - install_node(&ldp_ipv6_node); install_element(LDP_NODE, &ldp_address_family_ipv6_cmd); install_element(LDP_IPV6_NODE, &vtysh_exit_ldpd_cmd); install_element(LDP_IPV6_NODE, &vtysh_quit_ldpd_cmd); install_element(LDP_IPV6_NODE, &ldp_exit_address_family_cmd); install_element(LDP_IPV6_NODE, &vtysh_end_all_cmd); - install_node(&ldp_ipv4_iface_node); install_element(LDP_IPV4_NODE, &ldp_interface_ifname_cmd); install_element(LDP_IPV4_IFACE_NODE, &vtysh_exit_ldpd_cmd); install_element(LDP_IPV4_IFACE_NODE, &vtysh_quit_ldpd_cmd); install_element(LDP_IPV4_IFACE_NODE, &vtysh_end_all_cmd); - install_node(&ldp_ipv6_iface_node); install_element(LDP_IPV6_NODE, &ldp_interface_ifname_cmd); install_element(LDP_IPV6_IFACE_NODE, &vtysh_exit_ldpd_cmd); install_element(LDP_IPV6_IFACE_NODE, &vtysh_quit_ldpd_cmd); install_element(LDP_IPV6_IFACE_NODE, &vtysh_end_all_cmd); - install_node(&ldp_l2vpn_node); install_element(CONFIG_NODE, &ldp_l2vpn_word_type_vpls_cmd); install_element(LDP_L2VPN_NODE, &vtysh_exit_ldpd_cmd); install_element(LDP_L2VPN_NODE, &vtysh_quit_ldpd_cmd); install_element(LDP_L2VPN_NODE, &vtysh_end_all_cmd); - install_node(&ldp_pseudowire_node); install_element(LDP_L2VPN_NODE, &ldp_member_pseudowire_ifname_cmd); install_element(LDP_PSEUDOWIRE_NODE, &vtysh_exit_ldpd_cmd); install_element(LDP_PSEUDOWIRE_NODE, &vtysh_quit_ldpd_cmd); @@ -5186,7 +5196,6 @@ void vtysh_init_vty(void) /* eigrpd */ #ifdef HAVE_EIGRPD - install_node(&eigrp_node); install_element(CONFIG_NODE, &router_eigrp_cmd); install_element(EIGRP_NODE, &vtysh_exit_eigrpd_cmd); install_element(EIGRP_NODE, &vtysh_quit_eigrpd_cmd); @@ -5195,7 +5204,6 @@ void vtysh_init_vty(void) /* babeld */ #ifdef HAVE_BABELD - install_node(&babel_node); install_element(CONFIG_NODE, &router_babel_cmd); install_element(BABEL_NODE, &vtysh_exit_babeld_cmd); install_element(BABEL_NODE, &vtysh_quit_babeld_cmd); @@ -5204,25 +5212,21 @@ void vtysh_init_vty(void) /* isisd */ #ifdef HAVE_ISISD - install_node(&isis_node); install_element(CONFIG_NODE, &router_isis_cmd); install_element(ISIS_NODE, &vtysh_exit_isisd_cmd); install_element(ISIS_NODE, &vtysh_quit_isisd_cmd); install_element(ISIS_NODE, &vtysh_end_all_cmd); - install_node(&isis_flex_algo_node); install_element(ISIS_NODE, &isis_flex_algo_cmd); install_element(ISIS_FLEX_ALGO_NODE, &vtysh_exit_isis_flex_algo_cmd); install_element(ISIS_FLEX_ALGO_NODE, &vtysh_quit_isis_flex_algo_cmd); install_element(ISIS_FLEX_ALGO_NODE, &vtysh_end_all_cmd); - install_node(&isis_srv6_node); install_element(ISIS_NODE, &isis_srv6_enable_cmd); install_element(ISIS_SRV6_NODE, &isis_srv6_node_msd_cmd); install_element(ISIS_SRV6_NODE, &vtysh_exit_isis_srv6_enable_cmd); install_element(ISIS_SRV6_NODE, &vtysh_quit_isis_srv6_enable_cmd); install_element(ISIS_SRV6_NODE, &vtysh_end_all_cmd); - install_node(&isis_srv6_node_msd_node); install_element(ISIS_SRV6_NODE_MSD_NODE, &vtysh_exit_isis_srv6_node_msd_cmd); install_element(ISIS_SRV6_NODE_MSD_NODE, @@ -5232,7 +5236,6 @@ void vtysh_init_vty(void) /* fabricd */ #ifdef HAVE_FABRICD - install_node(&openfabric_node); install_element(CONFIG_NODE, &router_openfabric_cmd); install_element(OPENFABRIC_NODE, &vtysh_exit_fabricd_cmd); install_element(OPENFABRIC_NODE, &vtysh_quit_fabricd_cmd); @@ -5241,7 +5244,6 @@ void vtysh_init_vty(void) /* pbrd */ #ifdef HAVE_PBRD - install_node(&pbr_map_node); install_element(CONFIG_NODE, &vtysh_pbr_map_cmd); install_element(CONFIG_NODE, &vtysh_no_pbr_map_cmd); install_element(PBRMAP_NODE, &vtysh_exit_pbr_map_cmd); @@ -5251,37 +5253,28 @@ void vtysh_init_vty(void) /* bfdd */ #if HAVE_BFDD > 0 - install_node(&bfd_node); install_element(CONFIG_NODE, &bfd_enter_cmd); install_element(BFD_NODE, &vtysh_exit_bfdd_cmd); install_element(BFD_NODE, &vtysh_quit_bfdd_cmd); install_element(BFD_NODE, &vtysh_end_all_cmd); - install_node(&bfd_peer_node); install_element(BFD_NODE, &bfd_peer_enter_cmd); install_element(BFD_PEER_NODE, &vtysh_exit_bfdd_cmd); install_element(BFD_PEER_NODE, &vtysh_quit_bfdd_cmd); install_element(BFD_PEER_NODE, &vtysh_end_all_cmd); - install_node(&bfd_profile_node); install_element(BFD_NODE, &bfd_profile_enter_cmd); install_element(BFD_PROFILE_NODE, &vtysh_exit_bfdd_cmd); install_element(BFD_PROFILE_NODE, &vtysh_quit_bfdd_cmd); install_element(BFD_PROFILE_NODE, &vtysh_end_all_cmd); #endif /* HAVE_BFDD */ - install_node(&segment_routing_node); install_element(CONFIG_NODE, &segment_routing_cmd); install_element(SEGMENT_ROUTING_NODE, &vtysh_exit_sr_cmd); install_element(SEGMENT_ROUTING_NODE, &vtysh_quit_sr_cmd); install_element(SEGMENT_ROUTING_NODE, &vtysh_end_all_cmd); #if defined(HAVE_PATHD) - install_node(&sr_traffic_eng_node); - install_node(&srte_segment_list_node); - install_node(&srte_policy_node); - install_node(&srte_candidate_dyn_node); - install_element(SR_TRAFFIC_ENG_NODE, &vtysh_exit_pathd_cmd); install_element(SR_TRAFFIC_ENG_NODE, &vtysh_quit_pathd_cmd); install_element(SR_SEGMENT_LIST_NODE, &vtysh_exit_pathd_cmd); @@ -5302,11 +5295,6 @@ void vtysh_init_vty(void) install_element(SR_TRAFFIC_ENG_NODE, &srte_policy_cmd); install_element(SR_POLICY_NODE, &srte_policy_candidate_dyn_path_cmd); - install_node(&pcep_node); - install_node(&pcep_pcc_node); - install_node(&pcep_pce_node); - install_node(&pcep_pce_config_node); - install_element(PCEP_NODE, &vtysh_exit_pathd_cmd); install_element(PCEP_NODE, &vtysh_quit_pathd_cmd); install_element(PCEP_PCC_NODE, &vtysh_exit_pathd_cmd); @@ -5329,14 +5317,12 @@ void vtysh_init_vty(void) #endif /* HAVE_PATHD */ /* keychain */ - install_node(&keychain_node); install_element(CONFIG_NODE, &key_chain_cmd); install_element(KEYCHAIN_NODE, &key_chain_cmd); install_element(KEYCHAIN_NODE, &vtysh_exit_keys_cmd); install_element(KEYCHAIN_NODE, &vtysh_quit_keys_cmd); install_element(KEYCHAIN_NODE, &vtysh_end_all_cmd); - install_node(&keychain_key_node); install_element(KEYCHAIN_NODE, &key_cmd); install_element(KEYCHAIN_KEY_NODE, &key_chain_cmd); install_element(KEYCHAIN_KEY_NODE, &vtysh_exit_keys_cmd); @@ -5344,7 +5330,6 @@ void vtysh_init_vty(void) install_element(KEYCHAIN_KEY_NODE, &vtysh_end_all_cmd); /* nexthop-group */ - install_node(&nh_group_node); install_element(CONFIG_NODE, &vtysh_nexthop_group_cmd); install_element(CONFIG_NODE, &vtysh_no_nexthop_group_cmd); install_element(NH_GROUP_NODE, &vtysh_end_all_cmd); @@ -5352,9 +5337,6 @@ void vtysh_init_vty(void) install_element(NH_GROUP_NODE, &vtysh_quit_nexthop_group_cmd); /* zebra and all */ - install_node(&zebra_node); - - install_node(&interface_node); install_element(CONFIG_NODE, &vtysh_interface_cmd); install_element(INTERFACE_NODE, &vtysh_end_all_cmd); install_element(INTERFACE_NODE, &vtysh_exit_interface_cmd); @@ -5362,7 +5344,6 @@ void vtysh_init_vty(void) /* pimd */ #ifdef HAVE_PIMD - install_node(&pim_node); install_element(CONFIG_NODE, &router_pim_cmd); install_element(PIM_NODE, &vtysh_exit_pimd_cmd); install_element(PIM_NODE, &vtysh_quit_pimd_cmd); @@ -5371,15 +5352,12 @@ void vtysh_init_vty(void) /* pim6d */ #ifdef HAVE_PIM6D - install_node(&pim6_node); install_element(CONFIG_NODE, &router_pim6_cmd); install_element(PIM6_NODE, &vtysh_exit_pim6d_cmd); install_element(PIM6_NODE, &vtysh_quit_pim6d_cmd); install_element(PIM6_NODE, &vtysh_end_all_cmd); #endif /* HAVE_PIM6D */ - /* zebra and all, cont. */ - install_node(&link_params_node); install_element(INTERFACE_NODE, &vtysh_link_params_cmd); install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd); install_element(LINK_PARAMS_NODE, &exit_link_params_cmd); @@ -5387,13 +5365,11 @@ void vtysh_init_vty(void) install_element(LINK_PARAMS_NODE, &vtysh_exit_link_params_cmd); install_element(LINK_PARAMS_NODE, &vtysh_quit_link_params_cmd); - install_node(&pw_node); install_element(CONFIG_NODE, &vtysh_pseudowire_cmd); install_element(PW_NODE, &vtysh_end_all_cmd); install_element(PW_NODE, &vtysh_exit_pseudowire_cmd); install_element(PW_NODE, &vtysh_quit_pseudowire_cmd); - install_node(&vrf_node); install_element(CONFIG_NODE, &vtysh_vrf_cmd); install_element(VRF_NODE, &exit_vrf_config_cmd); install_element(VRF_NODE, &vtysh_end_all_cmd); @@ -5401,7 +5377,6 @@ void vtysh_init_vty(void) install_element(VRF_NODE, &vtysh_quit_vrf_cmd); #ifdef HAVE_BGPD - install_node(&rpki_vrf_node); install_element(VRF_NODE, &rpki_cmd); install_element(RPKI_VRF_NODE, &rpki_exit_cmd); install_element(RPKI_VRF_NODE, &rpki_quit_cmd); @@ -5411,13 +5386,11 @@ void vtysh_init_vty(void) install_element(CONFIG_NODE, &vtysh_affinity_map_cmd); install_element(CONFIG_NODE, &vtysh_no_affinity_map_cmd); - install_node(&rmap_node); install_element(CONFIG_NODE, &vtysh_route_map_cmd); install_element(RMAP_NODE, &vtysh_exit_rmap_cmd); install_element(RMAP_NODE, &vtysh_quit_rmap_cmd); install_element(RMAP_NODE, &vtysh_end_all_cmd); - install_node(&vty_node); install_element(CONFIG_NODE, &vtysh_line_vty_cmd); install_element(VTY_NODE, &vtysh_exit_line_vty_cmd); install_element(VTY_NODE, &vtysh_quit_line_vty_cmd); @@ -5450,7 +5423,6 @@ void vtysh_init_vty(void) install_element(ENABLE_NODE, &vtysh_end_all_cmd); /* SRv6 Data-plane */ - install_node(&srv6_node); install_element(SEGMENT_ROUTING_NODE, &srv6_cmd); install_element(SRV6_NODE, &srv6_locators_cmd); install_element(SRV6_NODE, &srv6_sid_formats_cmd); @@ -5458,32 +5430,26 @@ void vtysh_init_vty(void) install_element(SRV6_NODE, &vtysh_end_all_cmd); install_element(SRV6_NODE, &srv6_encap_cmd); - install_node(&srv6_locs_node); install_element(SRV6_LOCS_NODE, &srv6_locator_cmd); install_element(SRV6_LOCS_NODE, &exit_srv6_locs_config_cmd); install_element(SRV6_LOCS_NODE, &vtysh_end_all_cmd); - install_node(&srv6_loc_node); install_element(SRV6_LOC_NODE, &exit_srv6_loc_config_cmd); install_element(SRV6_LOC_NODE, &vtysh_end_all_cmd); - install_node(&srv6_encap_node); install_element(SRV6_ENCAP_NODE, &exit_srv6_encap_cmd); install_element(SRV6_ENCAP_NODE, &vtysh_end_all_cmd); - install_node(&srv6_sid_formats_node); install_element(SRV6_SID_FORMATS_NODE, &srv6_sid_format_f3216_usid_cmd); install_element(SRV6_SID_FORMATS_NODE, &srv6_sid_format_f4024_uncompressed_cmd); install_element(SRV6_SID_FORMATS_NODE, &exit_srv6_sid_formats_cmd); install_element(SRV6_SID_FORMATS_NODE, &vtysh_end_all_cmd); - install_node(&srv6_sid_format_usid_f3216_node); install_element(SRV6_SID_FORMAT_USID_F3216_NODE, &exit_srv6_sid_format_cmd); install_element(SRV6_SID_FORMAT_USID_F3216_NODE, &vtysh_end_all_cmd); - install_node(&srv6_sid_format_uncompressed_f4024_node); install_element(SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE, &exit_srv6_sid_format_cmd); install_element(SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE, diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c index 464d82cf7fee..64198132cc64 100644 --- a/vtysh/vtysh_main.c +++ b/vtysh/vtysh_main.c @@ -489,7 +489,6 @@ int main(int argc, char **argv, char **env) /* Make vty structure and register commands. */ vtysh_init_vty(); - vtysh_init_cmd(); vtysh_user_init(); vtysh_config_init();