mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 15:36:25 +00:00
build, vtysh: extract vtysh commands from .xref
Rather than running selected source files through the preprocessor and a bunch of perl regex'ing to get the list of all DEFUNs, use the data collected in frr.xref. This not only eliminates issues we've been having with preprocessor failures due to nonexistent header files, but is also much faster. Where extract.pl would take 5s, this now finishes in 0.2s. And since this is a non-parallelizable build step towards the end of the build (dependent on a lot of other things being done already), the speedup is actually noticeable. Also files containing CLI no longer need to be listed in `vtysh_scan` since the .xref data covers everything. `#ifndef VTYSH_EXTRACT_PL` checks are equally obsolete. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
695f387ed8
commit
89cb86aeb0
@ -144,7 +144,6 @@ pkginclude_HEADERS =
|
||||
nodist_pkginclude_HEADERS =
|
||||
dist_yangmodels_DATA =
|
||||
man_MANS =
|
||||
vtysh_scan =
|
||||
vtysh_daemons =
|
||||
clippy_scan =
|
||||
|
||||
@ -226,6 +225,7 @@ EXTRA_DIST += \
|
||||
python/makefile.py \
|
||||
python/tiabwarfo.py \
|
||||
python/xrelfo.py \
|
||||
python/xref2vtysh.py \
|
||||
python/test_xrelfo.py \
|
||||
python/runtests.py \
|
||||
\
|
||||
|
@ -4,11 +4,6 @@
|
||||
|
||||
if BABELD
|
||||
sbin_PROGRAMS += babeld/babeld
|
||||
vtysh_scan += \
|
||||
babeld/babel_interface.c \
|
||||
babeld/babel_zebra.c \
|
||||
babeld/babeld.c \
|
||||
# end
|
||||
vtysh_daemons += babeld
|
||||
endif
|
||||
|
||||
|
@ -26,9 +26,7 @@
|
||||
#include "lib/log.h"
|
||||
#include "lib/northbound_cli.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "bfdd/bfdd_cli_clippy.c"
|
||||
#endif /* VTYSH_EXTRACT_PL */
|
||||
|
||||
#include "bfd.h"
|
||||
#include "bfdd_nb.h"
|
||||
|
@ -28,9 +28,7 @@
|
||||
|
||||
#include "bfd.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "bfdd/bfdd_vty_clippy.c"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Commands help string definitions.
|
||||
|
@ -5,8 +5,6 @@
|
||||
if BFDD
|
||||
noinst_LIBRARIES += bfdd/libbfd.a
|
||||
sbin_PROGRAMS += bfdd/bfdd
|
||||
vtysh_scan += bfdd/bfdd_vty.c
|
||||
vtysh_scan += bfdd/bfdd_cli.c
|
||||
vtysh_daemons += bfdd
|
||||
man8 += $(MANBUILD)/frr-bfdd.8
|
||||
endif
|
||||
|
@ -2033,9 +2033,7 @@ static const struct cmd_variable_handler bmp_targets_var_handlers[] = {
|
||||
|
||||
#define BMP_STR "BGP Monitoring Protocol\n"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "bgpd/bgp_bmp_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFPY_NOSH(bmp_targets_main,
|
||||
bmp_targets_cmd,
|
||||
|
@ -1410,9 +1410,7 @@ DEFUN (no_debug_bgp_update_direct_peer,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "bgpd/bgp_debug_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFPY (debug_bgp_update_prefix_afi_safi,
|
||||
debug_bgp_update_prefix_afi_safi_cmd,
|
||||
|
@ -3336,9 +3336,7 @@ static void write_vni_config(struct vty *vty, struct bgpevpn *vpn)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "bgpd/bgp_evpn_vty_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFPY(bgp_evpn_flood_control,
|
||||
bgp_evpn_flood_control_cmd,
|
||||
|
@ -39,9 +39,7 @@
|
||||
|
||||
#define BGP_LABELPOOL_ENABLE_TESTS 0
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "bgpd/bgp_labelpool_clippy.c"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -90,9 +90,7 @@
|
||||
#include "bgpd/bgp_flowspec_util.h"
|
||||
#include "bgpd/bgp_pbr.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "bgpd/bgp_route_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFINE_HOOK(bgp_snmp_update_stats,
|
||||
(struct bgp_node *rn, struct bgp_path_info *pi, bool added),
|
||||
|
@ -74,9 +74,7 @@
|
||||
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
|
||||
#endif
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "bgpd/bgp_routemap_clippy.c"
|
||||
#endif
|
||||
|
||||
/* Memo of route-map commands.
|
||||
|
||||
|
@ -52,16 +52,12 @@
|
||||
|
||||
#include "lib/network.h"
|
||||
#include "lib/thread.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "rtrlib/rtrlib.h"
|
||||
#endif
|
||||
#include "hook.h"
|
||||
#include "libfrr.h"
|
||||
#include "lib/version.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "bgpd/bgp_rpki_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_CACHE, "BGP RPKI Cache server");
|
||||
DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_CACHE_GROUP, "BGP RPKI Cache server group");
|
||||
|
@ -1316,9 +1316,7 @@ void bgp_clear_soft_in(struct bgp *bgp, afi_t afi, safi_t safi)
|
||||
bgp_clear(NULL, bgp, afi, safi, clear_all, BGP_CLEAR_SOFT_IN, NULL);
|
||||
}
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "bgpd/bgp_vty_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFUN_HIDDEN (bgp_local_mac,
|
||||
bgp_local_mac_cmd,
|
||||
|
@ -6,36 +6,9 @@ if BGPD
|
||||
noinst_LIBRARIES += bgpd/libbgp.a
|
||||
sbin_PROGRAMS += bgpd/bgpd
|
||||
noinst_PROGRAMS += bgpd/bgp_btoa
|
||||
vtysh_scan += \
|
||||
bgpd/bgp_bfd.c \
|
||||
bgpd/bgp_debug.c \
|
||||
bgpd/bgp_dump.c \
|
||||
bgpd/bgp_evpn_mh.c \
|
||||
bgpd/bgp_evpn_vty.c \
|
||||
bgpd/bgp_filter.c \
|
||||
bgpd/bgp_labelpool.c \
|
||||
bgpd/bgp_mplsvpn.c \
|
||||
bgpd/bgp_nexthop.c \
|
||||
bgpd/bgp_route.c \
|
||||
bgpd/bgp_routemap.c \
|
||||
bgpd/bgp_vty.c \
|
||||
bgpd/bgp_flowspec_vty.c \
|
||||
# end
|
||||
|
||||
# can be loaded as DSO - always include for vtysh
|
||||
vtysh_scan += bgpd/bgp_rpki.c
|
||||
vtysh_scan += bgpd/bgp_bmp.c
|
||||
|
||||
vtysh_daemons += bgpd
|
||||
|
||||
if ENABLE_BGP_VNC
|
||||
vtysh_scan += \
|
||||
bgpd/rfapi/bgp_rfapi_cfg.c \
|
||||
bgpd/rfapi/rfapi.c \
|
||||
bgpd/rfapi/rfapi_vty.c \
|
||||
bgpd/rfapi/vnc_debug.c \
|
||||
# end
|
||||
endif
|
||||
if SNMP
|
||||
module_LTLIBRARIES += bgpd/bgpd_snmp.la
|
||||
endif
|
||||
|
@ -2747,7 +2747,6 @@ AC_CONFIG_FILES([
|
||||
pkgsrc/ripd.sh pkgsrc/ripngd.sh pkgsrc/zebra.sh
|
||||
pkgsrc/eigrpd.sh])
|
||||
|
||||
AC_CONFIG_FILES([vtysh/extract.pl], [chmod +x vtysh/extract.pl])
|
||||
AC_CONFIG_FILES([tools/frr], [chmod +x tools/frr])
|
||||
AC_CONFIG_FILES([tools/watchfrr.sh], [chmod +x tools/watchfrr.sh])
|
||||
AC_CONFIG_FILES([tools/frrinit.sh], [chmod +x tools/frrinit.sh])
|
||||
|
@ -453,9 +453,7 @@ all DEFPY statements**:
|
||||
/* GPL header */
|
||||
#include ...
|
||||
...
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "daemon/filename_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFPY(...)
|
||||
DEFPY(...)
|
||||
|
@ -43,9 +43,14 @@ simplifying the output. This is discussed in :ref:`vtysh-configuration`.
|
||||
Command Extraction
|
||||
------------------
|
||||
|
||||
When VTYSH is built, a Perl script named :file:`extract.pl` searches the FRR
|
||||
codebase looking for ``DEFUN``'s. It extracts these ``DEFUN``'s, transforms
|
||||
them into ``DEFSH``'s and appends them to ``vtysh_cmd.c``. Each ``DEFSH``
|
||||
To build ``vtysh``, the :file:`python/xref2vtysh.py` script scans through the
|
||||
:file:`frr.xref` file created earlier in the build process. This file contains
|
||||
a list of all ``DEFUN`` and ``install_element`` sites in the code, generated
|
||||
directly from the binaries (and therefore matching exactly what is really
|
||||
available.)
|
||||
|
||||
This list is collated and transformed into ``DEFSH`` (and ``install_element``)
|
||||
statements, output to ``vtysh_cmd.c``. Each ``DEFSH``
|
||||
contains the name of the command plus ``_vtysh``, as well as a flag that
|
||||
indicates which daemons the command was found in. When the command is executed
|
||||
in VTYSH, this flag is inspected to determine which daemons to send the command
|
||||
@ -55,6 +60,12 @@ avoiding spurious errors from daemons that don't have the command defined.
|
||||
The extraction script contains lots of hardcoded knowledge about what sources
|
||||
to look at and what flags to use for certain commands.
|
||||
|
||||
.. note::
|
||||
|
||||
The ``vtysh_scan`` Makefile variable and ``#ifndef VTYSH_EXTRACT_PL``
|
||||
checks in source files are no longer used. Remove them when rebasing older
|
||||
changes.
|
||||
|
||||
.. _vtysh-special-defuns:
|
||||
|
||||
Special DEFUNs
|
||||
@ -69,7 +80,7 @@ several VTYSH-specific ``DEFUN`` variants that each serve different purposes.
|
||||
simply forwarded to the daemons indicated in the daemon flag.
|
||||
|
||||
``DEFUN_NOSH``
|
||||
Used by daemons. Has the same expansion as a ``DEFUN``, but ``extract.pl``
|
||||
Used by daemons. Has the same expansion as a ``DEFUN``, but ``xref2vtysh.py``
|
||||
will skip these definitions when extracting commands. This is typically used
|
||||
when VTYSH must take some special action upon receiving the command, and the
|
||||
programmer therefore needs to write VTYSH's copy of the command manually
|
||||
|
@ -31,9 +31,7 @@
|
||||
#include "eigrp_zebra.h"
|
||||
#include "eigrp_cli.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "eigrpd/eigrp_cli_clippy.c"
|
||||
#endif /* VTYSH_EXTRACT_PL */
|
||||
|
||||
/*
|
||||
* XPath: /frr-eigrpd:eigrpd/instance
|
||||
|
@ -55,9 +55,7 @@
|
||||
#include "eigrpd/eigrp_dump.h"
|
||||
#include "eigrpd/eigrp_const.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "eigrpd/eigrp_vty_clippy.c"
|
||||
#endif
|
||||
|
||||
static void eigrp_vty_display_prefix_entry(struct vty *vty, struct eigrp *eigrp,
|
||||
struct eigrp_prefix_descriptor *pe,
|
||||
|
@ -4,12 +4,6 @@
|
||||
|
||||
if EIGRPD
|
||||
sbin_PROGRAMS += eigrpd/eigrpd
|
||||
vtysh_scan += \
|
||||
eigrpd/eigrp_cli.c \
|
||||
eigrpd/eigrp_dump.c \
|
||||
eigrpd/eigrp_vty.c \
|
||||
# end
|
||||
# eigrpd/eigrp_routemap.c
|
||||
vtysh_daemons += eigrpd
|
||||
man8 += $(MANBUILD)/frr-eigrpd.8
|
||||
endif
|
||||
|
@ -37,9 +37,7 @@
|
||||
#include "isisd/isis_circuit.h"
|
||||
#include "isisd/isis_csm.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "isisd/isis_cli_clippy.c"
|
||||
#endif
|
||||
|
||||
#ifndef FABRICD
|
||||
|
||||
|
@ -5,16 +5,6 @@
|
||||
if ISISD
|
||||
noinst_LIBRARIES += isisd/libisis.a
|
||||
sbin_PROGRAMS += isisd/isisd
|
||||
vtysh_scan += \
|
||||
isisd/isis_cli.c \
|
||||
isisd/isis_ldp_sync.c \
|
||||
isisd/isis_redist.c \
|
||||
isisd/isis_spf.c \
|
||||
isisd/isis_te.c \
|
||||
isisd/isis_sr.c \
|
||||
isisd/isis_vty_fabricd.c \
|
||||
isisd/isisd.c \
|
||||
# end
|
||||
vtysh_daemons += isisd
|
||||
if SNMP
|
||||
module_LTLIBRARIES += isisd/isisd_snmp.la
|
||||
@ -25,18 +15,6 @@ endif
|
||||
if FABRICD
|
||||
noinst_LIBRARIES += isisd/libfabric.a
|
||||
sbin_PROGRAMS += isisd/fabricd
|
||||
if !ISISD
|
||||
vtysh_scan += \
|
||||
isisd/isis_cli.c \
|
||||
isisd/isis_ldp_sync.c \
|
||||
isisd/isis_redist.c \
|
||||
isisd/isis_spf.c \
|
||||
isisd/isis_te.c \
|
||||
isisd/isis_sr.c \
|
||||
isisd/isis_vty_fabricd.c \
|
||||
isisd/isisd.c \
|
||||
# end
|
||||
endif
|
||||
vtysh_daemons += fabricd
|
||||
endif
|
||||
|
||||
|
@ -25,9 +25,7 @@
|
||||
|
||||
#include "ldpd/ldpd.h"
|
||||
#include "ldpd/ldp_vty.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "ldpd/ldp_vty_cmds_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFPY_NOSH(ldp_mpls_ldp,
|
||||
ldp_mpls_ldp_cmd,
|
||||
|
@ -5,7 +5,6 @@
|
||||
if LDPD
|
||||
noinst_LIBRARIES += ldpd/libldp.a
|
||||
sbin_PROGRAMS += ldpd/ldpd
|
||||
vtysh_scan += ldpd/ldp_vty_cmds.c
|
||||
vtysh_daemons += ldpd
|
||||
man8 += $(MANBUILD)/frr-ldpd.8
|
||||
endif
|
||||
|
@ -251,9 +251,6 @@ struct cmd_node {
|
||||
/* Argc max counts. */
|
||||
#define CMD_ARGC_MAX 256
|
||||
|
||||
/* Turn off these macros when using cpp with extract.pl */
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
|
||||
/* helper defines for end-user DEFUN* macros */
|
||||
#define DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \
|
||||
static const struct cmd_element cmdname = { \
|
||||
@ -370,8 +367,6 @@ struct cmd_node {
|
||||
#define ALIAS_YANG(funcname, cmdname, cmdstr, helpstr) \
|
||||
ALIAS_ATTR(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_YANG)
|
||||
|
||||
#endif /* VTYSH_EXTRACT_PL */
|
||||
|
||||
/* Some macroes */
|
||||
|
||||
/*
|
||||
@ -511,7 +506,6 @@ struct xref_install_element {
|
||||
enum node_type node_type;
|
||||
};
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#define install_element(node_type_, cmd_element_) do { \
|
||||
static const struct xref_install_element _xref \
|
||||
__attribute__((used)) = { \
|
||||
@ -523,7 +517,6 @@ struct xref_install_element {
|
||||
XREF_LINK(_xref.xref); \
|
||||
_install_element(node_type_, cmd_element_); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
extern void _install_element(enum node_type, const struct cmd_element *);
|
||||
|
||||
|
@ -31,9 +31,7 @@
|
||||
#include "lib/plist_int.h"
|
||||
#include "lib/printfrr.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "lib/filter_cli_clippy.c"
|
||||
#endif /* VTYSH_EXTRACT_PL */
|
||||
|
||||
#define ACCESS_LIST_STR "Access list entry\n"
|
||||
#define ACCESS_LIST_ZEBRA_STR "Access list name\n"
|
||||
|
2
lib/if.c
2
lib/if.c
@ -35,9 +35,7 @@
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
#include "northbound_cli.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "lib/if_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFINE_MTYPE_STATIC(LIB, IF, "Interface");
|
||||
DEFINE_MTYPE_STATIC(LIB, CONNECTED, "Connected");
|
||||
|
@ -29,9 +29,7 @@
|
||||
#include "lib/printfrr.h"
|
||||
#include "lib/systemd.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "lib/log_vty_clippy.c"
|
||||
#endif
|
||||
|
||||
#define ZLOG_MAXLVL(a, b) MAX(a, b)
|
||||
|
||||
|
@ -28,9 +28,7 @@
|
||||
#include <command.h>
|
||||
#include <jhash.h>
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "lib/nexthop_group_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFINE_MTYPE_STATIC(LIB, NEXTHOP_GROUP, "Nexthop Group");
|
||||
|
||||
|
@ -32,9 +32,7 @@
|
||||
#include "northbound.h"
|
||||
#include "northbound_cli.h"
|
||||
#include "northbound_db.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "lib/northbound_cli_clippy.c"
|
||||
#endif
|
||||
|
||||
struct debug nb_dbg_cbs_config = {0, "Northbound callbacks: configuration"};
|
||||
struct debug nb_dbg_cbs_state = {0, "Northbound callbacks: state"};
|
||||
|
@ -1193,9 +1193,7 @@ static int vty_clear_prefix_list(struct vty *vty, afi_t afi, const char *name,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "lib/plist_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFPY (show_ip_prefix_list,
|
||||
show_ip_prefix_list_cmd,
|
||||
|
@ -26,9 +26,7 @@
|
||||
#include "lib/northbound_cli.h"
|
||||
#include "lib/routemap.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "lib/routemap_cli_clippy.c"
|
||||
#endif /* VTYSH_EXTRACT_PL */
|
||||
|
||||
#define ROUTE_MAP_CMD_STR \
|
||||
"Create route-map or enter route-map command mode\n" \
|
||||
|
@ -139,27 +139,6 @@ nodist_lib_libfrr_la_SOURCES = \
|
||||
yang/frr-module-translator.yang.c \
|
||||
# end
|
||||
|
||||
vtysh_scan += \
|
||||
lib/distribute.c \
|
||||
lib/filter.c \
|
||||
lib/filter_cli.c \
|
||||
lib/if.c \
|
||||
lib/if_rmap.c \
|
||||
lib/keychain.c \
|
||||
lib/lib_vty.c \
|
||||
lib/log_vty.c \
|
||||
lib/nexthop_group.c \
|
||||
lib/plist.c \
|
||||
lib/routemap.c \
|
||||
lib/routemap_cli.c \
|
||||
lib/spf_backoff.c \
|
||||
lib/thread.c \
|
||||
lib/vrf.c \
|
||||
lib/vty.c \
|
||||
# end
|
||||
# can be loaded as DSO - always include for vtysh
|
||||
vtysh_scan += lib/agentx.c
|
||||
|
||||
if SQLITE3
|
||||
lib_libfrr_la_LIBADD += $(SQLITE3_LIBS)
|
||||
lib_libfrr_la_SOURCES += lib/db.c
|
||||
@ -347,7 +326,6 @@ lib_libfrrsnmp_la_SOURCES = \
|
||||
if CARES
|
||||
lib_LTLIBRARIES += lib/libfrrcares.la
|
||||
pkginclude_HEADERS += lib/resolver.h
|
||||
vtysh_scan += lib/resolver.c
|
||||
endif
|
||||
|
||||
lib_libfrrcares_la_CFLAGS = $(AM_CFLAGS) $(CARES_CFLAGS)
|
||||
@ -478,13 +456,18 @@ SUFFIXES += .xref
|
||||
|
||||
# dependencies added in python/makefile.py
|
||||
frr.xref:
|
||||
$(AM_V_XRELFO) $(CLIPPY) $(top_srcdir)/python/xrelfo.py -o $@ $^
|
||||
$(AM_V_XRELFO) $(CLIPPY) $(top_srcdir)/python/xrelfo.py -o $@ -c vtysh/vtysh_cmd.c $^
|
||||
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
|
||||
|
||||
## automake's "ylwrap" is a great piece of GNU software... not.
|
||||
.l.c:
|
||||
$(AM_V_LEX)$(am__skiplex) $(LEXCOMPILE) $<
|
||||
|
@ -102,9 +102,7 @@ unsigned long cputime_threshold = CONSUMED_TIME_CHECK;
|
||||
unsigned long walltime_threshold = CONSUMED_TIME_CHECK;
|
||||
|
||||
/* CLI start ---------------------------------------------------------------- */
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "lib/thread_clippy.c"
|
||||
#endif
|
||||
|
||||
static unsigned int cpu_record_hash_key(const struct cpu_thread_history *a)
|
||||
{
|
||||
|
@ -53,9 +53,7 @@
|
||||
#include <arpa/telnet.h>
|
||||
#include <termios.h>
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "lib/vty_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFINE_MTYPE_STATIC(LIB, VTY, "VTY");
|
||||
DEFINE_MTYPE_STATIC(LIB, VTY_SERV, "VTY server");
|
||||
|
@ -202,9 +202,9 @@
|
||||
#endif /* HAVE_GLIBC_BACKTRACE */
|
||||
|
||||
/* Local includes: */
|
||||
#if !(defined(__GNUC__) || defined(VTYSH_EXTRACT_PL))
|
||||
#if !defined(__GNUC__)
|
||||
#define __attribute__(x)
|
||||
#endif /* !__GNUC__ || VTYSH_EXTRACT_PL */
|
||||
#endif /* !__GNUC__ */
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
@ -158,9 +158,7 @@ static int reconf_clear_dst(struct zlog_cfg_5424_user *cfg, struct vty *vty)
|
||||
return reconf_dst(cfg, vty);
|
||||
}
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "lib/zlog_5424_cli_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFPY_NOSH(log_5424_target,
|
||||
log_5424_target_cmd,
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
if NHRPD
|
||||
sbin_PROGRAMS += nhrpd/nhrpd
|
||||
vtysh_scan += nhrpd/nhrp_vty.c
|
||||
vtysh_daemons += nhrpd
|
||||
man8 += $(MANBUILD)/frr-nhrpd.8
|
||||
endif
|
||||
|
@ -47,9 +47,7 @@
|
||||
#include "ospf6d.h"
|
||||
#include "lib/json.h"
|
||||
#include "ospf6_nssa.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "ospf6d/ospf6_area_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_AREA, "OSPF6 area");
|
||||
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_PLISTNAME, "Prefix list name");
|
||||
|
@ -65,9 +65,7 @@ static void ospf6_asbr_redistribute_set(struct ospf6 *ospf6, int type);
|
||||
static void ospf6_asbr_redistribute_unset(struct ospf6 *ospf6,
|
||||
struct ospf6_redist *red, int type);
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "ospf6d/ospf6_asbr_clippy.c"
|
||||
#endif
|
||||
|
||||
unsigned char conf_debug_ospf6_asbr = 0;
|
||||
|
||||
|
@ -42,9 +42,7 @@
|
||||
#include "ospf6d/ospf6_intra.h"
|
||||
#include "ospf6d/ospf6_spf.h"
|
||||
#include "ospf6d/ospf6_gr.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "ospf6d/ospf6_gr_clippy.c"
|
||||
#endif
|
||||
|
||||
static void ospf6_gr_nvm_delete(struct ospf6 *ospf6);
|
||||
|
||||
|
@ -49,9 +49,7 @@
|
||||
#include "ospf6d.h"
|
||||
#include "ospf6_gr.h"
|
||||
#include "lib/json.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "ospf6d/ospf6_gr_helper_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_GR_HELPER, "OSPF6 Graceful restart helper");
|
||||
|
||||
|
@ -46,9 +46,7 @@
|
||||
#include "ospf6_flood.h"
|
||||
#include "ospf6d.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "ospf6d/ospf6_lsa_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_LSA, "OSPF6 LSA");
|
||||
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_LSA_HEADER, "OSPF6 LSA header");
|
||||
|
@ -49,9 +49,7 @@
|
||||
#include "ospf6_asbr.h"
|
||||
#include "ospf6d.h"
|
||||
#include "ospf6_nssa.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "ospf6d/ospf6_nssa_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_LSA, "OSPF6 LSA");
|
||||
unsigned char config_debug_ospf6_nssa = 0;
|
||||
|
@ -37,9 +37,7 @@
|
||||
#include "ospf6_interface.h"
|
||||
#include "ospf6d.h"
|
||||
#include "ospf6_zebra.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "ospf6d/ospf6_route_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_ROUTE, "OSPF6 route");
|
||||
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_ROUTE_TABLE, "OSPF6 route table");
|
||||
|
@ -65,9 +65,7 @@ FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES,
|
||||
{ .val_bool = false },
|
||||
);
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "ospf6d/ospf6_top_clippy.c"
|
||||
#endif
|
||||
|
||||
/* global ospf6d variable */
|
||||
static struct ospf6_master ospf6_master;
|
||||
|
@ -5,27 +5,6 @@
|
||||
if OSPF6D
|
||||
noinst_LIBRARIES += ospf6d/libospf6.a
|
||||
sbin_PROGRAMS += ospf6d/ospf6d
|
||||
vtysh_scan += \
|
||||
ospf6d/ospf6_nssa.c \
|
||||
ospf6d/ospf6_abr.c \
|
||||
ospf6d/ospf6_asbr.c \
|
||||
ospf6d/ospf6_area.c \
|
||||
ospf6d/ospf6_bfd.c \
|
||||
ospf6d/ospf6_flood.c \
|
||||
ospf6d/ospf6_gr.c \
|
||||
ospf6d/ospf6_gr_helper.c \
|
||||
ospf6d/ospf6_interface.c \
|
||||
ospf6d/ospf6_intra.c \
|
||||
ospf6d/ospf6_lsa.c \
|
||||
ospf6d/ospf6_message.c \
|
||||
ospf6d/ospf6_neighbor.c \
|
||||
ospf6d/ospf6_route.c \
|
||||
ospf6d/ospf6_spf.c \
|
||||
ospf6d/ospf6_top.c \
|
||||
ospf6d/ospf6_zebra.c \
|
||||
ospf6d/ospf6d.c \
|
||||
ospf6d/ospf6_auth_trailer.c \
|
||||
# end
|
||||
vtysh_daemons += ospf6d
|
||||
if SNMP
|
||||
module_LTLIBRARIES += ospf6d/ospf6d_snmp.la
|
||||
|
@ -42,9 +42,7 @@
|
||||
#include "ospfd/ospf_dump.h"
|
||||
#include "ospfd/ospf_packet.h"
|
||||
#include "ospfd/ospf_network.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "ospfd/ospf_dump_clippy.c"
|
||||
#endif
|
||||
|
||||
/* Configuration debug option variables. */
|
||||
unsigned long conf_debug_ospf_packet[5] = {0, 0, 0, 0, 0};
|
||||
|
@ -44,9 +44,7 @@
|
||||
#include "ospfd/ospf_gr.h"
|
||||
#include "ospfd/ospf_errors.h"
|
||||
#include "ospfd/ospf_dump.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "ospfd/ospf_gr_clippy.c"
|
||||
#endif
|
||||
|
||||
static void ospf_gr_nvm_delete(struct ospf *ospf);
|
||||
|
||||
|
@ -751,9 +751,7 @@ void ospf_ldp_sync_if_write_config(struct vty *vty,
|
||||
/*
|
||||
* LDP-SYNC commands.
|
||||
*/
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "ospfd/ospf_ldp_sync_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFPY (ospf_mpls_ldp_sync,
|
||||
ospf_mpls_ldp_sync_cmd,
|
||||
|
@ -185,9 +185,7 @@ static void ospf_show_vrf_name(struct ospf *ospf, struct vty *vty,
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "ospfd/ospf_vty_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFUN_NOSH (router_ospf,
|
||||
router_ospf_cmd,
|
||||
|
@ -5,18 +5,6 @@
|
||||
if OSPFD
|
||||
noinst_LIBRARIES += ospfd/libfrrospf.a
|
||||
sbin_PROGRAMS += ospfd/ospfd
|
||||
vtysh_scan += \
|
||||
ospfd/ospf_bfd.c \
|
||||
ospfd/ospf_dump.c \
|
||||
ospfd/ospf_gr.c \
|
||||
ospfd/ospf_ldp_sync.c \
|
||||
ospfd/ospf_opaque.c \
|
||||
ospfd/ospf_ri.c \
|
||||
ospfd/ospf_routemap.c \
|
||||
ospfd/ospf_te.c \
|
||||
ospfd/ospf_sr.c \
|
||||
ospfd/ospf_vty.c \
|
||||
# end
|
||||
vtysh_daemons += ospfd
|
||||
if SNMP
|
||||
module_LTLIBRARIES += ospfd/ospfd_snmp.la
|
||||
|
@ -31,9 +31,7 @@
|
||||
|
||||
#include "pathd/pathd.h"
|
||||
#include "pathd/path_nb.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "pathd/path_cli_clippy.c"
|
||||
#endif
|
||||
#include "pathd/path_ted.h"
|
||||
|
||||
#define XPATH_MAXATTRSIZE 64
|
||||
|
@ -40,9 +40,7 @@
|
||||
#include "pathd/path_pcep_lib.h"
|
||||
#include "pathd/path_pcep_pcc.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "pathd/path_pcep_cli_clippy.c"
|
||||
#endif
|
||||
|
||||
#define DEFAULT_PCE_PRECEDENCE 255
|
||||
#define DEFAULT_PCC_MSD 4
|
||||
|
@ -29,9 +29,7 @@
|
||||
#include "pathd/path_errors.h"
|
||||
#include "pathd/path_ted.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "pathd/path_ted_clippy.c"
|
||||
#endif
|
||||
|
||||
static struct ls_ted *path_ted_create_ted(void);
|
||||
static void path_ted_register_vty(void);
|
||||
|
@ -5,16 +5,11 @@
|
||||
if PATHD
|
||||
noinst_LIBRARIES += pathd/libpath.a
|
||||
sbin_PROGRAMS += pathd/pathd
|
||||
vtysh_scan += \
|
||||
pathd/path_cli.c \
|
||||
pathd/path_ted.c \
|
||||
#end
|
||||
vtysh_daemons += pathd
|
||||
# TODO add man page
|
||||
#man8 += $(MANBUILD)/pathd.8
|
||||
|
||||
if PATHD_PCEP
|
||||
vtysh_scan += pathd/path_pcep_cli.c
|
||||
module_LTLIBRARIES += pathd/pathd_pcep.la
|
||||
endif
|
||||
|
||||
|
@ -23,9 +23,7 @@
|
||||
#include "command.h"
|
||||
#include "vector.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "pbrd/pbr_debug_clippy.c"
|
||||
#endif
|
||||
#include "pbrd/pbr_debug.h"
|
||||
|
||||
struct debug pbr_dbg_map = {0, "PBR map"};
|
||||
|
@ -36,9 +36,7 @@
|
||||
#include "pbrd/pbr_zebra.h"
|
||||
#include "pbrd/pbr_vty.h"
|
||||
#include "pbrd/pbr_debug.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "pbrd/pbr_vty_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFUN_NOSH(pbr_map, pbr_map_cmd, "pbr-map PBRMAP seq (1-700)",
|
||||
"Create pbr-map or enter pbr-map command mode\n"
|
||||
|
@ -5,10 +5,6 @@
|
||||
if PBRD
|
||||
noinst_LIBRARIES += pbrd/libpbr.a
|
||||
sbin_PROGRAMS += pbrd/pbrd
|
||||
vtysh_scan += \
|
||||
pbrd/pbr_vty.c \
|
||||
pbrd/pbr_debug.c \
|
||||
# end
|
||||
vtysh_daemons += pbrd
|
||||
man8 += $(MANBUILD)/frr-pbrd.8
|
||||
endif
|
||||
|
@ -45,9 +45,7 @@
|
||||
#include "pim_zebra.h"
|
||||
#include "pim_instance.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "pimd/pim6_cmd_clippy.c"
|
||||
#endif
|
||||
|
||||
static struct cmd_node debug_node = {
|
||||
.name = "debug",
|
||||
|
@ -2319,9 +2319,7 @@ void gm_ifp_update(struct interface *ifp)
|
||||
|
||||
#include "lib/command.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "pimd/pim6_mld_clippy.c"
|
||||
#endif
|
||||
|
||||
static struct vrf *gm_cmd_vrf_lookup(struct vty *vty, const char *vrf_str,
|
||||
int *err)
|
||||
|
@ -70,9 +70,7 @@
|
||||
#include "pim_addr.h"
|
||||
#include "pim_cmd_common.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "pimd/pim_cmd_clippy.c"
|
||||
#endif
|
||||
|
||||
static struct cmd_node debug_node = {
|
||||
.name = "debug",
|
||||
|
@ -39,10 +39,8 @@
|
||||
#if defined(HAVE_LINUX_MROUTE_H)
|
||||
#include <linux/mroute.h>
|
||||
#else
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "linux/mroute.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct vifctl pim_vifctl;
|
||||
typedef struct igmpmsg kernmsg;
|
||||
@ -86,10 +84,8 @@ typedef struct sioc_sg_req pim_sioc_sg_req;
|
||||
#if defined(HAVE_LINUX_MROUTE6_H)
|
||||
#include <linux/mroute6.h>
|
||||
#else
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "linux/mroute6.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MRT_INIT
|
||||
#define MRT_BASE MRT6_BASE
|
||||
|
@ -6,11 +6,6 @@ if PIMD
|
||||
sbin_PROGRAMS += pimd/pimd
|
||||
bin_PROGRAMS += pimd/mtracebis
|
||||
noinst_PROGRAMS += pimd/test_igmpv3_join
|
||||
vtysh_scan += \
|
||||
pimd/pim_cmd.c \
|
||||
pimd/pim6_cmd.c \
|
||||
pimd/pim6_mld.c \
|
||||
#end
|
||||
vtysh_daemons += pimd
|
||||
vtysh_daemons += pim6d
|
||||
man8 += $(MANBUILD)/frr-pimd.8
|
||||
|
@ -1,72 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Quick demo program that checks whether files define commands that aren't
|
||||
# in vtysh. Execute after building.
|
||||
#
|
||||
# This is free and unencumbered software released into the public domain.
|
||||
#
|
||||
# Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
# distribute this software, either in source code form or as a compiled
|
||||
# binary, for any purpose, commercial or non-commercial, and by any
|
||||
# means.
|
||||
#
|
||||
# In jurisdictions that recognize copyright laws, the author or authors
|
||||
# of this software dedicate any and all copyright interest in the
|
||||
# software to the public domain. We make this dedication for the benefit
|
||||
# of the public at large and to the detriment of our heirs and
|
||||
# successors. We intend this dedication to be an overt act of
|
||||
# relinquishment in perpetuity of all present and future rights to this
|
||||
# software under copyright law.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
# OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# For more information, please refer to <http://unlicense.org/>
|
||||
|
||||
import os
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
with open("frr.xref", "r") as fd:
|
||||
data = json.load(fd)
|
||||
|
||||
vtysh_scan, _ = subprocess.Popen(
|
||||
["make", "var-vtysh_scan"], stdout=subprocess.PIPE
|
||||
).communicate()
|
||||
vtysh_scan = set(vtysh_scan.decode("US-ASCII").split())
|
||||
|
||||
check = set()
|
||||
vtysh = {}
|
||||
|
||||
for cmd, defs in data["cli"].items():
|
||||
for binary, clidef in defs.items():
|
||||
if clidef["defun"]["file"].startswith("vtysh/"):
|
||||
vtysh[clidef["string"]] = clidef
|
||||
|
||||
for cmd, defs in data["cli"].items():
|
||||
for binary, clidef in defs.items():
|
||||
if clidef["defun"]["file"].startswith("vtysh/"):
|
||||
continue
|
||||
|
||||
if clidef["defun"]["file"] not in vtysh_scan:
|
||||
vtysh_def = vtysh.get(clidef["string"])
|
||||
if vtysh_def is not None:
|
||||
print(
|
||||
"\033[33m%s defines %s, has a custom define in vtysh %s\033[m"
|
||||
% (clidef["defun"]["file"], cmd, vtysh_def["defun"]["file"])
|
||||
)
|
||||
else:
|
||||
print(
|
||||
"\033[31m%s defines %s, not in vtysh_scan\033[m"
|
||||
% (clidef["defun"]["file"], cmd)
|
||||
)
|
||||
check.add(clidef["defun"]["file"])
|
||||
|
||||
print("\nfiles to check:\n\t" + " ".join(sorted(check)))
|
386
python/xref2vtysh.py
Normal file
386
python/xref2vtysh.py
Normal file
@ -0,0 +1,386 @@
|
||||
# FRR xref vtysh command extraction
|
||||
#
|
||||
# Copyright (C) 2022 David Lamparter for NetDEF, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; see the file COPYING; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
"""
|
||||
Generate vtysh_cmd.c from frr .xref file(s).
|
||||
|
||||
This can run either standalone or as part of xrelfo. The latter saves a
|
||||
non-negligible amount of time (0.5s on average systems, more on e.g. slow ARMs)
|
||||
since serializing and deserializing JSON is a significant bottleneck in this.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import pathlib
|
||||
import argparse
|
||||
from collections import defaultdict
|
||||
import difflib
|
||||
|
||||
import typing
|
||||
from typing import (
|
||||
Dict,
|
||||
List,
|
||||
)
|
||||
|
||||
import json
|
||||
|
||||
try:
|
||||
import ujson as json # type: ignore
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
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
|
||||
# not quite obvious...
|
||||
|
||||
daemon_flags = {
|
||||
"lib/agentx.c": "VTYSH_ISISD|VTYSH_RIPD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA",
|
||||
"lib/filter.c": "VTYSH_ACL",
|
||||
"lib/filter_cli.c": "VTYSH_ACL",
|
||||
"lib/if.c": "VTYSH_INTERFACE",
|
||||
"lib/keychain.c": "VTYSH_RIPD|VTYSH_EIGRPD|VTYSH_OSPF6D",
|
||||
"lib/lib_vty.c": "VTYSH_ALL",
|
||||
"lib/log_vty.c": "VTYSH_ALL",
|
||||
"lib/nexthop_group.c": "VTYSH_NH_GROUP",
|
||||
"lib/resolver.c": "VTYSH_NHRPD|VTYSH_BGPD",
|
||||
"lib/routemap.c": "VTYSH_RMAP",
|
||||
"lib/routemap_cli.c": "VTYSH_RMAP",
|
||||
"lib/spf_backoff.c": "VTYSH_ISISD",
|
||||
"lib/thread.c": "VTYSH_ALL",
|
||||
"lib/vrf.c": "VTYSH_VRF",
|
||||
"lib/vty.c": "VTYSH_ALL",
|
||||
}
|
||||
|
||||
vtysh_cmd_head = """/* autogenerated file, DO NOT EDIT! */
|
||||
#include <zebra.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "linklist.h"
|
||||
|
||||
#include "vtysh/vtysh.h"
|
||||
"""
|
||||
|
||||
if sys.stderr.isatty():
|
||||
_fmt_red = "\033[31m"
|
||||
_fmt_green = "\033[32m"
|
||||
_fmt_clear = "\033[m"
|
||||
else:
|
||||
_fmt_red = _fmt_green = _fmt_clear = ""
|
||||
|
||||
|
||||
def c_escape(text: str) -> str:
|
||||
"""
|
||||
Escape string for output into C source code.
|
||||
|
||||
Handles only what's needed here. CLI strings and help text don't contain
|
||||
weird special characters.
|
||||
"""
|
||||
return text.replace("\\", "\\\\").replace('"', '\\"').replace("\n", "\\n")
|
||||
|
||||
|
||||
class NodeDict(defaultdict):
|
||||
"""
|
||||
CLI node ID (integer) -> dict of commands in that node.
|
||||
"""
|
||||
|
||||
nodenames: Dict[int, str] = {}
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(dict)
|
||||
|
||||
def items_named(self):
|
||||
for k, v in self.items():
|
||||
yield self.nodename(k), v
|
||||
|
||||
@classmethod
|
||||
def nodename(cls, nodeid: int) -> str:
|
||||
return cls.nodenames.get(nodeid, str(nodeid))
|
||||
|
||||
@classmethod
|
||||
def load_nodenames(cls):
|
||||
with open(os.path.join(frr_top_src, "lib", "command.h"), "r") as fd:
|
||||
command_h = fd.read()
|
||||
|
||||
nodes = re.search(r"enum\s+node_type\s+\{(.*?)\}", command_h, re.S)
|
||||
if nodes is None:
|
||||
raise RuntimeError(
|
||||
"regex failed to match on lib/command.h (to get CLI node names)"
|
||||
)
|
||||
|
||||
text = nodes.group(1)
|
||||
text = re.sub(r"/\*.*?\*/", "", text, flags=re.S)
|
||||
text = re.sub(r"//.*?$", "", text, flags=re.M)
|
||||
text = text.replace(",", " ")
|
||||
text = text.split()
|
||||
|
||||
for i, name in enumerate(text):
|
||||
cls.nodenames[i] = name
|
||||
|
||||
|
||||
class CommandEntry:
|
||||
"""
|
||||
CLI command definition.
|
||||
|
||||
- one DEFUN creates at most one of these, even if the same command is
|
||||
installed in multiple CLI nodes (e.g. BGP address-family nodes)
|
||||
- for each CLI node, commands with the same CLI string are merged. This
|
||||
is *almost* irrelevant - ospfd & ospf6d define some identical commands
|
||||
in the route-map node. Those must be merged for things to work
|
||||
correctly.
|
||||
"""
|
||||
|
||||
all_defs: List["CommandEntry"] = []
|
||||
warn_counter = 0
|
||||
|
||||
def __init__(self, origin, name, spec):
|
||||
self.origin = origin
|
||||
self.name = name
|
||||
self._spec = spec
|
||||
self._registered = False
|
||||
|
||||
self.cmd = spec["string"]
|
||||
self._cmd_normalized = self.normalize_cmd(self.cmd)
|
||||
|
||||
self.hidden = "hidden" in spec.get("attrs", [])
|
||||
self.daemons = self._get_daemons()
|
||||
|
||||
self.doclines = self._spec["doc"].splitlines(keepends=True)
|
||||
if not self.doclines[-1].endswith("\n"):
|
||||
self.warn_loc("docstring does not end with \\n")
|
||||
|
||||
def warn_loc(self, wtext, nodename=None):
|
||||
"""
|
||||
Print warning with parseable (compiler style) location
|
||||
|
||||
Matching the way compilers emit file/lineno means editors/IDE can
|
||||
identify / jump to the error location.
|
||||
"""
|
||||
|
||||
if nodename:
|
||||
prefix = ": [%s] %s:" % (nodename, self.name)
|
||||
else:
|
||||
prefix = ": %s:" % (self.name,)
|
||||
|
||||
for line in wtext.rstrip("\n").split("\n"):
|
||||
sys.stderr.write(
|
||||
"%s:%d%s %s\n"
|
||||
% (
|
||||
self._spec["defun"]["file"],
|
||||
self._spec["defun"]["line"],
|
||||
prefix,
|
||||
line,
|
||||
)
|
||||
)
|
||||
prefix = "- "
|
||||
|
||||
CommandEntry.warn_counter += 1
|
||||
|
||||
def _get_daemons(self):
|
||||
path = pathlib.Path(self.origin)
|
||||
if path.name == "vtysh":
|
||||
return {}
|
||||
|
||||
defun_file = os.path.relpath(self._spec["defun"]["file"], frr_top_src)
|
||||
defun_path = pathlib.Path(defun_file)
|
||||
|
||||
if defun_path.parts[0] != "lib":
|
||||
if "." not in path.name:
|
||||
# daemons don't have dots in their filename
|
||||
return {"VTYSH_" + path.name.upper()}
|
||||
|
||||
# loadable modules - use directory name to determine daemon
|
||||
return {"VTYSH_" + path.parts[-2].upper()}
|
||||
|
||||
if defun_file in daemon_flags:
|
||||
return {daemon_flags[defun_file]}
|
||||
|
||||
v6_cmd = "ipv6" in self.name
|
||||
if defun_file == "lib/plist.c":
|
||||
if v6_cmd:
|
||||
return {
|
||||
"VTYSH_RIPNGD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIM6D|VTYSH_BABELD|VTYSH_ISISD|VTYSH_FABRICD"
|
||||
}
|
||||
else:
|
||||
return {
|
||||
"VTYSH_RIPD|VTYSH_OSPFD|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_ISISD|VTYSH_FABRICD"
|
||||
}
|
||||
|
||||
if defun_file == "lib/if_rmap.c":
|
||||
if v6_cmd:
|
||||
return {"VTYSH_RIPNGD"}
|
||||
else:
|
||||
return {"VTYSH_RIPD"}
|
||||
|
||||
return {}
|
||||
|
||||
def __repr__(self):
|
||||
return f"<CommandEntry {self.name}: {self.cmd!r}>"
|
||||
|
||||
def register(self):
|
||||
"""Track DEFUNs so each is only output once."""
|
||||
if not self._registered:
|
||||
self.all_defs.append(self)
|
||||
self._registered = True
|
||||
return self
|
||||
|
||||
def merge(self, other, nodename):
|
||||
if self._cmd_normalized != other._cmd_normalized:
|
||||
self.warn_loc(
|
||||
f"command definition mismatch, first definied as:\n{self.cmd!r}",
|
||||
nodename=nodename,
|
||||
)
|
||||
other.warn_loc(f"later defined as:\n{other.cmd!r}", nodename=nodename)
|
||||
|
||||
if self._spec["doc"] != other._spec["doc"]:
|
||||
self.warn_loc(
|
||||
f"help string mismatch, first defined here (-)", nodename=nodename
|
||||
)
|
||||
other.warn_loc(
|
||||
f"later defined here (+)\nnote: both commands define {self.cmd!r} in same node ({nodename})",
|
||||
nodename=nodename,
|
||||
)
|
||||
|
||||
d = difflib.Differ()
|
||||
for diffline in d.compare(self.doclines, other.doclines):
|
||||
if diffline.startswith(" "):
|
||||
continue
|
||||
if diffline.startswith("+ "):
|
||||
diffline = _fmt_green + diffline
|
||||
elif diffline.startswith("- "):
|
||||
diffline = _fmt_red + diffline
|
||||
sys.stderr.write("\t" + diffline.rstrip("\n") + _fmt_clear + "\n")
|
||||
|
||||
if self.hidden != other.hidden:
|
||||
self.warn_loc(
|
||||
f"hidden flag mismatch, first {self.hidden!r} here", nodename=nodename
|
||||
)
|
||||
other.warn_loc(
|
||||
f"later {other.hidden!r} here (+)\nnote: both commands define {self.cmd!r} in same node ({nodename})",
|
||||
nodename=nodename,
|
||||
)
|
||||
|
||||
# ensure name is deterministic regardless of input DEFUN order
|
||||
self.name = min([self.name, other.name], key=lambda i: (len(i), i))
|
||||
self.daemons.update(other.daemons)
|
||||
|
||||
def get_def(self):
|
||||
doc = "\n".join(['\t"%s"' % c_escape(line) for line in self.doclines])
|
||||
defsh = "DEFSH_HIDDEN" if self.hidden else "DEFSH"
|
||||
|
||||
# make daemon list deterministic
|
||||
daemons = set()
|
||||
for daemon in self.daemons:
|
||||
daemons.update(daemon.split("|"))
|
||||
daemon_str = "|".join(sorted(daemons))
|
||||
|
||||
return f"""
|
||||
{defsh} ({daemon_str}, {self.name}_vtysh,
|
||||
\t"{c_escape(self.cmd)}",
|
||||
{doc})
|
||||
"""
|
||||
|
||||
# accept slightly different command definitions that result in the same command
|
||||
re_collapse_ws = re.compile(r"\s+")
|
||||
re_remove_varnames = re.compile(r"\$[a-z][a-z0-9_]*")
|
||||
|
||||
@classmethod
|
||||
def normalize_cmd(cls, cmd):
|
||||
cmd = cmd.strip()
|
||||
cmd = cls.re_collapse_ws.sub(" ", cmd)
|
||||
cmd = cls.re_remove_varnames.sub("", cmd)
|
||||
return cmd
|
||||
|
||||
@classmethod
|
||||
def process(cls, nodes, name, origin, spec):
|
||||
if "nosh" in spec.get("attrs", []):
|
||||
return
|
||||
if origin == "vtysh/vtysh":
|
||||
return
|
||||
|
||||
if origin == "isisd/fabricd":
|
||||
# dirty workaround :(
|
||||
name = "fabricd_" + name
|
||||
|
||||
entry = cls(origin, name, spec)
|
||||
if not entry.daemons:
|
||||
return
|
||||
|
||||
for nodedata in spec.get("nodes", []):
|
||||
node = nodes[nodedata["node"]]
|
||||
if entry._cmd_normalized not in node:
|
||||
node[entry._cmd_normalized] = entry.register()
|
||||
else:
|
||||
node[entry._cmd_normalized].merge(
|
||||
entry, nodes.nodename(nodedata["node"])
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def load(cls, xref):
|
||||
nodes = NodeDict()
|
||||
|
||||
for cmd_name, origins in xref.get("cli", {}).items():
|
||||
for origin, spec in origins.items():
|
||||
CommandEntry.process(nodes, cmd_name, origin, spec)
|
||||
return nodes
|
||||
|
||||
@classmethod
|
||||
def output_defs(cls, ofd):
|
||||
for entry in sorted(cls.all_defs, key=lambda i: i.name):
|
||||
ofd.write(entry.get_def())
|
||||
|
||||
@classmethod
|
||||
def output_install(cls, ofd, nodes):
|
||||
ofd.write("\nvoid vtysh_init_cmd(void)\n{\n")
|
||||
|
||||
for name, items in sorted(nodes.items_named()):
|
||||
for item in sorted(items.values(), key=lambda i: i.name):
|
||||
ofd.write(f"\tinstall_element({name}, &{item.name}_vtysh);\n")
|
||||
|
||||
ofd.write("}\n")
|
||||
|
||||
@classmethod
|
||||
def run(cls, xref, ofd):
|
||||
ofd.write(vtysh_cmd_head)
|
||||
|
||||
NodeDict.load_nodenames()
|
||||
nodes = cls.load(xref)
|
||||
cls.output_defs(ofd)
|
||||
cls.output_install(ofd, nodes)
|
||||
|
||||
|
||||
def main():
|
||||
argp = argparse.ArgumentParser(description="FRR xref to vtysh defs")
|
||||
argp.add_argument(
|
||||
"xreffile", metavar="XREFFILE", type=str, help=".xref file to read"
|
||||
)
|
||||
argp.add_argument("-Werror", action="store_const", const=True)
|
||||
args = argp.parse_args()
|
||||
|
||||
with open(args.xreffile, "r") as fd:
|
||||
data = json.load(fd)
|
||||
|
||||
CommandEntry.run(data, sys.stdout)
|
||||
|
||||
if args.Werror and CommandEntry.warn_counter:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -37,6 +37,7 @@ from clippy.uidhash import uidhash
|
||||
from clippy.elf import *
|
||||
from clippy import frr_top_src, CmdAttr
|
||||
from tiabwarfo import FieldApplicator
|
||||
from xref2vtysh import CommandEntry
|
||||
|
||||
try:
|
||||
with open(os.path.join(frr_top_src, 'python', 'xrefstructs.json'), 'r') as fd:
|
||||
@ -366,6 +367,7 @@ 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('-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)
|
||||
@ -435,5 +437,13 @@ def _main(args):
|
||||
json.dump(outbyfile, fd, indent=2, sort_keys=True, **json_dump_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)
|
||||
if args.Werror and CommandEntry.warn_counter:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@ -30,9 +30,7 @@
|
||||
|
||||
#include "ripd/ripd.h"
|
||||
#include "ripd/rip_nb.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "ripd/rip_cli_clippy.c"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* XPath: /frr-ripd:ripd/instance
|
||||
|
@ -4,11 +4,6 @@
|
||||
|
||||
if RIPD
|
||||
sbin_PROGRAMS += ripd/ripd
|
||||
vtysh_scan += \
|
||||
ripd/rip_cli.c \
|
||||
ripd/rip_debug.c \
|
||||
ripd/ripd.c \
|
||||
# end
|
||||
vtysh_daemons += ripd
|
||||
|
||||
if SNMP
|
||||
|
@ -30,9 +30,7 @@
|
||||
|
||||
#include "ripngd/ripngd.h"
|
||||
#include "ripngd/ripng_nb.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "ripngd/ripng_cli_clippy.c"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* XPath: /frr-ripngd:ripngd/instance
|
||||
|
@ -4,11 +4,6 @@
|
||||
|
||||
if RIPNGD
|
||||
sbin_PROGRAMS += ripngd/ripngd
|
||||
vtysh_scan += \
|
||||
ripngd/ripng_cli.c \
|
||||
ripngd/ripng_debug.c \
|
||||
ripngd/ripngd.c \
|
||||
# end
|
||||
vtysh_daemons += ripngd
|
||||
man8 += $(MANBUILD)/frr-ripngd.8
|
||||
endif
|
||||
|
@ -37,9 +37,7 @@
|
||||
#include "sharpd/sharp_zebra.h"
|
||||
#include "sharpd/sharp_nht.h"
|
||||
#include "sharpd/sharp_vty.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "sharpd/sharp_vty_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFINE_MTYPE_STATIC(SHARPD, SRV6_LOCATOR, "SRv6 Locator");
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
if SHARPD
|
||||
noinst_LIBRARIES += sharpd/libsharp.a
|
||||
sbin_PROGRAMS += sharpd/sharpd
|
||||
vtysh_scan += sharpd/sharp_vty.c
|
||||
vtysh_daemons += sharpd
|
||||
man8 += $(MANBUILD)/frr-sharpd.8
|
||||
endif
|
||||
|
@ -36,9 +36,7 @@
|
||||
#include "static_vty.h"
|
||||
#include "static_routes.h"
|
||||
#include "static_debug.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "staticd/static_vty_clippy.c"
|
||||
#endif
|
||||
#include "static_nb.h"
|
||||
|
||||
#define STATICD_STR "Static route daemon\n"
|
||||
|
@ -5,7 +5,6 @@
|
||||
if STATICD
|
||||
noinst_LIBRARIES += staticd/libstatic.a
|
||||
sbin_PROGRAMS += staticd/staticd
|
||||
vtysh_scan += staticd/static_vty.c
|
||||
vtysh_daemons += staticd
|
||||
man8 += $(MANBUILD)/frr-staticd.8
|
||||
endif
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
if VRRPD
|
||||
sbin_PROGRAMS += vrrpd/vrrpd
|
||||
vtysh_scan += vrrpd/vrrp_vty.c
|
||||
vtysh_daemons += vrrpd
|
||||
man8 += $(MANBUILD)/frr-vrrpd.8
|
||||
endif
|
||||
|
@ -33,9 +33,7 @@
|
||||
#include "vrrp_debug.h"
|
||||
#include "vrrp_vty.h"
|
||||
#include "vrrp_zebra.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "vrrpd/vrrp_vty_clippy.c"
|
||||
#endif
|
||||
|
||||
|
||||
#define VRRP_STR "Virtual Router Redundancy Protocol\n"
|
||||
|
4
vtysh/.gitignore
vendored
4
vtysh/.gitignore
vendored
@ -1,4 +1,6 @@
|
||||
vtysh
|
||||
vtysh_cmd.c
|
||||
extract.pl
|
||||
vtysh_daemons.h
|
||||
|
||||
# does not exist anymore - remove 2023-10-04 or so
|
||||
extract.pl
|
||||
|
@ -1,282 +0,0 @@
|
||||
#! @PERL@
|
||||
##
|
||||
## @configure_input@
|
||||
##
|
||||
## Virtual terminal interface shell command extractor.
|
||||
## Copyright (C) 2000 Kunihiro Ishiguro
|
||||
##
|
||||
## This file is part of GNU Zebra.
|
||||
##
|
||||
## GNU Zebra is free software; you can redistribute it and/or modify it
|
||||
## under the terms of the GNU General Public License as published by the
|
||||
## Free Software Foundation; either version 2, or (at your option) any
|
||||
## later version.
|
||||
##
|
||||
## GNU Zebra is distributed in the hope that it will be useful, but
|
||||
## WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
## General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with GNU Zebra; see the file COPYING. If not, write to the Free
|
||||
## Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
## 02111-1307, USA.
|
||||
##
|
||||
|
||||
use Getopt::Long;
|
||||
|
||||
print <<EOF;
|
||||
#include <zebra.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "linklist.h"
|
||||
|
||||
#include "vtysh/vtysh.h"
|
||||
|
||||
EOF
|
||||
|
||||
my $cli_stomp = 0;
|
||||
|
||||
sub scan_file {
|
||||
my ( $file, $fabricd) = @_;
|
||||
|
||||
$cppadd = $fabricd ? "-DFABRICD=1" : "";
|
||||
|
||||
$command_line = "@CPP@ -P -std=gnu11 -DHAVE_CONFIG_H -DVTYSH_EXTRACT_PL -Ivtysh/@top_builddir@ -Ivtysh/@top_srcdir@ -Ivtysh/@top_srcdir@/lib -Ivtysh/@top_builddir@/lib -Ivtysh/@top_srcdir@/bgpd -Ivtysh/@top_srcdir@/bgpd/rfapi @LUA_INCLUDE@ @CPPFLAGS@ @LIBYANG_CFLAGS@ $cppadd $file |";
|
||||
open (FH, $command_line)
|
||||
|| die "Open to the pipeline failed: $!\n\nCommand Issued:\n$command_line";
|
||||
local $/; undef $/;
|
||||
$line = <FH>;
|
||||
if (!close (FH)) {
|
||||
die "File: $file failed to compile:\n$!\nwhen extracting cli from it please inspect\n"
|
||||
}
|
||||
|
||||
# ?: makes a group non-capturing
|
||||
@defun = ($line =~ /((?:DEFUN|DEFUN_HIDDEN|DEFUN_YANG|ALIAS|ALIAS_HIDDEN|ALIAS_YANG|DEFPY|DEFPY_HIDDEN|DEFPY_YANG)\s*\(.+?\));?\s?\s?\n/sg);
|
||||
@install = ($line =~ /install_element\s*\(\s*[0-9A-Z_]+,\s*&[^;]*;\s*\n/sg);
|
||||
|
||||
# DEFUN process
|
||||
foreach (@defun) {
|
||||
# $_ will contain the entire string including the DEFUN, ALIAS, etc.
|
||||
# We need to extract the DEFUN/ALIAS from everything in ()s.
|
||||
# The /s at the end tells the regex to allow . to match newlines.
|
||||
$_ =~ /^(.*?)\s*\((.*)\)$/s;
|
||||
|
||||
my (@defun_array);
|
||||
$defun_or_alias = $1;
|
||||
@defun_array = split (/,/, $2);
|
||||
|
||||
if ($defun_or_alias =~ /_HIDDEN/) {
|
||||
$hidden = 1;
|
||||
} else {
|
||||
$hidden = 0;
|
||||
}
|
||||
|
||||
$defun_array[0] = '';
|
||||
|
||||
# Actual input command string.
|
||||
$str = "$defun_array[2]";
|
||||
$str =~ s/^\s+//g;
|
||||
$str =~ s/\s+$//g;
|
||||
|
||||
# Get VTY command structure. This is needed for searching
|
||||
# install_element() command.
|
||||
$cmd = "$defun_array[1]";
|
||||
$cmd =~ s/^\s+//g;
|
||||
$cmd =~ s/\s+$//g;
|
||||
|
||||
if ($fabricd) {
|
||||
$cmd = "fabricd_" . $cmd;
|
||||
}
|
||||
|
||||
# $protocol is VTYSH_PROTO format for redirection of user input
|
||||
if ($file =~ /lib\/keychain\.c$/) {
|
||||
$protocol = "VTYSH_RIPD|VTYSH_EIGRPD|VTYSH_OSPF6D";
|
||||
}
|
||||
elsif ($file =~ /lib\/routemap\.c$/ || $file =~ /lib\/routemap_cli\.c$/) {
|
||||
$protocol = "VTYSH_RMAP";
|
||||
}
|
||||
elsif ($file =~ /lib\/vrf\.c$/) {
|
||||
$protocol = "VTYSH_VRF";
|
||||
}
|
||||
elsif ($file =~ /lib\/if\.c$/) {
|
||||
$protocol = "VTYSH_INTERFACE";
|
||||
}
|
||||
elsif ($file =~ /lib\/(filter|filter_cli)\.c$/) {
|
||||
$protocol = "VTYSH_ACL";
|
||||
}
|
||||
elsif ($file =~ /lib\/(lib|log)_vty\.c$/) {
|
||||
$protocol = "VTYSH_ALL";
|
||||
}
|
||||
elsif ($file =~ /lib\/agentx\.c$/) {
|
||||
$protocol = "VTYSH_ISISD|VTYSH_RIPD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA";
|
||||
}
|
||||
elsif ($file =~ /lib\/nexthop_group\.c$/) {
|
||||
$protocol = "VTYSH_NH_GROUP";
|
||||
}
|
||||
elsif ($file =~ /lib\/plist\.c$/) {
|
||||
if ($defun_array[1] =~ m/ipv6/) {
|
||||
$protocol = "VTYSH_RIPNGD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIM6D|VTYSH_BABELD|VTYSH_ISISD|VTYSH_FABRICD";
|
||||
} else {
|
||||
$protocol = "VTYSH_RIPD|VTYSH_OSPFD|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_ISISD|VTYSH_FABRICD";
|
||||
}
|
||||
}
|
||||
elsif ($file =~ /lib\/if_rmap\.c$/) {
|
||||
if ($defun_array[1] =~ m/ipv6/) {
|
||||
$protocol = "VTYSH_RIPNGD";
|
||||
} else {
|
||||
$protocol = "VTYSH_RIPD";
|
||||
}
|
||||
}
|
||||
elsif ($file =~ /lib\/resolver\.c$/) {
|
||||
$protocol = "VTYSH_NHRPD|VTYSH_BGPD";
|
||||
}
|
||||
elsif ($file =~ /lib\/spf_backoff\.c$/) {
|
||||
$protocol = "VTYSH_ISISD";
|
||||
}
|
||||
elsif ($file =~ /lib\/(vty|thread)\.c$/) {
|
||||
$protocol = "VTYSH_ALL";
|
||||
}
|
||||
elsif ($file =~ /librfp\/.*\.c$/ || $file =~ /rfapi\/.*\.c$/) {
|
||||
$protocol = "VTYSH_BGPD";
|
||||
}
|
||||
elsif ($fabricd) {
|
||||
$protocol = "VTYSH_FABRICD";
|
||||
}
|
||||
elsif ($file =~ /pimd\/pim6_.*\.c$/) {
|
||||
$protocol = "VTYSH_PIM6D";
|
||||
}
|
||||
else {
|
||||
($protocol) = ($file =~ /^(?:.*\/)?([a-z0-9]+)\/[a-zA-Z0-9_\-]+\.c$/);
|
||||
$protocol = "VTYSH_" . uc $protocol;
|
||||
}
|
||||
|
||||
# Append _vtysh to structure then build DEFUN again
|
||||
$defun_array[1] = $cmd . "_vtysh";
|
||||
$defun_body = join (", ", @defun_array);
|
||||
|
||||
# $cmd -> $str hash for lookup
|
||||
if (exists($cmd2str{$cmd})) {
|
||||
warn "Duplicate CLI Function: $cmd\n";
|
||||
warn "\tFrom cli: $cmd2str{$cmd} to New cli: $str\n";
|
||||
warn "\tOriginal Protocol: $cmd2proto{$cmd} to New Protocol: $protocol\n";
|
||||
$cli_stomp++;
|
||||
}
|
||||
$cmd2str{$cmd} = $str;
|
||||
$cmd2defun{$cmd} = $defun_body;
|
||||
$cmd2proto{$cmd} = $protocol;
|
||||
$cmd2hidden{$cmd} = $hidden;
|
||||
}
|
||||
|
||||
# install_element() process
|
||||
foreach (@install) {
|
||||
my (@element_array);
|
||||
@element_array = split (/,/);
|
||||
|
||||
# Install node
|
||||
$enode = $element_array[0];
|
||||
$enode =~ s/^\s+//g;
|
||||
$enode =~ s/\s+$//g;
|
||||
($enode) = ($enode =~ /([0-9A-Z_]+)$/);
|
||||
|
||||
# VTY command structure.
|
||||
($ecmd) = ($element_array[1] =~ /&([^\)]+)/);
|
||||
$ecmd =~ s/^\s+//g;
|
||||
$ecmd =~ s/\s+$//g;
|
||||
|
||||
if ($fabricd) {
|
||||
$ecmd = "fabricd_" . $ecmd;
|
||||
}
|
||||
|
||||
# Register $ecmd
|
||||
if (defined ($cmd2str{$ecmd})) {
|
||||
my ($key);
|
||||
$key = $enode . "," . $cmd2str{$ecmd};
|
||||
$ocmd{$key} = $ecmd;
|
||||
$odefun{$key} = $cmd2defun{$ecmd};
|
||||
|
||||
if ($cmd2hidden{$ecmd}) {
|
||||
$defsh{$key} = "DEFSH_HIDDEN"
|
||||
} else {
|
||||
$defsh{$key} = "DEFSH"
|
||||
}
|
||||
push (@{$oproto{$key}}, $cmd2proto{$ecmd});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $have_isisd = 0;
|
||||
my $have_fabricd = 0;
|
||||
|
||||
GetOptions('have-isisd' => \$have_isisd, 'have-fabricd' => \$have_fabricd);
|
||||
|
||||
foreach (@ARGV) {
|
||||
if (/(^|\/)isisd\//) {
|
||||
# We scan all the IS-IS files twice, once for isisd,
|
||||
# once for fabricd. Exceptions are made for the files
|
||||
# that are not shared between the two.
|
||||
if (/isis_vty_isisd.c/) {
|
||||
if ( $have_isisd ) {
|
||||
scan_file($_, 0);
|
||||
}
|
||||
} elsif (/isis_vty_fabricd.c/) {
|
||||
if ( $have_fabricd ) {
|
||||
scan_file($_, 1);
|
||||
}
|
||||
} else {
|
||||
if ( $have_isisd ) {
|
||||
scan_file($_, 0);
|
||||
}
|
||||
if ( $have_fabricd ) {
|
||||
scan_file($_, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
scan_file($_, 0);
|
||||
}
|
||||
}
|
||||
|
||||
# When we have cli commands that map to the same function name, we
|
||||
# can introduce subtle bugs due to code not being called when
|
||||
# we think it is.
|
||||
#
|
||||
# If extract.pl fails with a error message and you've been
|
||||
# modifying the cli, then go back and fix your code to
|
||||
# not have cli command function collisions.
|
||||
# please fix your code before submittal
|
||||
if ($cli_stomp) {
|
||||
warn "There are $cli_stomp command line stomps\n";
|
||||
}
|
||||
|
||||
# Check finaly alive $cmd;
|
||||
foreach (keys %odefun) {
|
||||
my ($node, $str) = (split (/,/));
|
||||
my ($cmd) = $ocmd{$_};
|
||||
$live{$cmd} = $_;
|
||||
}
|
||||
|
||||
# Output DEFSH
|
||||
foreach (sort keys %live) {
|
||||
my ($proto);
|
||||
my ($key);
|
||||
$key = $live{$_};
|
||||
$proto = join ("|", @{$oproto{$key}});
|
||||
printf "$defsh{$key} ($proto$odefun{$key})\n\n";
|
||||
}
|
||||
|
||||
# Output install_element
|
||||
print <<EOF;
|
||||
void vtysh_init_cmd(void)
|
||||
{
|
||||
EOF
|
||||
|
||||
foreach (sort keys %odefun) {
|
||||
my ($node, $str) = (split (/,/));
|
||||
$cmd = $ocmd{$_};
|
||||
$cmd =~ s/_cmd$/_cmd_vtysh/;
|
||||
printf " install_element ($node, &$cmd);\n";
|
||||
}
|
||||
|
||||
print <<EOF
|
||||
}
|
||||
EOF
|
@ -20,7 +20,6 @@ vtysh_vtysh_SOURCES = \
|
||||
nodist_vtysh_vtysh_SOURCES = \
|
||||
vtysh/vtysh_cmd.c \
|
||||
# end
|
||||
CLEANFILES += vtysh/vtysh_cmd.c
|
||||
|
||||
noinst_HEADERS += \
|
||||
vtysh/vtysh.h \
|
||||
@ -39,23 +38,3 @@ $(vtysh_vtysh_OBJECTS): vtysh/vtysh_daemons.h
|
||||
CLEANFILES += vtysh/vtysh_daemons.h
|
||||
vtysh/vtysh_daemons.h:
|
||||
$(PERL) $(top_srcdir)/vtysh/daemons.pl $(vtysh_daemons) > vtysh/vtysh_daemons.h
|
||||
|
||||
AM_V_EXTRACT = $(am__v_EXTRACT_$(V))
|
||||
am__v_EXTRACT_ = $(am__v_EXTRACT_$(AM_DEFAULT_VERBOSITY))
|
||||
am__v_EXTRACT_0 = @echo " EXTRACT " $@;
|
||||
am__v_EXTRACT_1 =
|
||||
|
||||
if ISISD
|
||||
HAVE_ISISD = --have-isisd
|
||||
else
|
||||
HAVE_ISISD =
|
||||
endif
|
||||
|
||||
if FABRICD
|
||||
HAVE_FABRICD = --have-fabricd
|
||||
else
|
||||
HAVE_FABRICD =
|
||||
endif
|
||||
|
||||
vtysh/vtysh_cmd.c: vtysh/extract.pl $(vtysh_scan)
|
||||
$(AM_V_EXTRACT) $^ $(HAVE_ISISD) $(HAVE_FABRICD) > vtysh/vtysh_cmd.c
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
if WATCHFRR
|
||||
sbin_PROGRAMS += watchfrr/watchfrr
|
||||
vtysh_scan += watchfrr/watchfrr_vty.c
|
||||
man8 += $(MANBUILD)/frr-watchfrr.8
|
||||
endif
|
||||
|
||||
|
@ -153,9 +153,7 @@ DEFUN_NOSH (show_logging,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "watchfrr/watchfrr_vty_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFPY (watchfrr_ignore_daemon,
|
||||
watchfrr_ignore_daemon_cmd,
|
||||
|
@ -23,9 +23,7 @@
|
||||
#include "command.h"
|
||||
#include "debug.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "zebra/debug_clippy.c"
|
||||
#endif
|
||||
|
||||
/* For debug statement. */
|
||||
unsigned long zebra_debug_event;
|
||||
|
@ -23,9 +23,7 @@
|
||||
#include "lib/json.h"
|
||||
#include "zebra/dpdk/zebra_dplane_dpdk.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "zebra/dpdk/zebra_dplane_dpdk_vty_clippy.c"
|
||||
#endif
|
||||
|
||||
#define ZD_STR "Zebra dataplane information\n"
|
||||
#define ZD_DPDK_STR "DPDK offload information\n"
|
||||
|
@ -2603,9 +2603,7 @@ static void interface_update_stats(void)
|
||||
#endif /* HAVE_NET_RT_IFLIST */
|
||||
}
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "zebra/interface_clippy.c"
|
||||
#endif
|
||||
/* Show all interfaces to vty. */
|
||||
DEFPY(show_interface, show_interface_cmd,
|
||||
"show interface vrf NAME$vrf_name [brief$brief] [json$uj]",
|
||||
|
@ -51,9 +51,7 @@ static uint32_t interfaces_configured_for_ra_from_bgp;
|
||||
|
||||
#if defined(HAVE_RTADV)
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "zebra/rtadv_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, RTADV_PREFIX, "Router Advertisement Prefix");
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, ADV_IF, "Advertised Interface");
|
||||
|
@ -4,29 +4,6 @@
|
||||
|
||||
if ZEBRA
|
||||
sbin_PROGRAMS += zebra/zebra
|
||||
vtysh_scan += \
|
||||
zebra/debug.c \
|
||||
zebra/interface.c \
|
||||
zebra/router-id.c \
|
||||
zebra/rtadv.c \
|
||||
zebra/zebra_gr.c \
|
||||
zebra/zebra_mlag_vty.c \
|
||||
zebra/zebra_evpn_mh.c \
|
||||
zebra/zebra_mpls_vty.c \
|
||||
zebra/zebra_srv6_vty.c \
|
||||
zebra/zebra_ptm.c \
|
||||
zebra/zebra_pw.c \
|
||||
zebra/zebra_routemap.c \
|
||||
zebra/zebra_vty.c \
|
||||
zebra/zserv.c \
|
||||
zebra/zebra_vrf.c \
|
||||
zebra/dpdk/zebra_dplane_dpdk_vty.c \
|
||||
# end
|
||||
|
||||
# can be loaded as DSO - always include for vtysh
|
||||
vtysh_scan += zebra/irdp_interface.c
|
||||
vtysh_scan += zebra/zebra_fpm.c
|
||||
|
||||
vtysh_daemons += zebra
|
||||
|
||||
if IRDP
|
||||
@ -255,8 +232,6 @@ module_LTLIBRARIES += zebra/dplane_fpm_nl.la
|
||||
zebra_dplane_fpm_nl_la_SOURCES = zebra/dplane_fpm_nl.c
|
||||
zebra_dplane_fpm_nl_la_LDFLAGS = $(MODULE_LDFLAGS)
|
||||
zebra_dplane_fpm_nl_la_LIBADD =
|
||||
|
||||
vtysh_scan += zebra/dplane_fpm_nl.c
|
||||
endif
|
||||
|
||||
if NETLINK_DEBUG
|
||||
|
@ -3252,9 +3252,7 @@ int zebra_evpn_mh_if_write(struct vty *vty, struct interface *ifp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "zebra/zebra_evpn_mh_clippy.c"
|
||||
#endif
|
||||
/* CLI for setting an ES in bypass mode */
|
||||
DEFPY_HIDDEN(zebra_evpn_es_bypass, zebra_evpn_es_bypass_cmd,
|
||||
"[no] evpn mh bypass",
|
||||
|
@ -29,9 +29,7 @@
|
||||
#include "debug.h"
|
||||
#include "zapi_msg.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "zebra/zebra_mlag_vty_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFUN_HIDDEN (show_mlag,
|
||||
show_mlag_cmd,
|
||||
|
@ -40,9 +40,7 @@
|
||||
#include "zebra/zebra_rnh.h"
|
||||
#include "zebra/zebra_routemap.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "zebra/zebra_routemap_clippy.c"
|
||||
#endif
|
||||
|
||||
static uint32_t zebra_rmap_update_timer = ZEBRA_RMAP_DEFAULT_UPDATE_TIMER;
|
||||
static struct thread *zebra_t_rmap_update = NULL;
|
||||
|
@ -40,9 +40,7 @@
|
||||
#include "zebra/zebra_routemap.h"
|
||||
#include "zebra/zebra_dplane.h"
|
||||
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "zebra/zebra_srv6_vty_clippy.c"
|
||||
#endif
|
||||
|
||||
static int zebra_sr_config(struct vty *vty);
|
||||
|
||||
|
@ -44,9 +44,7 @@
|
||||
#include "zebra/zebra_vxlan.h"
|
||||
#include "zebra/zebra_netns_notify.h"
|
||||
#include "zebra/zebra_routemap.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "zebra/zebra_vrf_clippy.c"
|
||||
#endif
|
||||
#include "zebra/table_manager.h"
|
||||
|
||||
static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi,
|
||||
|
@ -46,9 +46,7 @@
|
||||
#include "lib/route_opaque.h"
|
||||
#include "zebra/zebra_vxlan.h"
|
||||
#include "zebra/zebra_evpn_mh.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "zebra/zebra_vty_clippy.c"
|
||||
#endif
|
||||
#include "zebra/zserv.h"
|
||||
#include "zebra/router-id.h"
|
||||
#include "zebra/ipforward.h"
|
||||
|
Loading…
Reference in New Issue
Block a user