ldpd: convert cli and get rid of the xml interface

The xml2cli.pl script was useful years ago when the vty code was very
rudimentary. This is not the case anymore, so convert all ldpd CLI
commands to use DEFUNs directly and get rid of the XML interface.

The benefits are:
* Consistency with the other daemons;
* One less build dependency (the LibXML perl module);
* Easier to add new commands.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
Renato Westphal 2017-06-12 11:39:12 -03:00 committed by Renato Westphal
parent 62e4232010
commit c740f7d367
20 changed files with 1252 additions and 1291 deletions

View File

@ -1284,14 +1284,6 @@ AM_CONDITIONAL(OSPFD, test "x$OSPFD" = "xospfd")
if test "${enable_ldpd}" = "no";then
LDPD=""
else
AX_PROG_PERL_MODULES(XML::LibXML, , [
if test -f "${srcdir}/ldpd/ldp_vty_cmds.c"; then
AC_MSG_WARN([XML::LibXML perl module not found, using pregenerated ldp_vty_cmds.c])
else
AC_MSG_ERROR([XML::LibXML perl module not found and pregenerated ldp_vty_cmds.c missing])
fi
])
LDPD="ldpd"
AC_DEFINE(HAVE_LDPD, 1, ldpd)
fi

View File

@ -8,8 +8,7 @@ Add packages:
sudo dnf install git autoconf automake libtool make gawk \
readline-devel texinfo net-snmp-devel groff pkgconfig \
json-c-devel pam-devel perl-XML-LibXML c-ares-devel \
python3-devel
json-c-devel pam-devel c-ares-devel python3-devel
Get FRR, compile it and install it (from Git)
---------------------------------------------

View File

@ -18,7 +18,7 @@ Configure Package location:
Add packages:
sudo pkg_add git autoconf automake libtool gmake gawk openssl \
pkg-config json-c p5-XML-LibXML python27 py27-test python35
pkg-config json-c python27 py27-test python35
Install SSL Root Certificates (for git https access):

View File

@ -12,7 +12,7 @@ Install required packages
-------------------------
sudo pkgin install git autoconf automake libtool gmake gawk openssl \
pkg-config json-c p5-XML-LibXML python27 py27-test python35
pkg-config json-c python27 py27-test python35
Install SSL Root Certificates (for git https access):

View File

@ -47,12 +47,6 @@ Add libjson to Solaris equivalent of ld.so.conf
crle -l /opt/csw/lib -u
Add Perl packages:
cpan
cpan[1]> install XML::LibXML
cpan[2]> exit
Add pytest:
pip install pytest

View File

@ -11,7 +11,7 @@ Configure PKG_PATH
Add packages:
pkg_add git autoconf-2.69p2 automake-1.15p0 libtool bison
pkg_add gmake gawk dejagnu openssl json-c p5-XML-LibXML py-test
pkg_add gmake gawk dejagnu openssl json-c py-test
Select Python2.7 as default (required for pytest)

View File

@ -13,7 +13,7 @@ Add packages:
apt-get install git autoconf automake libtool make gawk libreadline-dev \
texinfo libpam0g-dev dejagnu libjson0-dev pkg-config libpam0g-dev \
libjson0-dev flex python-pip libc-ares-dev python3-dev libxml2 libxml2-dev
libjson0-dev flex python-pip libc-ares-dev python3-dev
Install newer bison from 14.04 package source (Ubuntu 12.04 package source
is too old)
@ -51,11 +51,6 @@ Install newer version of autoconf and automake:
sudo make install
cd ..
Install XML::LibXML
sudo cpan
install XML::LibXML
Install pytest:
pip install pytest

1
ldpd/.gitignore vendored
View File

@ -15,4 +15,3 @@ TAGS
.arch-ids
*~
*.loT
ldp_vty_cmds.c

View File

@ -3,16 +3,12 @@
AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
INSTALL_SDATA=@INSTALL@ -m 600
EXTRA_DIST=
AM_CFLAGS = $(WERROR)
noinst_LIBRARIES = libldp.a
sbin_PROGRAMS = ldpd
BUILT_SOURCES = ldp_vty_cmds.c
EXTRA_DIST += ldp_vty.xml
libldp_a_SOURCES = \
accept.c address.c adjacency.c control.c hello.c init.c interface.c \
keepalive.c l2vpn.c labelmapping.c lde.c lde_lib.c ldpd.c \
@ -23,11 +19,6 @@ libldp_a_SOURCES = \
noinst_HEADERS = \
control.h lde.h ldpd.h ldpe.h ldp.h log.h ldp_debug.h ldp_vty.h
ldp_vty_cmds.c: $(srcdir)/ldp_vty.xml $(srcdir)/../tools/xml2cli.pl
@PERL@ $(srcdir)/../tools/xml2cli.pl $(srcdir)/ldp_vty.xml | \
sed -e 's%DEFUN \((ldp_\(interface_\|mpls_ldp\|address_family\|l2vpn_word\|member_pseudo\)\)%DEFUN_NOSH \1%' \
> $@
ldpd_SOURCES = ldpd.c
ldpd_LDADD = libldp.a ../lib/libfrr.la @LIBCAP@

View File

