From 89cb86aeb0262e17ee39c1d791effe9515bd0dc8 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 4 Oct 2022 18:44:36 +0200 Subject: [PATCH] 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 --- Makefile.am | 2 +- babeld/subdir.am | 5 - bfdd/bfdd_cli.c | 2 - bfdd/bfdd_vty.c | 2 - bfdd/subdir.am | 2 - bgpd/bgp_bmp.c | 2 - bgpd/bgp_debug.c | 2 - bgpd/bgp_evpn_vty.c | 2 - bgpd/bgp_labelpool.c | 2 - bgpd/bgp_route.c | 2 - bgpd/bgp_routemap.c | 2 - bgpd/bgp_rpki.c | 4 - bgpd/bgp_vty.c | 2 - bgpd/subdir.am | 27 -- configure.ac | 1 - doc/developer/cli.rst | 2 - doc/developer/vtysh.rst | 19 +- eigrpd/eigrp_cli.c | 2 - eigrpd/eigrp_vty.c | 2 - eigrpd/subdir.am | 6 - isisd/isis_cli.c | 2 - isisd/subdir.am | 22 -- ldpd/ldp_vty_cmds.c | 2 - ldpd/subdir.am | 1 - lib/command.h | 7 - lib/filter_cli.c | 2 - lib/if.c | 2 - lib/log_vty.c | 2 - lib/nexthop_group.c | 2 - lib/northbound_cli.c | 2 - lib/plist.c | 2 - lib/routemap_cli.c | 2 - lib/subdir.am | 29 +-- lib/thread.c | 2 - lib/vty.c | 2 - lib/zebra.h | 4 +- lib/zlog_5424_cli.c | 2 - nhrpd/subdir.am | 1 - ospf6d/ospf6_area.c | 2 - ospf6d/ospf6_asbr.c | 2 - ospf6d/ospf6_gr.c | 2 - ospf6d/ospf6_gr_helper.c | 2 - ospf6d/ospf6_lsa.c | 2 - ospf6d/ospf6_nssa.c | 2 - ospf6d/ospf6_route.c | 2 - ospf6d/ospf6_top.c | 2 - ospf6d/subdir.am | 21 -- ospfd/ospf_dump.c | 2 - ospfd/ospf_gr.c | 2 - ospfd/ospf_ldp_sync.c | 2 - ospfd/ospf_vty.c | 2 - ospfd/subdir.am | 12 - pathd/path_cli.c | 2 - pathd/path_pcep_cli.c | 2 - pathd/path_ted.c | 2 - pathd/subdir.am | 5 - pbrd/pbr_debug.c | 2 - pbrd/pbr_vty.c | 2 - pbrd/subdir.am | 4 - pimd/pim6_cmd.c | 2 - pimd/pim6_mld.c | 2 - pimd/pim_cmd.c | 2 - pimd/pim_mroute.h | 4 - pimd/subdir.am | 5 - python/vtysh-cmd-check.py | 72 ------ python/xref2vtysh.py | 386 +++++++++++++++++++++++++++++ python/xrelfo.py | 10 + ripd/rip_cli.c | 2 - ripd/subdir.am | 5 - ripngd/ripng_cli.c | 2 - ripngd/subdir.am | 5 - sharpd/sharp_vty.c | 2 - sharpd/subdir.am | 1 - staticd/static_vty.c | 2 - staticd/subdir.am | 1 - vrrpd/subdir.am | 1 - vrrpd/vrrp_vty.c | 2 - vtysh/.gitignore | 4 +- vtysh/extract.pl.in | 282 --------------------- vtysh/subdir.am | 21 -- watchfrr/subdir.am | 1 - watchfrr/watchfrr_vty.c | 2 - zebra/debug.c | 2 - zebra/dpdk/zebra_dplane_dpdk_vty.c | 2 - zebra/interface.c | 2 - zebra/rtadv.c | 2 - zebra/subdir.am | 25 -- zebra/zebra_evpn_mh.c | 2 - zebra/zebra_mlag_vty.c | 2 - zebra/zebra_routemap.c | 2 - zebra/zebra_srv6_vty.c | 2 - zebra/zebra_vrf.c | 2 - zebra/zebra_vty.c | 2 - 93 files changed, 423 insertions(+), 692 deletions(-) delete mode 100644 python/vtysh-cmd-check.py create mode 100644 python/xref2vtysh.py delete mode 100755 vtysh/extract.pl.in diff --git a/Makefile.am b/Makefile.am index ce0f70a1a294..8c7bde9d4ce7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 \ \ diff --git a/babeld/subdir.am b/babeld/subdir.am index 856cbd13e397..4b9037283c5d 100644 --- a/babeld/subdir.am +++ b/babeld/subdir.am @@ -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 diff --git a/bfdd/bfdd_cli.c b/bfdd/bfdd_cli.c index 69424c45d9a8..52f2dd8fd325 100644 --- a/bfdd/bfdd_cli.c +++ b/bfdd/bfdd_cli.c @@ -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" diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c index 4a2c5bf662b9..7b7a001e24b2 100644 --- a/bfdd/bfdd_vty.c +++ b/bfdd/bfdd_vty.c @@ -28,9 +28,7 @@ #include "bfd.h" -#ifndef VTYSH_EXTRACT_PL #include "bfdd/bfdd_vty_clippy.c" -#endif /* * Commands help string definitions. diff --git a/bfdd/subdir.am b/bfdd/subdir.am index 8d35b933d789..b86a18967e19 100644 --- a/bfdd/subdir.am +++ b/bfdd/subdir.am @@ -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 diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index bcab4099c049..2cb85cb1daed 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -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, diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index 580c18b58de0..8c75f48307ec 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -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, diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 24fa2b2a539d..e19a58266b4d 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -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, diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c index c227a5e41c40..129878451d3f 100644 --- a/bgpd/bgp_labelpool.c +++ b/bgpd/bgp_labelpool.c @@ -39,9 +39,7 @@ #define BGP_LABELPOOL_ENABLE_TESTS 0 -#ifndef VTYSH_EXTRACT_PL #include "bgpd/bgp_labelpool_clippy.c" -#endif /* diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index f6b6cb93dbc9..701c3779e821 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -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), diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 233fd55ef0c1..9aade05d69a6 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -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. diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index cb7afd89677e..2acf74c52b30 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -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"); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index f380460a9573..9c1159968ab7 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -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, diff --git a/bgpd/subdir.am b/bgpd/subdir.am index 765650313bfd..04fe1f12491c 100644 --- a/bgpd/subdir.am +++ b/bgpd/subdir.am @@ -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 diff --git a/configure.ac b/configure.ac index 4cbdfe0fccde..1a481ecd794c 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) diff --git a/doc/developer/cli.rst b/doc/developer/cli.rst index ff6c4f6e16a1..d51f06d118f8 100644 --- a/doc/developer/cli.rst +++ b/doc/developer/cli.rst @@ -453,9 +453,7 @@ all DEFPY statements**: /* GPL header */ #include ... ... - #ifndef VTYSH_EXTRACT_PL #include "daemon/filename_clippy.c" - #endif DEFPY(...) DEFPY(...) diff --git a/doc/developer/vtysh.rst b/doc/developer/vtysh.rst index 160676a7b1f7..323ea57c166d 100644 --- a/doc/developer/vtysh.rst +++ b/doc/developer/vtysh.rst @@ -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 diff --git a/eigrpd/eigrp_cli.c b/eigrpd/eigrp_cli.c index 744f5f9c7ae2..2afd9d5eaaf6 100644 --- a/eigrpd/eigrp_cli.c +++ b/eigrpd/eigrp_cli.c @@ -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 diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index 3d61294b22bd..137f9b028c59 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -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, diff --git a/eigrpd/subdir.am b/eigrpd/subdir.am index 3b647e060b84..e417132b51b3 100644 --- a/eigrpd/subdir.am +++ b/eigrpd/subdir.am @@ -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 diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index 9db867e2c073..3650984f1bb7 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -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 diff --git a/isisd/subdir.am b/isisd/subdir.am index 3e5816c16b9a..dabf6a925ea0 100644 --- a/isisd/subdir.am +++ b/isisd/subdir.am @@ -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 diff --git a/ldpd/ldp_vty_cmds.c b/ldpd/ldp_vty_cmds.c index 3d11d3137ac2..33e6b297cbfa 100644 --- a/ldpd/ldp_vty_cmds.c +++ b/ldpd/ldp_vty_cmds.c @@ -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, diff --git a/ldpd/subdir.am b/ldpd/subdir.am index 083effb703ad..0b948adb6fc2 100644 --- a/ldpd/subdir.am +++ b/ldpd/subdir.am @@ -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 diff --git a/lib/command.h b/lib/command.h index f4168dedd75c..31e5cad23fb0 100644 --- a/lib/command.h +++ b/lib/command.h @@ -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 *); diff --git a/lib/filter_cli.c b/lib/filter_cli.c index 9a877a57041d..e0f0f177e516 100644 --- a/lib/filter_cli.c +++ b/lib/filter_cli.c @@ -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" diff --git a/lib/if.c b/lib/if.c index fa4fdb82d38a..e7ff0c49b094 100644 --- a/lib/if.c +++ b/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"); diff --git a/lib/log_vty.c b/lib/log_vty.c index c9268734c404..4091c92c7322 100644 --- a/lib/log_vty.c +++ b/lib/log_vty.c @@ -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) diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c index 7284d6cea606..f342f50e8fe0 100644 --- a/lib/nexthop_group.c +++ b/lib/nexthop_group.c @@ -28,9 +28,7 @@ #include #include -#ifndef VTYSH_EXTRACT_PL #include "lib/nexthop_group_clippy.c" -#endif DEFINE_MTYPE_STATIC(LIB, NEXTHOP_GROUP, "Nexthop Group"); diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index 56eac9dc32a3..e0dcdb490fcf 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -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"}; diff --git a/lib/plist.c b/lib/plist.c index ff2a59ba2dfd..17e692d13954 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -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, diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c index 6be5d15ec4f8..9adaed91ed5f 100644 --- a/lib/routemap_cli.c +++ b/lib/routemap_cli.c @@ -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" \ diff --git a/lib/subdir.am b/lib/subdir.am index e04e700eb692..ea6cb9339a6d 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -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) $< diff --git a/lib/thread.c b/lib/thread.c index 9eac9b410a4a..4078634f75fe 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -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) { diff --git a/lib/vty.c b/lib/vty.c index 92db07677ae0..d524ae53cba8 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -53,9 +53,7 @@ #include #include -#ifndef VTYSH_EXTRACT_PL #include "lib/vty_clippy.c" -#endif DEFINE_MTYPE_STATIC(LIB, VTY, "VTY"); DEFINE_MTYPE_STATIC(LIB, VTY_SERV, "VTY server"); diff --git a/lib/zebra.h b/lib/zebra.h index 53ae5b4e9e2c..b2f5e5a848cc 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -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 diff --git a/lib/zlog_5424_cli.c b/lib/zlog_5424_cli.c index dd8dbfaffd15..5eebda9debc4 100644 --- a/lib/zlog_5424_cli.c +++ b/lib/zlog_5424_cli.c @@ -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, diff --git a/nhrpd/subdir.am b/nhrpd/subdir.am index dc0c162c832f..227ff6c6787d 100644 --- a/nhrpd/subdir.am +++ b/nhrpd/subdir.am @@ -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 diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index a0cb45579803..a5746e1150ad 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -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"); diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index ae3ce2f0c7c8..2280465213dc 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -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; diff --git a/ospf6d/ospf6_gr.c b/ospf6d/ospf6_gr.c index d7de66c6631f..1f7fefa048ab 100644 --- a/ospf6d/ospf6_gr.c +++ b/ospf6d/ospf6_gr.c @@ -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); diff --git a/ospf6d/ospf6_gr_helper.c b/ospf6d/ospf6_gr_helper.c index f352d35270c8..771a710240b8 100644 --- a/ospf6d/ospf6_gr_helper.c +++ b/ospf6d/ospf6_gr_helper.c @@ -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"); diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index 779076f387f2..2792820a542a 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -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"); diff --git a/ospf6d/ospf6_nssa.c b/ospf6d/ospf6_nssa.c index b1bff69f06d1..f35c9df4a5a5 100644 --- a/ospf6d/ospf6_nssa.c +++ b/ospf6d/ospf6_nssa.c @@ -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; diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 8e964393f100..52e0adaec522 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -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"); diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index d48e85cedb46..eb89a14cd382 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -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; diff --git a/ospf6d/subdir.am b/ospf6d/subdir.am index cf863ff52349..3dff03956cea 100644 --- a/ospf6d/subdir.am +++ b/ospf6d/subdir.am @@ -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 diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index 59f95c5da268..a47ed8d67abd 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -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}; diff --git a/ospfd/ospf_gr.c b/ospfd/ospf_gr.c index 66ef1d6564d9..6678d8c1f362 100644 --- a/ospfd/ospf_gr.c +++ b/ospfd/ospf_gr.c @@ -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); diff --git a/ospfd/ospf_ldp_sync.c b/ospfd/ospf_ldp_sync.c index 77e96f173387..7b1fa6626f3a 100644 --- a/ospfd/ospf_ldp_sync.c +++ b/ospfd/ospf_ldp_sync.c @@ -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, diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 4f0fa6194acf..c8285f2e5b3f 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -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, diff --git a/ospfd/subdir.am b/ospfd/subdir.am index 78688fac95be..b67f942883d0 100644 --- a/ospfd/subdir.am +++ b/ospfd/subdir.am @@ -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 diff --git a/pathd/path_cli.c b/pathd/path_cli.c index 13e52ac86bf7..a6540cc84a1e 100644 --- a/pathd/path_cli.c +++ b/pathd/path_cli.c @@ -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 diff --git a/pathd/path_pcep_cli.c b/pathd/path_pcep_cli.c index d2b49a7d955e..0f259f1dc717 100644 --- a/pathd/path_pcep_cli.c +++ b/pathd/path_pcep_cli.c @@ -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 diff --git a/pathd/path_ted.c b/pathd/path_ted.c index 316255a97ee2..3e720e42dd86 100644 --- a/pathd/path_ted.c +++ b/pathd/path_ted.c @@ -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); diff --git a/pathd/subdir.am b/pathd/subdir.am index f339c792256f..29be8f463dc9 100644 --- a/pathd/subdir.am +++ b/pathd/subdir.am @@ -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 diff --git a/pbrd/pbr_debug.c b/pbrd/pbr_debug.c index 82f045c4624c..99489777eb47 100644 --- a/pbrd/pbr_debug.c +++ b/pbrd/pbr_debug.c @@ -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"}; diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c index 6f53adb334da..e8e5981ec55e 100644 --- a/pbrd/pbr_vty.c +++ b/pbrd/pbr_vty.c @@ -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" diff --git a/pbrd/subdir.am b/pbrd/subdir.am index bbe3f2ab71df..8a3bf31bf64c 100644 --- a/pbrd/subdir.am +++ b/pbrd/subdir.am @@ -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 diff --git a/pimd/pim6_cmd.c b/pimd/pim6_cmd.c index ae272bbb9287..bd6d229476f6 100644 --- a/pimd/pim6_cmd.c +++ b/pimd/pim6_cmd.c @@ -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", diff --git a/pimd/pim6_mld.c b/pimd/pim6_mld.c index c34c78296945..dc5e67e2c5d9 100644 --- a/pimd/pim6_mld.c +++ b/pimd/pim6_mld.c @@ -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) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index efa1382fc0ea..306891c0e0ea 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -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", diff --git a/pimd/pim_mroute.h b/pimd/pim_mroute.h index d6798c52ada5..c409b9ed0afa 100644 --- a/pimd/pim_mroute.h +++ b/pimd/pim_mroute.h @@ -39,10 +39,8 @@ #if defined(HAVE_LINUX_MROUTE_H) #include #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 #else -#ifndef VTYSH_EXTRACT_PL #include "linux/mroute6.h" #endif -#endif #ifndef MRT_INIT #define MRT_BASE MRT6_BASE diff --git a/pimd/subdir.am b/pimd/subdir.am index aa06b86479d9..9b7859696205 100644 --- a/pimd/subdir.am +++ b/pimd/subdir.am @@ -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 diff --git a/python/vtysh-cmd-check.py b/python/vtysh-cmd-check.py deleted file mode 100644 index ef9eea41ad76..000000000000 --- a/python/vtysh-cmd-check.py +++ /dev/null @@ -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 - -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))) diff --git a/python/xref2vtysh.py b/python/xref2vtysh.py new file mode 100644 index 000000000000..ef18fac8a185 --- /dev/null +++ b/python/xref2vtysh.py @@ -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 + +#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"" + + 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() diff --git a/python/xrelfo.py b/python/xrelfo.py index 09455ea9b43d..739becd8ad33 100644 --- a/python/xrelfo.py +++ b/python/xrelfo.py @@ -37,6 +37,7 @@ 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() diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c index 73442bf16f62..34ea2167264c 100644 --- a/ripd/rip_cli.c +++ b/ripd/rip_cli.c @@ -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 diff --git a/ripd/subdir.am b/ripd/subdir.am index b00c375888fb..98cc765c91cf 100644 --- a/ripd/subdir.am +++ b/ripd/subdir.am @@ -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 diff --git a/ripngd/ripng_cli.c b/ripngd/ripng_cli.c index ded2f4358e0d..049a392ddbe6 100644 --- a/ripngd/ripng_cli.c +++ b/ripngd/ripng_cli.c @@ -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 diff --git a/ripngd/subdir.am b/ripngd/subdir.am index a4db3e5a6b6c..162426c58ca8 100644 --- a/ripngd/subdir.am +++ b/ripngd/subdir.am @@ -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 diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index ba2e599a5bf4..164a0fd218cd 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -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"); diff --git a/sharpd/subdir.am b/sharpd/subdir.am index acf4fe5d0079..3eb8d1d3b5e9 100644 --- a/sharpd/subdir.am +++ b/sharpd/subdir.am @@ -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 diff --git a/staticd/static_vty.c b/staticd/static_vty.c index c0638f4bc4b4..94a3493477f1 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -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" diff --git a/staticd/subdir.am b/staticd/subdir.am index 62969a0a2a7c..bb0fc95bc202 100644 --- a/staticd/subdir.am +++ b/staticd/subdir.am @@ -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 diff --git a/vrrpd/subdir.am b/vrrpd/subdir.am index 02e0497eef13..03b404261197 100644 --- a/vrrpd/subdir.am +++ b/vrrpd/subdir.am @@ -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 diff --git a/vrrpd/vrrp_vty.c b/vrrpd/vrrp_vty.c index aea7d9abc713..f822b89854ab 100644 --- a/vrrpd/vrrp_vty.c +++ b/vrrpd/vrrp_vty.c @@ -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" diff --git a/vtysh/.gitignore b/vtysh/.gitignore index 118b84407beb..09e90e51d2ed 100644 --- a/vtysh/.gitignore +++ b/vtysh/.gitignore @@ -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 diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in deleted file mode 100755 index 228a136b71fe..000000000000 --- a/vtysh/extract.pl.in +++ /dev/null @@ -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 < - -#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 = ; - 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 < 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 diff --git a/watchfrr/subdir.am b/watchfrr/subdir.am index e899b895e7c5..04a4aaf166bd 100644 --- a/watchfrr/subdir.am +++ b/watchfrr/subdir.am @@ -4,7 +4,6 @@ if WATCHFRR sbin_PROGRAMS += watchfrr/watchfrr -vtysh_scan += watchfrr/watchfrr_vty.c man8 += $(MANBUILD)/frr-watchfrr.8 endif diff --git a/watchfrr/watchfrr_vty.c b/watchfrr/watchfrr_vty.c index e5cc43754243..742b474eab6f 100644 --- a/watchfrr/watchfrr_vty.c +++ b/watchfrr/watchfrr_vty.c @@ -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, diff --git a/zebra/debug.c b/zebra/debug.c index 25102145d757..16aac7909fa9 100644 --- a/zebra/debug.c +++ b/zebra/debug.c @@ -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; diff --git a/zebra/dpdk/zebra_dplane_dpdk_vty.c b/zebra/dpdk/zebra_dplane_dpdk_vty.c index 748bce9e3456..d1814af3b7d8 100644 --- a/zebra/dpdk/zebra_dplane_dpdk_vty.c +++ b/zebra/dpdk/zebra_dplane_dpdk_vty.c @@ -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" diff --git a/zebra/interface.c b/zebra/interface.c index c674b499ac82..52e6bc81dffb 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -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]", diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 127888d65547..a8ec60844cda 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -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"); diff --git a/zebra/subdir.am b/zebra/subdir.am index 298b71598c4b..9842931496d4 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -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 diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index 064c91b72948..98120accfdc2 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -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", diff --git a/zebra/zebra_mlag_vty.c b/zebra/zebra_mlag_vty.c index ebaaf03dabc8..a1c544d5d848 100644 --- a/zebra/zebra_mlag_vty.c +++ b/zebra/zebra_mlag_vty.c @@ -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, diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 2cc84a1f7fcb..13d1995d5894 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -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; diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c index 9adfc6550a58..e6810bdc5683 100644 --- a/zebra/zebra_srv6_vty.c +++ b/zebra/zebra_srv6_vty.c @@ -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); diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index a2844ca9568f..c99aa2e8ffff 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -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, diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 525e0366e782..f68a656710f3 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -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"