@ -39,16 +39,10 @@ struct cmd_node ldp_debug_node =
};
int
ldp_vty_debug(struct vty *vty, struct vty_arg *args[])
ldp_vty_debug(struct vty *vty, int disable, const char *type_str,
const char *dir_str, int all)
{
const char *type_str, *dir_str;
int disable, all;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
type_str = vty_get_arg_value(args, "type");
if (strcmp(type_str, "discovery") == 0) {
dir_str = vty_get_arg_value(args, "dir");
if (dir_str == NULL)
return (CMD_WARNING);
@ -74,8 +68,6 @@ ldp_vty_debug(struct vty *vty, struct vty_arg *args[])
else
DEBUG_ON(event, EVENT);
} else if (strcmp(type_str, "messages") == 0) {
all = (vty_get_arg_value(args, "all")) ? 1 : 0;
dir_str = vty_get_arg_value(args, "dir");
if (dir_str == NULL)
return (CMD_WARNING);
@ -112,7 +104,7 @@ ldp_vty_debug(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_show_debugging(struct vty *vty, struct vty_arg *args[])
ldp_vty_show_debugging(struct vty *vty)
{
vty_out(vty, "LDP debugging status:%s", VTY_NEWLINE);

View File

@ -37,46 +37,47 @@ int ldp_get_address(const char *, int *, union ldpd_addr *);
int ldp_config_write(struct vty *);
int ldp_l2vpn_config_write(struct vty *);
int ldp_debug_config_write(struct vty *);
int ldp_vty_mpls_ldp (struct vty *, struct vty_arg *[]);
int ldp_vty_address_family (struct vty *, struct vty_arg *[]);
int ldp_vty_disc_holdtime(struct vty *, struct vty_arg *[]);
int ldp_vty_disc_interval(struct vty *, struct vty_arg *[]);
int ldp_vty_targeted_hello_accept(struct vty *, struct vty_arg *[]);
int ldp_vty_session_holdtime(struct vty *, struct vty_arg *[]);
int ldp_vty_interface(struct vty *, struct vty_arg *[]);
int ldp_vty_trans_addr(struct vty *, struct vty_arg *[]);
int ldp_vty_neighbor_targeted(struct vty *, struct vty_arg *[]);
int ldp_vty_label_advertise(struct vty *, struct vty_arg *[]);
int ldp_vty_label_allocate(struct vty *, struct vty_arg *[]);
int ldp_vty_label_expnull(struct vty *, struct vty_arg *[]);
int ldp_vty_label_accept(struct vty *, struct vty_arg *[]);
int ldp_vty_ttl_security(struct vty *, struct vty_arg *[]);
int ldp_vty_router_id(struct vty *, struct vty_arg *[]);
int ldp_vty_ds_cisco_interop(struct vty *, struct vty_arg *[]);
int ldp_vty_trans_pref_ipv4(struct vty *, struct vty_arg *[]);
int ldp_vty_neighbor_password(struct vty *, struct vty_arg *[]);
int ldp_vty_neighbor_ttl_security(struct vty *, struct vty_arg *[]);
int ldp_vty_l2vpn(struct vty *, struct vty_arg *[]);
int ldp_vty_l2vpn_bridge(struct vty *, struct vty_arg *[]);
int ldp_vty_l2vpn_mtu(struct vty *, struct vty_arg *[]);
int ldp_vty_l2vpn_pwtype(struct vty *, struct vty_arg *[]);
int ldp_vty_l2vpn_interface(struct vty *, struct vty_arg *[]);
int ldp_vty_l2vpn_pseudowire(struct vty *, struct vty_arg *[]);
int ldp_vty_l2vpn_pw_cword(struct vty *, struct vty_arg *[]);
int ldp_vty_l2vpn_pw_nbr_addr(struct vty *, struct vty_arg *[]);
int ldp_vty_l2vpn_pw_nbr_id(struct vty *, struct vty_arg *[]);
int ldp_vty_l2vpn_pw_pwid(struct vty *, struct vty_arg *[]);
int ldp_vty_l2vpn_pw_pwstatus(struct vty *, struct vty_arg *[]);
int ldp_vty_show_binding(struct vty *, struct vty_arg *[]);
int ldp_vty_show_discovery(struct vty *, struct vty_arg *[]);
int ldp_vty_show_interface(struct vty *, struct vty_arg *[]);
int ldp_vty_show_capabilities(struct vty *, struct vty_arg *[]);
int ldp_vty_show_neighbor(struct vty *, struct vty_arg *[]);
int ldp_vty_show_atom_binding(struct vty *, struct vty_arg *[]);
int ldp_vty_show_atom_vc(struct vty *, struct vty_arg *[]);
int ldp_vty_clear_nbr(struct vty *, struct vty_arg *[]);
int ldp_vty_debug(struct vty *, struct vty_arg *[]);
int ldp_vty_show_debugging(struct vty *, struct vty_arg *[]);
int ldp_vty_mpls_ldp (struct vty *, int);
int ldp_vty_address_family (struct vty *, int, const char *);
int ldp_vty_disc_holdtime(struct vty *, int, const char *, const char *);
int ldp_vty_disc_interval(struct vty *, int, const char *, const char *);
int ldp_vty_targeted_hello_accept(struct vty *, int, const char *);
int ldp_vty_nbr_session_holdtime(struct vty *, int, const char *, const char *);
int ldp_vty_af_session_holdtime(struct vty *, int, const char *);
int ldp_vty_interface(struct vty *, int, const char *);
int ldp_vty_trans_addr(struct vty *, int, const char *);
int ldp_vty_neighbor_targeted(struct vty *, int, const char *);
int ldp_vty_label_advertise(struct vty *, int, const char *, const char *);
int ldp_vty_label_allocate(struct vty *, int, int, const char *);
int ldp_vty_label_expnull(struct vty *, int, const char *);
int ldp_vty_label_accept(struct vty *, int, const char *, const char *);
int ldp_vty_ttl_security(struct vty *, int);
int ldp_vty_router_id(struct vty *, int, const char *);
int ldp_vty_ds_cisco_interop(struct vty *, int);
int ldp_vty_trans_pref_ipv4(struct vty *, int);
int ldp_vty_neighbor_password(struct vty *, int, const char *, const char *);
int ldp_vty_neighbor_ttl_security(struct vty *, int, const char *, const char *);
int ldp_vty_l2vpn(struct vty *, int, const char *);
int ldp_vty_l2vpn_bridge(struct vty *, int, const char *);
int ldp_vty_l2vpn_mtu(struct vty *, int, const char *);
int ldp_vty_l2vpn_pwtype(struct vty *, int, const char *);
int ldp_vty_l2vpn_interface(struct vty *, int, const char *);
int ldp_vty_l2vpn_pseudowire(struct vty *, int, const char *);
int ldp_vty_l2vpn_pw_cword(struct vty *, int, const char *);
int ldp_vty_l2vpn_pw_nbr_addr(struct vty *, int, const char *);
int ldp_vty_l2vpn_pw_nbr_id(struct vty *, int, const char *);
int ldp_vty_l2vpn_pw_pwid(struct vty *, int, const char *);
int ldp_vty_l2vpn_pw_pwstatus(struct vty *, int);
int ldp_vty_clear_nbr(struct vty *, const char *);
int ldp_vty_debug(struct vty *, int, const char *, const char *, int);
int ldp_vty_show_binding(struct vty *, const char *, int, int);
int ldp_vty_show_discovery(struct vty *, const char *, int, int);
int ldp_vty_show_interface(struct vty *, const char *, int);
int ldp_vty_show_capabilities(struct vty *, int);
int ldp_vty_show_neighbor(struct vty *, int, int, int);
int ldp_vty_show_atom_binding(struct vty *, int);
int ldp_vty_show_atom_vc(struct vty *, int);
int ldp_vty_show_debugging(struct vty *);
void ldp_vty_init(void);

View File

@ -1,466 +0,0 @@
<?xml version="1.0"?>
<file init="ldp_vty_init" cmdprefix="ldp" header="ldpd/ldp_vty.h">
<!-- address-family -->
<options name="address-family">
<option name="ipv4" help="IPv4 Address Family"/>
<option name="ipv6" help="IPv6 Address Family"/>
</options>
<!-- ipv4/ipv6 address -->
<options name="addr">
<option input="ipv4" help="IPv4 address"/>
<option input="ipv6" help="IPv6 address"/>
</options>
<!-- pseudowire control-word options -->
<options name="cword">
<option name="exclude" help="Exclude control-word in pseudowire packets"/>
<option name="include" help="Include control-word in pseudowire packets"/>
</options>
<!-- pseudowire types -->
<options name="pwtype">
<option name="ethernet" help="Ethernet (type 5)"/>
<option name="ethernet-tagged" help="Ethernet-tagged (type 4)"/>
</options>
<!-- packet direction -->
<options name="dir">
<option name="recv" help="Received messages"/>
<option name="sent" help="Sent messages"/>
</options>
<!-- ACL -->
<options name="acl">
<option input="acl_range" help="IP access-list number"/>
<option input="acl_expanded_range" help="IP access-list number (expanded range)"/>
<option input="word" help="IP access-list name"/>
</options>
<!-- shared subtrees -->
<subtree name="label_local_acls">
<option name="to" help="IP Access-list specifying controls on LDP Peers">
<select options="acl" arg="to_acl" function="inherited">
<option name="for" help="IP access-list for destination prefixes">
<select options="acl" arg="for_acl" function="inherited"/>
</option>
</select>
</option>
<option name="for" help="IP access-list for destination prefixes">
<select options="acl" arg="for_acl" function="inherited">
<option name="to" help="IP Access-list specifying controls on LDP Peers">
<select options="acl" arg="to_acl" function="inherited"/>
</option>
</select>
</option>
</subtree>
<subtree name="label_remote_acls">
<option name="from" help="Neighbor from whom to accept label advertisement">
<select options="acl" arg="from_acl" function="inherited">
<option name="for" help="IP access-list for destination prefixes">
<select options="acl" arg="for_acl" function="inherited"/>
</option>
</select>
</option>
<option name="for" help="IP access-list for destination prefixes">
<select options="acl" arg="for_acl" function="inherited">
<option name="from" help="Neighbor from whom to accept label advertisement">
<select options="acl" arg="from_acl" function="inherited"/>
</option>
</select>
</option>
</subtree>
<subtree name="discovery_link">
<option name="discovery" help="Configure discovery parameters">
<option name="hello" arg="hello_type" help="LDP Link Hellos">
<option name="holdtime" help="Hello holdtime">
<option input="disc_time" arg="seconds" help="Time (seconds) - 65535 implies infinite" function="ldp_vty_disc_holdtime"/>
</option>
<option name="interval" help="Hello interval">
<option input="disc_time" arg="seconds" help="Time (seconds)" function="ldp_vty_disc_interval"/>
</option>
</option>
</option>
</subtree>
<subtree name="discovery_targeted">
<option name="discovery" help="Configure discovery parameters">
<option name="targeted-hello" arg="hello_type" help="LDP Targeted Hellos">
<option name="holdtime" help="Targeted hello holdtime">
<option input="disc_time" arg="seconds" help="Time (seconds) - 65535 implies infinite" function="ldp_vty_disc_holdtime"/>
</option>
<option name="interval" help="Targeted hello interval">
<option input="disc_time" arg="seconds" help="Time (seconds)" function="ldp_vty_disc_interval"/>
</option>
</option>
</option>
</subtree>
<subtree name="session_holdtime">
<option name="session" help="Configure session parameters">
<option name="holdtime" help="Configure session holdtime">
<option input="session_time" arg="seconds" help="Time (seconds)" function="ldp_vty_session_holdtime"/>
</option>
</option>
</subtree>
<subtree name="af_common">
<include subtree="discovery_link"/>
<include subtree="discovery_targeted"/>
<option name="discovery" help="Configure discovery parameters">
<option name="targeted-hello" arg="hello_type" help="LDP Targeted Hellos">
<option name="accept" help="Accept and respond to targeted hellos" function="ldp_vty_targeted_hello_accept">
<option name="from" help="Access list to specify acceptable targeted hello source">
<select options="acl" arg="from_acl" function="inherited"/>
</option>
</option>
</option>
</option>
<option name="label" help="Configure label control and policies">
<option name="local" help="Configure local label control and policies">
<option name="advertise" help="Configure outbound label advertisement control" function="ldp_vty_label_advertise">
<include subtree="label_local_acls"/>
<option name="explicit-null" help="Configure explicit-null advertisement" function="ldp_vty_label_expnull">
<option name="for" help="IP access-list for destination prefixes">
<select options="acl" arg="for_acl" function="inherited"/>
</option>
</option>
</option>
<option name="allocate" help="Configure label allocation control">
<option name="for" help="IP access-list">
<select options="acl" arg="for_acl" function="ldp_vty_label_allocate"/>
</option>
<option name="host-routes" arg="host-routes" help="allocate local label for host routes only" function="ldp_vty_label_allocate"/>
</option>
</option>
<option name="remote" help="Configure remote/peer label control and policies">
<option name="accept" help="Configure inbound label acceptance control" function="ldp_vty_label_accept">
<include subtree="label_remote_acls"/>
</option>
</option>
</option>
<option name="ttl-security" help="LDP ttl security check">
<option name="disable" help="Disable ttl security" function="ldp_vty_ttl_security"/>
</option>
<include subtree="session_holdtime"/>
<option name="interface" help="Enable LDP on an interface and enter interface submode">
<option input="ifname" arg="ifname" help="Interface's name" function="ldp_vty_interface"/>
</option>
</subtree>
<!-- global -->
<subtree name="__global">
<option name="mpls" help="Global MPLS configuration subcommands">
<option name="ldp" help="Label Distribution Protocol" function="ldp_vty_mpls_ldp"/>
</option>
<option name="l2vpn" help="Configure l2vpn commands">
<option input="word" arg="name" help="L2VPN name">
<option name="type" help="L2VPN type">
<option name="vpls" help="Virtual Private LAN Service" function="ldp_vty_l2vpn"/>
</option>
</option>
</option>
</subtree>
<tree name="global">
<include subtree="__global"/>
<option name="no" arg="no" help="Negate a command or set its defaults">
<include subtree="__global"/>
</option>
</tree>
<!-- ldp node -->
<subtree name="__ldp_node">
<option name="address-family" help="Configure Address Family and its parameters">
<option name="ipv4" arg="address-family" help="IPv4" function="ldp_vty_address_family"/>
<option name="ipv6" arg="address-family" help="IPv6" function="ldp_vty_address_family"/>
</option>
<include subtree="discovery_link"/>
<include subtree="discovery_targeted"/>
<option name="dual-stack" help="Configure dual stack parameters">
<option name="transport-connection" help="Configure TCP transport parameters">
<option name="prefer" help="Configure prefered address family for TCP transport connection with neighbor">
<option name="ipv4" help="IPv4" function="ldp_vty_trans_pref_ipv4"/>
</option>
</option>
<option name="cisco-interop" help="Use Cisco non-compliant format to send and interpret the Dual-Stack capability TLV" function="ldp_vty_ds_cisco_interop"/>
</option>
<option name="neighbor" help="Configure neighbor parameters">
<option input="ipv4" arg="lsr_id" help="LDP Id of neighbor">
<option name="password" help="Configure password for MD5 authentication">
<option input="word" arg="password" help="The password" function="ldp_vty_neighbor_password"/>
</option>
<include subtree="session_holdtime"/>
<option name="ttl-security" help="LDP ttl security check">
<option name="disable" help="Disable ttl security" function="ldp_vty_neighbor_ttl_security"/>
<option name="hops" help="IP hops">
<option input="hops" arg="hops" help="maximum number of hops" function="ldp_vty_neighbor_ttl_security"/>
</option>
</option>
</option>
</option>
<option name="router-id" help="Configure router Id">
<option input="ipv4" arg="addr" help="LSR Id (in form of an IPv4 address)" function="ldp_vty_router_id"/>
</option>
</subtree>
<tree name="ldp_node">
<include subtree="__ldp_node"/>
<option name="no" arg="no" help="Negate a command or set its defaults">
<include subtree="__ldp_node"/>
</option>
</tree>
<!-- address-family ipv4 -->
<subtree name="__ldp_ipv4_node">
<include subtree="af_common"/>
<option name="discovery" help="Configure discovery parameters">
<option name="transport-address" help="Specify transport address for TCP connection">
<option input="ipv4" arg="addr" help="IP address to be used as transport address" function="ldp_vty_trans_addr"/>
</option>
</option>
<option name="neighbor" help="Configure neighbor parameters">
<option input="ipv4" arg="addr" help="IP address of neighbor">
<option name="targeted" help="Establish targeted session" function="ldp_vty_neighbor_targeted"/>
</option>
</option>
</subtree>
<tree name="ldp_ipv4_node">
<include subtree="__ldp_ipv4_node"/>
<option name="no" arg="no" help="Negate a command or set its defaults">
<include subtree="__ldp_ipv4_node"/>
</option>
</tree>
<!-- address-family ipv6 -->
<subtree name="__ldp_ipv6_node">
<include subtree="af_common"/>
<option name="discovery" help="Configure discovery parameters">
<option name="transport-address" help="Specify transport address for TCP connection">
<option input="ipv6" arg="addr" help="IPv6 address to be used as transport address" function="ldp_vty_trans_addr"/>
</option>
</option>
<option name="neighbor" help="Configure neighbor parameters">
<option input="ipv6" arg="addr" help="IPv6 address of neighbor">
<option name="targeted" help="Establish targeted session" function="ldp_vty_neighbor_targeted"/>
</option>
</option>
</subtree>
<tree name="ldp_ipv6_node">
<include subtree="__ldp_ipv6_node"/>
<option name="no" arg="no" help="Negate a command or set its defaults">
<include subtree="__ldp_ipv6_node"/>
</option>
</tree>
<!-- ldp ipv4 interface node -->
<subtree name="__ldp_ipv4_iface_node">
<include subtree="discovery_link"/>
</subtree>
<tree name="ldp_ipv4_iface_node">
<include subtree="__ldp_ipv4_iface_node"/>
<option name="no" arg="no" help="Negate a command or set its defaults">
<include subtree="__ldp_ipv4_iface_node"/>
</option>
</tree>
<!-- ldp ipv6 interface node -->
<subtree name="__ldp_ipv6_iface_node">
<include subtree="discovery_link"/>
</subtree>
<tree name="ldp_ipv6_iface_node">
<include subtree="__ldp_ipv6_iface_node"/>
<option name="no" arg="no" help="Negate a command or set its defaults">
<include subtree="__ldp_ipv6_iface_node"/>
</option>
</tree>
<!-- l2vpn -->
<subtree name="__ldp_l2vpn">
<option name="bridge" help="Bridge interface">
<option input="ifname" arg="ifname" help="Interface's name" function="ldp_vty_l2vpn_bridge"/>
</option>
<option name="mtu" help="set Maximum Transmission Unit">
<option input="mtu" arg="mtu" help="Maximum Transmission Unit value" function="ldp_vty_l2vpn_mtu"/>
</option>
<option name="member" help="L2VPN member configuration">
<option name="interface" help="Local interface">
<option input="ifname" arg="ifname" help="Interface's name" function="ldp_vty_l2vpn_interface"/>
</option>
<option name="pseudowire" help="Pseudowire interface">
<option input="ifname" arg="ifname" help="Interface's name" function="ldp_vty_l2vpn_pseudowire"/>
</option>
</option>
<option name="vc" help="Virtual Circuit options">
<option name="type" help="Virtual Circuit type to use">
<select options="pwtype" arg="type" function="ldp_vty_l2vpn_pwtype"/>
</option>
</option>
</subtree>
<tree name="ldp_l2vpn">
<include subtree="__ldp_l2vpn"/>
<option name="no" arg="no" help="Negate a command or set its defaults">
<include subtree="__ldp_l2vpn"/>
</option>
</tree>
<!-- l2vpn pseudowire -->
<subtree name="__ldp_pseudowire">
<option name="control-word" help="Control-word options">
<select options="cword" arg="preference" function="ldp_vty_l2vpn_pw_cword"/>
</option>
<option name="neighbor" help="Remote endpoint configuration">
<option name="address" help="Specify the IPv4 or IPv6 address of the remote endpoint">
<select options="addr" arg="addr" function="ldp_vty_l2vpn_pw_nbr_addr"/>
</option>
<option name="lsr-id" help="Specify the LSR-ID of the remote endpoint">
<option input="ipv4" arg="lsr-id" help="IPv4 address" function="ldp_vty_l2vpn_pw_nbr_id"/>
</option>
</option>
<option name="pw-id" help="Set the Virtual Circuit ID">
<option input="pwid" arg="pwid" help="Virtual Circuit ID value" function="ldp_vty_l2vpn_pw_pwid"/>
</option>
<option name="pw-status" help="Configure PW status">
<option name="disable" help="Disable PW status" function="ldp_vty_l2vpn_pw_pwstatus"/>
</option>
</subtree>
<tree name="ldp_pseudowire">
<include subtree="__ldp_pseudowire"/>
<option name="no" arg="no" help="Negate a command or set its defaults">
<include subtree="__ldp_pseudowire"/>
</option>
</tree>
<!-- exec mode commands -->
<subtree name="ldp_show_af">
<option name="binding" help="Label Information Base (LIB) information" function="ldp_vty_show_binding">
<option name="json" arg="json" help="JavaScript Object Notation" function="ldp_vty_show_binding"/>
<option name="detail" arg="detail" help="Show detailed information">
<option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_binding"/>
</option>
</option>
<option name="discovery" help="Discovery Hello Information" function="ldp_vty_show_discovery">
<option name="json" arg="json" help="JavaScript Object Notation" function="ldp_vty_show_discovery"/>
<option name="detail" arg="detail" help="Show detailed information">
<option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_discovery"/>
</option>
</option>
<option name="interface" help="interface information">
<option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_interface"/>
</option>
</subtree>
<tree name="ldp_exec">
<option name="show" help="Show running system information">
<option name="mpls" help="MPLS information">
<option name="ldp" help="Label Distribution Protocol">
<option name="capabilities" help="Display LDP Capabilities information">
<option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_capabilities"/>
</option>
<option name="neighbor" help="Neighbor information" function="ldp_vty_show_neighbor">
<option name="capabilities" arg="capabilities" help="Display neighbor capability information">
<option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_neighbor"/>
</option>
<option name="json" arg="json" help="JavaScript Object Notation" function="ldp_vty_show_neighbor"/>
<option name="detail" arg="detail" help="Show detailed information">
<option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_neighbor"/>
</option>
</option>
<include subtree="ldp_show_af"/>
<select options="address-family" arg="address-family">
<include subtree="ldp_show_af"/>
</select>
</option>
</option>
<option name="l2vpn" help="Show information about Layer2 VPN">
<option name="atom" help="Show Any Transport over MPLS information">
<option name="binding" help="Show AToM label binding information">
<option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_atom_binding"/>
</option>
<option name="vc" help="Show AToM virtual circuit information">
<option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_atom_vc"/>
</option>
</option>
</option>
<option name="debugging" help="Debugging functions">
<option name="mpls" help="MPLS information">
<option name="ldp" help="Label Distribution Protocol" function="ldp_vty_show_debugging"/>
</option>
</option>
</option>
<option name="clear" help="Reset functions">
<option name="mpls" help="Reset MPLS statistical information">
<option name="ldp" help="Clear LDP state">
<option name="neighbor" help="Clear LDP neighbor sessions" function="ldp_vty_clear_nbr">
<select options="addr" arg="addr" function="ldp_vty_clear_nbr"/>
</option>
</option>
</option>
</option>
</tree>
<!-- debug commands -->
<subtree name="__ldp_debug">
<option name="debug" help="Debugging functions">
<option name="mpls" help="MPLS information">
<option name="ldp" help="Label Distribution Protocol">
<option name="discovery" arg="type" help="Discovery messages">
<option name="hello" help="Discovery hello message">
<select options="dir" arg="dir" function="ldp_vty_debug"/>
</option>
</option>
<option name="errors" arg="type" help="Errors" function="ldp_vty_debug"/>
<option name="event" arg="type" help="LDP event information" function="ldp_vty_debug"/>
<option name="messages" arg="type" help="Messages">
<option name="recv" arg="dir" help="Received messages, excluding periodic Keep Alives" function="ldp_vty_debug">
<option name="all" arg="all" help="Received messages, including periodic Keep Alives" function="ldp_vty_debug"/>
</option>
<option name="sent" arg="dir" help="Sent messages, excluding periodic Keep Alives" function="ldp_vty_debug">
<option name="all" arg="all" help="Sent messages, including periodic Keep Alives" function="ldp_vty_debug"/>
</option>
</option>
<option name="zebra" arg="type" help="LDP zebra information" function="ldp_vty_debug"/>
</option>
</option>
</option>
</subtree>
<tree name="ldp_debug">
<include subtree="__ldp_debug"/>
<option name="no" arg="no" help="Negate a command or set its defaults">
<include subtree="__ldp_debug"/>
</option>
</tree>
<!-- nodes -->
<node name="CONFIG">
<include tree="global"/>
<include tree="ldp_debug"/>
</node>
<node install="1" install_default="1" config_write="ldp_config_write" name="LDP">
<include tree="ldp_node"/>
</node>
<node install="1" install_default="1" config_write="NULL" name="LDP_IPV4">
<include tree="ldp_ipv4_node"/>
</node>
<node install="1" install_default="1" config_write="NULL" name="LDP_IPV6">
<include tree="ldp_ipv6_node"/>
</node>
<node install="1" install_default="1" config_write="NULL" name="LDP_IPV4_IFACE">
<include tree="ldp_ipv4_iface_node"/>
</node>
<node install="1" install_default="1" config_write="NULL" name="LDP_IPV6_IFACE">
<include tree="ldp_ipv6_iface_node"/>
</node>
<node install="1" install_default="1" config_write="ldp_l2vpn_config_write" name="LDP_L2VPN">
<include tree="ldp_l2vpn"/>
</node>
<node install="1" install_default="1" config_write="NULL" name="LDP_PSEUDOWIRE">
<include tree="ldp_pseudowire"/>
</node>
<node install="1" config_write="ldp_debug_config_write" name="LDP_DEBUG"/>
<node name="ENABLE">
<include tree="ldp_debug"/>
</node>
<node name="VIEW">
<include tree="ldp_exec"/>
</node>
</file>

1133
ldpd/ldp_vty_cmds.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -37,8 +37,6 @@ static void ldp_af_config_write(struct vty *, int, struct ldpd_conf *,
static void ldp_l2vpn_pw_config_write(struct vty *, struct l2vpn_pw *);
static int ldp_vty_get_af(struct vty *);
static int ldp_iface_is_configured(struct ldpd_conf *, const char *);
static int ldp_vty_nbr_session_holdtime(struct vty *, struct vty_arg *[]);
static int ldp_vty_af_session_holdtime(struct vty *, struct vty_arg *[]);
struct cmd_node ldp_node =
{
@ -418,12 +416,8 @@ ldp_iface_is_configured(struct ldpd_conf *xconf, const char *ifname)
}
int
ldp_vty_mpls_ldp(struct vty *vty, struct vty_arg *args[])
ldp_vty_mpls_ldp(struct vty *vty, int disable)
{
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
if (disable)
vty_conf->flags &= ~F_LDPD_ENABLED;
else {
@ -437,15 +431,10 @@ ldp_vty_mpls_ldp(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_address_family(struct vty *vty, struct vty_arg *args[])
ldp_vty_address_family(struct vty *vty, int disable, const char *af_str)
{
struct ldpd_af_conf *af_conf;
int af;
const char *af_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
af_str = vty_get_arg_value(args, "address-family");
if (strcmp(af_str, "ipv4") == 0) {
af = AF_INET;
@ -480,7 +469,8 @@ ldp_vty_address_family(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[])
ldp_vty_disc_holdtime(struct vty *vty, int disable, const char *hello_type_str,
const char *seconds_str)
{
struct ldpd_af_conf *af_conf;
struct iface *iface;
@ -489,13 +479,6 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[])
char *ep;
long int secs;
enum hello_type hello_type;
const char *seconds_str;
const char *hello_type_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
seconds_str = vty_get_arg_value(args, "seconds");
hello_type_str = vty_get_arg_value(args, "hello_type");
secs = strtol(seconds_str, &ep, 10);
if (*ep != '\0' || secs < MIN_HOLDTIME || secs > MAX_HOLDTIME) {
@ -580,7 +563,8 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[])
ldp_vty_disc_interval(struct vty *vty, int disable, const char *hello_type_str,
const char *seconds_str)
{
struct ldpd_af_conf *af_conf;
struct iface *iface;
@ -589,13 +573,6 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[])
char *ep;
long int secs;
enum hello_type hello_type;
const char *seconds_str;
const char *hello_type_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
seconds_str = vty_get_arg_value(args, "seconds");
hello_type_str = vty_get_arg_value(args, "hello_type");
secs = strtol(seconds_str, &ep, 10);
if (*ep != '\0' || secs < MIN_HELLO_INTERVAL ||
@ -681,15 +658,11 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_targeted_hello_accept(struct vty *vty, struct vty_arg *args[])
ldp_vty_targeted_hello_accept(struct vty *vty, int disable,
const char *acl_from_str)
{
struct ldpd_af_conf *af_conf;
int af;
const char *acl_from_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
acl_from_str = vty_get_arg_value(args, "from_acl");
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
@ -711,20 +684,14 @@ ldp_vty_targeted_hello_accept(struct vty *vty, struct vty_arg *args[])
return (CMD_SUCCESS);
}
static int
ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[])
int
ldp_vty_nbr_session_holdtime(struct vty *vty, int disable,
const char *lsr_id_str, const char *seconds_str)
{
char *ep;
long int secs;
struct in_addr lsr_id;
struct nbr_params *nbrp;
const char *seconds_str;
const char *lsr_id_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
seconds_str = vty_get_arg_value(args, "seconds");
lsr_id_str = vty_get_arg_value(args, "lsr_id");
if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
bad_addr_v4(lsr_id)) {
@ -763,18 +730,14 @@ ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[])
return (CMD_SUCCESS);
}
static int
ldp_vty_af_session_holdtime(struct vty *vty, struct vty_arg *args[])
int
ldp_vty_af_session_holdtime(struct vty *vty, int disable,
const char *seconds_str)
{
struct ldpd_af_conf *af_conf;
int af;
char *ep;
long int secs;
const char *seconds_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
seconds_str = vty_get_arg_value(args, "seconds");
secs = strtol(seconds_str, &ep, 10);
if (*ep != '\0' || secs < MIN_KEEPALIVE || secs > MAX_KEEPALIVE) {
@ -796,30 +759,11 @@ ldp_vty_af_session_holdtime(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_session_holdtime(struct vty *vty, struct vty_arg *args[])
{
switch (vty->node) {
case LDP_NODE:
return (ldp_vty_nbr_session_holdtime(vty, args));
case LDP_IPV4_NODE:
case LDP_IPV6_NODE:
return (ldp_vty_af_session_holdtime(vty, args));
default:
fatalx("ldp_vty_session_holdtime: unexpected node");
}
}
int
ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
ldp_vty_interface(struct vty *vty, int disable, const char *ifname)
{
int af;
struct iface *iface;
struct iface_af *ia;
const char *ifname;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
ifname = vty_get_arg_value(args, "ifname");
af = ldp_vty_get_af(vty);
iface = if_lookup_name(vty_conf, ifname);
@ -878,15 +822,10 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_trans_addr(struct vty *vty, struct vty_arg *args[])
ldp_vty_trans_addr(struct vty *vty, int disable, const char *addr_str)
{
struct ldpd_af_conf *af_conf;
int af;
const char *addr_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
addr_str = vty_get_arg_value(args, "addr");
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
@ -907,16 +846,11 @@ ldp_vty_trans_addr(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[])
ldp_vty_neighbor_targeted(struct vty *vty, int disable, const char *addr_str)
{
int af;
union ldpd_addr addr;
struct tnbr *tnbr;
const char *addr_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
addr_str = vty_get_arg_value(args, "addr");
af = ldp_vty_get_af(vty);
@ -959,17 +893,11 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_label_advertise(struct vty *vty, struct vty_arg *args[])
ldp_vty_label_advertise(struct vty *vty, int disable, const char *acl_to_str,
const char *acl_for_str)
{
struct ldpd_af_conf *af_conf;
int af;
const char *acl_to_str;
const char *acl_for_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
acl_to_str = vty_get_arg_value(args, "to_acl");
acl_for_str = vty_get_arg_value(args, "for_acl");
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
@ -996,17 +924,11 @@ ldp_vty_label_advertise(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_label_allocate(struct vty *vty, struct vty_arg *args[])
ldp_vty_label_allocate(struct vty *vty, int disable, int host_routes,
const char *acl_for_str)
{
struct ldpd_af_conf *af_conf;
int af;
const char *acl_for_str;
const char *host_routes_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
acl_for_str = vty_get_arg_value(args, "for_acl");
host_routes_str = vty_get_arg_value(args, "host-routes");
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
@ -1014,7 +936,7 @@ ldp_vty_label_allocate(struct vty *vty, struct vty_arg *args[])
af_conf->flags &= ~F_LDPD_AF_ALLOCHOSTONLY;
af_conf->acl_label_allocate_for[0] = '\0';
if (!disable) {
if (host_routes_str)
if (host_routes)
af_conf->flags |= F_LDPD_AF_ALLOCHOSTONLY;
else
strlcpy(af_conf->acl_label_allocate_for, acl_for_str,
@ -1027,15 +949,10 @@ ldp_vty_label_allocate(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_label_expnull(struct vty *vty, struct vty_arg *args[])
ldp_vty_label_expnull(struct vty *vty, int disable, const char *acl_for_str)
{
struct ldpd_af_conf *af_conf;
int af;
const char *acl_for_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
acl_for_str = vty_get_arg_value(args, "for_acl");
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
@ -1058,17 +975,11 @@ ldp_vty_label_expnull(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_label_accept(struct vty *vty, struct vty_arg *args[])
ldp_vty_label_accept(struct vty *vty, int disable, const char *acl_from_str,
const char *acl_for_str)
{
struct ldpd_af_conf *af_conf;
int af;
const char *acl_from_str;
const char *acl_for_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
acl_from_str = vty_get_arg_value(args, "from_acl");
acl_for_str = vty_get_arg_value(args, "for_acl");
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
@ -1095,13 +1006,10 @@ ldp_vty_label_accept(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_ttl_security(struct vty *vty, struct vty_arg *args[])
ldp_vty_ttl_security(struct vty *vty, int disable)
{
struct ldpd_af_conf *af_conf;
int af;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
@ -1117,14 +1025,8 @@ ldp_vty_ttl_security(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_router_id(struct vty *vty, struct vty_arg *args[])
ldp_vty_router_id(struct vty *vty, int disable, const char *addr_str)
{
const char *addr_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
addr_str = vty_get_arg_value(args, "addr");
if (disable)
vty_conf->rtr_id.s_addr = INADDR_ANY;
else {
@ -1141,12 +1043,8 @@ ldp_vty_router_id(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_ds_cisco_interop(struct vty *vty, struct vty_arg *args[])
ldp_vty_ds_cisco_interop(struct vty *vty, int disable)
{
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
if (disable)
vty_conf->flags &= ~F_LDPD_DS_CISCO_INTEROP;
else
@ -1158,12 +1056,8 @@ ldp_vty_ds_cisco_interop(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_trans_pref_ipv4(struct vty *vty, struct vty_arg *args[])
ldp_vty_trans_pref_ipv4(struct vty *vty, int disable)
{
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
if (disable)
vty_conf->trans_pref = DUAL_STACK_LDPOV6;
else
@ -1175,18 +1069,12 @@ ldp_vty_trans_pref_ipv4(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[])
ldp_vty_neighbor_password(struct vty *vty, int disable, const char *lsr_id_str,
const char *password_str)
{
struct in_addr lsr_id;
size_t password_len;
struct nbr_params *nbrp;
const char *lsr_id_str;
const char *password_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
lsr_id_str = vty_get_arg_value(args, "lsr_id");
password_str = vty_get_arg_value(args, "password");
if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
bad_addr_v4(lsr_id)) {
@ -1226,19 +1114,13 @@ ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_neighbor_ttl_security(struct vty *vty, struct vty_arg *args[])
ldp_vty_neighbor_ttl_security(struct vty *vty, int disable,
const char *lsr_id_str, const char *hops_str)
{
struct in_addr lsr_id;
struct nbr_params *nbrp;
long int hops = 0;
char *ep;
const char *lsr_id_str;
const char *hops_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
lsr_id_str = vty_get_arg_value(args, "lsr_id");
hops_str = vty_get_arg_value(args, "hops");
if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
bad_addr_v4(lsr_id)) {
@ -1286,16 +1168,11 @@ ldp_vty_neighbor_ttl_security(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
ldp_vty_l2vpn(struct vty *vty, int disable, const char *name_str)
{
struct l2vpn *l2vpn;
struct l2vpn_if *lif;
struct l2vpn_pw *pw;
const char *name_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
name_str = vty_get_arg_value(args, "name");
l2vpn = l2vpn_find(vty_conf, name_str);
@ -1336,14 +1213,9 @@ ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_l2vpn_bridge(struct vty *vty, struct vty_arg *args[])
ldp_vty_l2vpn_bridge(struct vty *vty, int disable, const char *ifname)
{
VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
const char *ifname;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
ifname = vty_get_arg_value(args, "ifname");
if (disable)
memset(l2vpn->br_ifname, 0, sizeof(l2vpn->br_ifname));
@ -1356,16 +1228,11 @@ ldp_vty_l2vpn_bridge(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_l2vpn_mtu(struct vty *vty, struct vty_arg *args[])
ldp_vty_l2vpn_mtu(struct vty *vty, int disable, const char *mtu_str)
{
VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
char *ep;
int mtu;
const char *mtu_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
mtu_str = vty_get_arg_value(args, "mtu");
mtu = strtol(mtu_str, &ep, 10);
if (*ep != '\0' || mtu < MIN_L2VPN_MTU || mtu > MAX_L2VPN_MTU) {
@ -1384,15 +1251,10 @@ ldp_vty_l2vpn_mtu(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_l2vpn_pwtype(struct vty *vty, struct vty_arg *args[])
ldp_vty_l2vpn_pwtype(struct vty *vty, int disable, const char *type_str)
{
VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
int pw_type;
const char *type_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
type_str = vty_get_arg_value(args, "type");
if (strcmp(type_str, "ethernet") == 0)
pw_type = PW_TYPE_ETHERNET;
@ -1410,15 +1272,10 @@ ldp_vty_l2vpn_pwtype(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
ldp_vty_l2vpn_interface(struct vty *vty, int disable, const char *ifname)
{
VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
struct l2vpn_if *lif;
const char *ifname;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
ifname = vty_get_arg_value(args, "ifname");
lif = l2vpn_if_find(l2vpn, ifname);
@ -1453,15 +1310,10 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
ldp_vty_l2vpn_pseudowire(struct vty *vty, int disable, const char *ifname)
{
VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
struct l2vpn_pw *pw;
const char *ifname;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
ifname = vty_get_arg_value(args, "ifname");
pw = l2vpn_pw_find(l2vpn, ifname);
@ -1504,14 +1356,9 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_l2vpn_pw_cword(struct vty *vty, struct vty_arg *args[])
ldp_vty_l2vpn_pw_cword(struct vty *vty, int disable, const char *preference_str)
{
VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
const char *preference_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
preference_str = vty_get_arg_value(args, "preference");
if (disable)
pw->flags |= F_PW_CWORD_CONF;
@ -1528,16 +1375,11 @@ ldp_vty_l2vpn_pw_cword(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[])
ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, int disable, const char *addr_str)
{
VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
int af;
union ldpd_addr addr;
const char *addr_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
addr_str = vty_get_arg_value(args, "addr");
if (ldp_get_address(addr_str, &af, &addr) == -1 ||
bad_addr(af, &addr)) {
@ -1561,15 +1403,10 @@ ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[])
ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, int disable, const char *lsr_id_str)
{
VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
struct in_addr lsr_id;
const char *lsr_id_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
lsr_id_str = vty_get_arg_value(args, "lsr-id");
if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
bad_addr_v4(lsr_id)) {
@ -1588,16 +1425,11 @@ ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_l2vpn_pw_pwid(struct vty *vty, struct vty_arg *args[])
ldp_vty_l2vpn_pw_pwid(struct vty *vty, int disable, const char *pwid_str)
{
VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
char *ep;
uint32_t pwid;
const char *pwid_str;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
pwid_str = vty_get_arg_value(args, "pwid");
pwid = strtol(pwid_str, &ep, 10);
if (*ep != '\0' || pwid < MIN_PWID_ID || pwid > MAX_PWID_ID) {
@ -1616,12 +1448,9 @@ ldp_vty_l2vpn_pw_pwid(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_l2vpn_pw_pwstatus(struct vty *vty, struct vty_arg *args[])
ldp_vty_l2vpn_pw_pwstatus(struct vty *vty, int disable)
{
VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
if (disable)
pw->flags |= F_PW_STATUSTLV_CONF;

View File

@ -1582,24 +1582,22 @@ ldp_vty_get_af(const char *str, int *af)
}
int
ldp_vty_show_binding(struct vty *vty, struct vty_arg *args[])
ldp_vty_show_binding(struct vty *vty, const char *af_str, int detail, int json)
{
struct imsgbuf ibuf;
struct show_params params;
const char *af_str;
int af;
if (ldp_vty_connect(&ibuf) < 0)
return (CMD_WARNING);
af_str = vty_get_arg_value(args, "address-family");
if (ldp_vty_get_af(af_str, &af) < 0)
return (CMD_ERR_NO_MATCH);
memset(&params, 0, sizeof(params));
params.family = af;
params.detail = vty_get_arg_value(args, "detail") ? 1 : 0;
params.json = vty_get_arg_value(args, "json") ? 1 : 0;
params.detail = detail;
params.json = json;
if (!params.detail && !params.json)
vty_out(vty, "%-4s %-20s %-15s %-11s %-13s %6s%s", "AF",
@ -1611,24 +1609,23 @@ ldp_vty_show_binding(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_show_discovery(struct vty *vty, struct vty_arg *args[])
ldp_vty_show_discovery(struct vty *vty, const char *af_str, int detail,
int json)
{
struct imsgbuf ibuf;
struct show_params params;
const char *af_str;
int af;
if (ldp_vty_connect(&ibuf) < 0)
return (CMD_WARNING);
af_str = vty_get_arg_value(args, "address-family");
if (ldp_vty_get_af(af_str, &af) < 0)
return (CMD_ERR_NO_MATCH);
memset(&params, 0, sizeof(params));
params.family = af;
params.detail = vty_get_arg_value(args, "detail") ? 1 : 0;
params.json = vty_get_arg_value(args, "json") ? 1 : 0;
params.detail = detail;
params.json = json;
if (!params.detail && !params.json)
vty_out(vty, "%-4s %-15s %-8s %-15s %9s%s",
@ -1643,24 +1640,22 @@ ldp_vty_show_discovery(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_show_interface(struct vty *vty, struct vty_arg *args[])
ldp_vty_show_interface(struct vty *vty, const char *af_str, int json)
{
struct imsgbuf ibuf;
struct show_params params;
unsigned int ifidx = 0;
const char *af_str;
int af;
if (ldp_vty_connect(&ibuf) < 0)
return (CMD_WARNING);
af_str = vty_get_arg_value(args, "address-family");
if (ldp_vty_get_af(af_str, &af) < 0)
return (CMD_ERR_NO_MATCH);
memset(&params, 0, sizeof(params));
params.family = af;
params.json = vty_get_arg_value(args, "json") ? 1 : 0;
params.json = json;
/* header */
if (!params.json) {
@ -1675,9 +1670,9 @@ ldp_vty_show_interface(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_show_capabilities(struct vty *vty, struct vty_arg *args[])
ldp_vty_show_capabilities(struct vty *vty, int json)
{
if (vty_get_arg_value(args, "json")) {
if (json) {
json_object *json;
json_object *json_array;
json_object *json_cap;
@ -1727,7 +1722,7 @@ ldp_vty_show_capabilities(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_show_neighbor(struct vty *vty, struct vty_arg *args[])
ldp_vty_show_neighbor(struct vty *vty, int capabilities, int detail, int json)
{
struct imsgbuf ibuf;
struct show_params params;
@ -1736,9 +1731,9 @@ ldp_vty_show_neighbor(struct vty *vty, struct vty_arg *args[])
return (CMD_WARNING);
memset(&params, 0, sizeof(params));
params.capabilities = vty_get_arg_value(args, "capabilities") ? 1 : 0;
params.detail = vty_get_arg_value(args, "detail") ? 1 : 0;
params.json = vty_get_arg_value(args, "json") ? 1 : 0;
params.capabilities = capabilities;
params.detail = detail;
params.json = json;
if (params.capabilities)
params.detail = 1;
@ -1753,7 +1748,7 @@ ldp_vty_show_neighbor(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_show_atom_binding(struct vty *vty, struct vty_arg *args[])
ldp_vty_show_atom_binding(struct vty *vty, int json)
{
struct imsgbuf ibuf;
struct show_params params;
@ -1762,14 +1757,14 @@ ldp_vty_show_atom_binding(struct vty *vty, struct vty_arg *args[])
return (CMD_WARNING);
memset(&params, 0, sizeof(params));
params.json = vty_get_arg_value(args, "json") ? 1 : 0;
params.json = json;
imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0);
return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, &params));
}
int
ldp_vty_show_atom_vc(struct vty *vty, struct vty_arg *args[])
ldp_vty_show_atom_vc(struct vty *vty, int json)
{
struct imsgbuf ibuf;
struct show_params params;
@ -1778,7 +1773,7 @@ ldp_vty_show_atom_vc(struct vty *vty, struct vty_arg *args[])
return (CMD_WARNING);
memset(&params, 0, sizeof(params));
params.json = vty_get_arg_value(args, "json") ? 1 : 0;
params.json = json;
if (!params.json) {
/* header */
@ -1795,14 +1790,11 @@ ldp_vty_show_atom_vc(struct vty *vty, struct vty_arg *args[])
}
int
ldp_vty_clear_nbr(struct vty *vty, struct vty_arg *args[])
ldp_vty_clear_nbr(struct vty *vty, const char *addr_str)
{
struct imsgbuf ibuf;
const char *addr_str;
struct ctl_nbr nbr;
addr_str = vty_get_arg_value(args, "addr");
memset(&nbr, 0, sizeof(nbr));
if (addr_str &&
(ldp_get_address(addr_str, &nbr.af, &nbr.raddr) == -1 ||

View File

@ -3151,29 +3151,3 @@ vty_terminate (void)
Vvty_serv_thread = NULL;
}
}
/* Utility functions to get arguments from commands generated
by the xml2cli.pl script. */
const char *
vty_get_arg_value (struct vty_arg *args[], const char *arg)
{
while (*args)
{
if (strcmp ((*args)->name, arg) == 0)
return (*args)->value;
args++;
}
return NULL;
}
struct vty_arg *
vty_get_arg (struct vty_arg *args[], const char *arg)
{
while (*args)
{
if (strcmp ((*args)->name, arg) == 0)
return *args;
args++;
}
return NULL;
}

View File

@ -342,7 +342,4 @@ extern void vty_hello (struct vty *);
an async-signal-safe function. */
extern void vty_log_fixed (char *buf, size_t len);
extern const char *vty_get_arg_value (struct vty_arg **, const char *);
extern struct vty_arg *vty_get_arg (struct vty_arg **, const char *);
#endif /* _ZEBRA_VTY_H */

View File

@ -13,6 +13,4 @@ sbin_SCRIPTS = frr-reload.py frr
EXTRA_DIST += frr.service frr-reload.py frr
EXTRA_DIST += xml2cli.pl
ssd_SOURCES = start-stop-daemon.c

View File

@ -1,446 +0,0 @@
#!/usr/bin/perl
##
## Parse a XML file containing a tree-like representation of Quagga CLI
## commands and generate a file with:
##
## - a DEFUN function for each command;
## - an initialization function.
##
##
## Copyright (C) 2012 Renato Westphal <renatow@digistar.com.br>
## 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 strict;
use warnings;
use Getopt::Std;
use vars qw($opt_d);
use File::Basename qw(fileparse);
use XML::LibXML;
%::input_strs = (
"ifname" => "IFNAME",
"word" => "WORD",
"line" => ".LINE",
"ipv4" => "A.B.C.D",
"ipv4m" => "A.B.C.D/M",
"ipv6" => "X:X::X:X",
"ipv6m" => "X:X::X:X/M",
"mtu" => "(1500-9180)",
"acl_range" => "(1-199)",
"acl_expanded_range" => "(1300-2699)",
# BGP specific
"rd" => "ASN:nn_or_IP-address:nn",
"asn" => "(1-4294967295)",
"community" => "AA:NN",
"clist" => "(1-500)",
# LDP specific
"disc_time" => "(1-65535)",
"session_time" => "(15-65535)",
"pwid" => "(1-4294967295)",
"hops" => "(1-254)"
);
# parse options node and store the corresponding information
# into a global hash of hashes
sub parse_options {
my $xml_node = $_[0];
my @cmdstr;
my $options_name = $xml_node->findvalue('./@name');
if (not $options_name) {
die('error: "options" node without "name" attribute');
}
# initialize hash
$::options{$options_name}{'cmdstr'} = "";
$::options{$options_name}{'help'} = "";
my @children = $xml_node->getChildnodes();
foreach my $child(@children) {
# skip comments, random text, etc
if ($child->getType() != XML_ELEMENT_NODE) {
next;
}
# check for error/special conditions
if ($child->getName() ne "option") {
die('error: invalid node type: "' . $child->getName() . '"');
}
my $name = $child->findvalue('./@name');
my $input = $child->findvalue('./@input');
my $help = $child->findvalue('./@help');
if ($input) {
$name = $::input_strs{$input};
}
push (@cmdstr, $name);
$::options{$options_name}{'help'} .= "\n \"" . $help . "\\n\"";
}
$::options{$options_name}{'cmdstr'} = "<" . join('|', @cmdstr) . ">";
}
# given a subtree, replace all the corresponding include nodes by
# this subtree
sub subtree_replace_includes {
my $subtree = $_[0];
my $subtree_name = $subtree->findvalue('./@name');
if (not $subtree_name) {
die("subtree without \"name\" attribute");
}
my $query = "//include[\@subtree='$subtree_name']";
foreach my $include_node($::xml->findnodes($query)) {
my @children = $subtree->getChildnodes();
foreach my $child(reverse @children) {
my $include_node_parent = $include_node->getParentNode();
$include_node_parent->insertAfter($child->cloneNode(1),
$include_node);
}
$include_node->unbindNode();
}
$subtree->unbindNode();
}
# generate arguments for a given command
sub generate_arguments {
my @nodes = @_;
my $arguments;
my $no_args = 1;
my $argc = -1;
$arguments .= " struct vty_arg *args[] =\n";
$arguments .= " {\n";
for (my $i = 0; $i < @nodes; $i++) {
my %node = %{$nodes[$i]};
my $arg_value;
$argc++;
if (not $node{'arg'}) {
next;
}
$no_args = 0;
# for input and select nodes, the value of the argument is an
# argv[] element. for the other types of nodes, the value of the
# argument is the name of the node
if ($node{'input'} or $node{'type'} eq "select") {
$arg_value = "argv[" . $argc . "]->arg";
} elsif ($node{'optional'}) {
$arg_value = "(argc > " . $argc . " ? argv[" . $argc. "]->arg : NULL)";
} else {
$arg_value = '"' . $node{'name'} . '"';
}
if ($node{'input'} and $node{'input'} eq "line") {
# arguments of the type 'line' may have multiple spaces (i.e
# they don't fit into a single argv[] element). to properly
# handle these arguments, we need to provide direct access
# to the argv[] array and the argc variable.
my $argc_str = "argc" . (($argc > 1) ? " - " . ($argc - 1) : "");
my $argv_str = "argv" . (($argc > 1) ? " + " . ($argc - 1) : "");
$arguments .= " &(struct vty_arg) { "
. ".name = \"" . $node{'arg'} . "\", "
. ".argc = $argc_str, "
. ".argv = $argv_str },\n";
} else {
# common case - each argument has a name and a single value
$arguments .= " &(struct vty_arg) { "
. ".name = \"" . $node{'arg'} . "\", "
. ".value = " . $arg_value . " },\n";
}
}
$arguments .= " NULL\n";
$arguments .= " };\n";
# handle special case
if ($no_args) {
return " struct vty_arg *args[] = { NULL };\n";
}
return $arguments;
}
# generate C code
sub generate_code {
my @nodes = @_;
my $funcname = '';
my $cmdstr = '';
my $cmdname = '';
my $helpstr = '';
my $function = '';
for (my $i = 0; $i < @nodes; $i++) {
my %node = %{$nodes[$i]};
if ($node{'input'}) {
$funcname .= $node{'input'} . " ";
$cmdstr .= $::input_strs{$node{'input'}} . " ";
$helpstr .= "\n \"" . $node{'help'} . "\\n\"";
} elsif ($node{'type'} eq "select") {
my $options_name = $node{'options'};
$funcname .= $options_name . " ";
$cmdstr .= $::options{$options_name}{'cmdstr'} . " ";
$helpstr .= $::options{$options_name}{'help'};
} else {
$funcname .= $node{'name'} . " ";
if ($node{'optional'}) {
$cmdstr .= "[" . $node{'name'} . "] ";
} else {
$cmdstr .= $node{'name'} . " ";
}
$helpstr .= "\n \"" . $node{'help'} . "\\n\"";
}
# update the command string
if ($node{'function'} ne "inherited" and $node{'function'}) {
$function = $node{'function'};
}
}
# rtrim
$funcname =~ s/\s+$//;
$cmdstr =~ s/\s+$//;
# lowercase
$funcname = lc($funcname);
# replace " " by "_"
$funcname =~ tr/ /_/;
# replace "-" by "_"
$funcname =~ tr/-/_/;
# add prefix
$funcname = $::cmdprefix . '_' . $funcname;
# generate DEFUN
$cmdname = $funcname . "_cmd";
# don't generate same command more than once
if ($::commands{$cmdname}) {
return $cmdname;
}
$::commands{$cmdname} = "1";
print STDOUT "DEFUN (" . $funcname . ",\n"
. " " . $cmdname . ",\n"
. " \"" . $cmdstr . "\","
. $helpstr . ")\n"
. "{\n"
. generate_arguments(@nodes)
. " return " . $function . " (vty, args);\n"
. "}\n\n";
return $cmdname;
}
# parse tree node (recursive function)
sub parse_tree {
# get args
my $xml_node = $_[0];
my @nodes = @{$_[1]};
my $tree_name = $_[2];
# hash containing all the node attributes
my %node;
$node{'type'} = $xml_node->getName();
# check for error/special conditions
if ($node{'type'} eq "tree") {
goto end;
}
if ($node{'type'} eq "include") {
die('error: can not include "'
. $xml_node->findvalue('./@subtree') . '"');
}
if (not $node{'type'} ~~ [qw(option select)]) {
die('error: invalid node type: "' . $node{'type'} . '"');
}
if ($node{'type'} eq "select") {
my $options_name = $xml_node->findvalue('./@options');
if (not $options_name) {
die('error: "select" node without "name" attribute');
}
if (not $::options{$options_name}) {
die('error: can not find options');
}
$node{'options'} = $options_name;
}
# get node attributes
$node{'name'} = $xml_node->findvalue('./@name');
$node{'input'} = $xml_node->findvalue('./@input');
$node{'arg'} = $xml_node->findvalue('./@arg');
$node{'help'} = $xml_node->findvalue('./@help');
$node{'function'} = $xml_node->findvalue('./@function');
$node{'ifdef'} = $xml_node->findvalue('./@ifdef');
$node{'optional'} = $xml_node->findvalue('./@optional');
# push node to stack
push (@nodes, \%node);
# generate C code
if ($node{'function'}) {
my $cmdname = generate_code(@nodes);
push (@{$::trees{$tree_name}}, [0, $cmdname, 0]);
}
if ($node{'ifdef'}) {
push (@{$::trees{$tree_name}}, [$node{'ifdef'}, 0, 0]);
}
end:
# recursively process child nodes
my @children = $xml_node->getChildnodes();
foreach my $child(@children) {
# skip comments, random text, etc
if ($child->getType() != XML_ELEMENT_NODE) {
next;
}
parse_tree($child, \@nodes, $tree_name);
}
if ($node{'ifdef'}) {
push (@{$::trees{$tree_name}}, [0, 0, $node{'ifdef'}]);
}
}
sub parse_node {
# get args
my $xml_node = $_[0];
my $node_name = $xml_node->findvalue('./@name');
if (not $node_name) {
die('missing the "name" attribute');
}
my $install = $xml_node->findvalue('./@install');
my $config_write = $xml_node->findvalue('./@config_write');
if ($install and $install eq "1") {
print " install_node (&" .lc( $node_name) . "_node, " . $config_write . ");\n";
}
my $install_default = $xml_node->findvalue('./@install_default');
if ($install_default and $install_default eq "1") {
print " install_default (" . $node_name . "_NODE);\n";
}
my @children = $xml_node->getChildnodes();
foreach my $child(@children) {
# skip comments, random text, etc
if ($child->getType() != XML_ELEMENT_NODE) {
next;
}
if ($child->getName() ne "include") {
die('error: invalid node type: "' . $child->getName() . '"');
}
my $tree_name = $child->findvalue('./@tree');
if (not $tree_name) {
die('missing the "tree" attribute');
}
foreach my $entry (@{$::trees{$tree_name}}) {
my ($ifdef, $cmdname, $endif) = @{$entry};
if ($ifdef) {
print ("#ifdef " . $ifdef . "\n");
}
if ($cmdname) {
print " install_element (" . $node_name . "_NODE, &" . $cmdname . ");\n";
}
if ($endif) {
print ("#endif /* " . $endif . " */\n");
}
}
}
}
# parse command-line arguments
if (not getopts('d')) {
die("Usage: xml2cli.pl [-d] FILE\n");
}
my $file = shift;
# initialize the XML parser
my $parser = new XML::LibXML;
$parser->keep_blanks(0);
# parse XML file
$::xml = $parser->parse_file($file);
my $xmlroot = $::xml->getDocumentElement();
if ($xmlroot->getName() ne "file") {
die('XML root element name must be "file"');
}
# read file attributes
my $init_function = $xmlroot->findvalue('./@init');
if (not $init_function) {
die('missing the "init" attribute in the "file" node');
}
$::cmdprefix = $xmlroot->findvalue('./@cmdprefix');
if (not $::cmdprefix) {
die('missing the "cmdprefix" attribute in the "file" node');
}
my $header = $xmlroot->findvalue('./@header');
if (not $header) {
die('missing the "header" attribute in the "file" node');
}
# generate source header
print STDOUT "/* Auto-generated from " . fileparse($file) . ". */\n"
. "/* Do not edit! */\n\n"
. "#include <zebra.h>\n\n"
. "#include \"command.h\"\n"
. "#include \"vty.h\"\n"
. "#include \"$header\"\n\n";
# Parse options
foreach my $options($::xml->findnodes("/file/options")) {
parse_options($options);
}
# replace include nodes by the corresponding subtrees
foreach my $subtree(reverse $::xml->findnodes("/file/subtree")) {
subtree_replace_includes($subtree);
}
# Parse trees
foreach my $tree($::xml->findnodes("/file/tree")) {
my @nodes = ();
my $tree_name = $tree->findvalue('./@name');
parse_tree($tree, \@nodes, $tree_name);
}
# install function header
print STDOUT "void\n"
. $init_function . " (void)\n"
. "{\n";
# Parse nodes
foreach my $node($::xml->findnodes("/file/node")) {
parse_node($node);
}
# closing braces for the install function
print STDOUT "}";
# print to stderr the expanded XML file if the debug flag (-d) is given
if ($opt_d) {
print STDERR $::xml->toString(1);
}

View File

@ -108,6 +108,10 @@ vtysh_scan += $(top_srcdir)/ripngd/ripng_zebra.c
vtysh_scan += $(top_srcdir)/ripngd/ripngd.c
endif
if LDPD
vtysh_scan += $(top_srcdir)/ldpd/ldp_vty_cmds.c
endif
if NHRPD
vtysh_scan += $(top_srcdir)/nhrpd/nhrp_vty.c
endif
@ -146,22 +150,5 @@ vtysh_cmd_FILES = $(vtysh_scan) \
$(top_srcdir)/watchfrr/watchfrr_vty.c \
$(BGP_VNC_RFAPI_SRC) $(BGP_VNC_RFP_SRC)
# this is slightly iffy... ldp_vty_cmds.c can be located in either
# $srcdir or $builddir depending on whether it's coming pre-built from a
# dist tarball or being built. automake uses VPATH to find it, but that
# doesn't work here...
# so after running "make ldp_vty_cmds.c", the file can be in either of the
# two directories. we need to do some magic to find out which.
vtysh_cmd_DEPS = $(vtysh_cmd_FILES)
if LDPD
$(top_builddir)/ldpd/ldp_vty_cmds.c:
make -C "$(top_builddir)/ldpd" ldp_vty_cmds.c
vtysh_cmd_DEPS += $(top_builddir)/ldpd/ldp_vty_cmds.c
endif
vtysh_cmd.c: $(vtysh_cmd_DEPS) extract.pl
if test -n "${LDPD}"; then \
ldpcmds="$(top_srcdir)/ldpd/ldp_vty_cmds.c"; \
test -f "$(top_builddir)/ldpd/ldp_vty_cmds.c" && ldpcmds="$(top_builddir)/ldpd/ldp_vty_cmds.c"; \
fi; \
./extract.pl $(vtysh_cmd_FILES) $${ldpcmds} > vtysh_cmd.c
vtysh_cmd.c: $(vtysh_cmd_FILES) extract.pl
./extract.pl $(vtysh_cmd_FILES) > vtysh_cmd.c