diff options
| author | Quentin Young <qlyoung@cumulusnetworks.com> | 2019-09-11 20:59:46 +0000 | 
|---|---|---|
| committer | Quentin Young <qlyoung@cumulusnetworks.com> | 2019-12-09 14:39:18 -0500 | 
| commit | f495425b64b50c32c5db29a30224f1b15d5b3a3b (patch) | |
| tree | 390589d6858a8c2f2f1aa620f3e720445bcd8a77 /vrrpd | |
| parent | e6a70ae8f108c7c82cf3d0e0937c3e76c0310e1e (diff) | |
vrrpd: northbound conversion
Convert VRRPD to use the northbound API.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Diffstat (limited to 'vrrpd')
| -rw-r--r-- | vrrpd/subdir.am | 4 | ||||
| -rw-r--r-- | vrrpd/vrrp.c | 12 | ||||
| -rw-r--r-- | vrrpd/vrrp.h | 7 | ||||
| -rw-r--r-- | vrrpd/vrrp_main.c | 1 | ||||
| -rw-r--r-- | vrrpd/vrrp_northbound.c | 814 | ||||
| -rw-r--r-- | vrrpd/vrrp_vty.c | 265 | ||||
| -rw-r--r-- | vrrpd/vrrp_vty.h | 15 | 
7 files changed, 972 insertions, 146 deletions
diff --git a/vrrpd/subdir.am b/vrrpd/subdir.am index 57eec108cb..d81594ad93 100644 --- a/vrrpd/subdir.am +++ b/vrrpd/subdir.am @@ -15,6 +15,7 @@ vrrpd_libvrrp_a_SOURCES = \  	vrrpd/vrrp_arp.c \  	vrrpd/vrrp_debug.c \  	vrrpd/vrrp_ndisc.c \ +	vrrpd/vrrp_northbound.c \  	vrrpd/vrrp_packet.c \  	vrrpd/vrrp_vty.c \  	vrrpd/vrrp_zebra.c \ @@ -35,3 +36,6 @@ vrrpd/vrrp_vty.$(OBJEXT): vrrpd/vrrp_vty_clippy.c  vrrpd_vrrpd_SOURCES = vrrpd/vrrp_main.c  vrrpd_vrrpd_LDADD = vrrpd/libvrrp.a lib/libfrr.la @LIBCAP@ +nodist_vrrpd_vrrpd_SOURCES = \ +	yang/frr-vrrpd.yang.c \ +	# end diff --git a/vrrpd/vrrp.c b/vrrpd/vrrp.c index 7a68b6b829..77bdf79b94 100644 --- a/vrrpd/vrrp.c +++ b/vrrpd/vrrp.c @@ -2337,6 +2337,7 @@ int vrrp_config_write_global(struct vty *vty)  		vty_out(vty, "vrrp autoconfigure%s\n",  			vrrp_autoconfig_version == 2 ? " version 2" : ""); +	/* FIXME: needs to be udpated for full YANG conversion. */  	if (vd.priority != VRRP_DEFAULT_PRIORITY && ++writes)  		vty_out(vty, "vrrp default priority %" PRIu8 "\n", vd.priority); @@ -2386,10 +2387,13 @@ static bool vrrp_hash_cmp(const void *arg1, const void *arg2)  void vrrp_init(void)  {  	/* Set default defaults */ -	vd.priority = VRRP_DEFAULT_PRIORITY; -	vd.advertisement_interval = VRRP_DEFAULT_ADVINT; -	vd.preempt_mode = VRRP_DEFAULT_PREEMPT; -	vd.accept_mode = VRRP_DEFAULT_ACCEPT; +	vd.version = yang_get_default_uint8("%s/version", VRRP_XPATH_FULL); +	vd.priority = yang_get_default_uint8("%s/priority", VRRP_XPATH_FULL); +	vd.advertisement_interval = yang_get_default_uint16( +		"%s/advertisement-interval", VRRP_XPATH_FULL); +	vd.preempt_mode = yang_get_default_bool("%s/preempt", VRRP_XPATH_FULL); +	vd.accept_mode = +		yang_get_default_bool("%s/accept-mode", VRRP_XPATH_FULL);  	vd.shutdown = VRRP_DEFAULT_SHUTDOWN;  	vrrp_autoconfig_version = 3; diff --git a/vrrpd/vrrp.h b/vrrpd/vrrp.h index b1994c23f7..7e3e493a26 100644 --- a/vrrpd/vrrp.h +++ b/vrrpd/vrrp.h @@ -28,6 +28,7 @@  #include "lib/hook.h"  #include "lib/if.h"  #include "lib/linklist.h" +#include "lib/northbound.h"  #include "lib/privs.h"  #include "lib/stream.h"  #include "lib/thread.h" @@ -46,6 +47,8 @@  #define VRRP_LOGPFX_FAM "[%s] "  /* Default defaults */ +#define VRRP_XPATH_FULL "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group" +#define VRRP_XPATH "./frr-vrrpd:vrrp/vrrp-group"  #define VRRP_DEFAULT_PRIORITY 100  #define VRRP_DEFAULT_ADVINT 100  #define VRRP_DEFAULT_PREEMPT true @@ -57,8 +60,12 @@  DECLARE_MGROUP(VRRPD) +/* Northbound */ +extern const struct frr_yang_module_info frr_vrrpd_info; +  /* Configured defaults */  struct vrrp_defaults { +	uint8_t version;  	uint8_t priority;  	uint16_t advertisement_interval;  	bool preempt_mode; diff --git a/vrrpd/vrrp_main.c b/vrrpd/vrrp_main.c index fface1718f..7bb3f05406 100644 --- a/vrrpd/vrrp_main.c +++ b/vrrpd/vrrp_main.c @@ -107,6 +107,7 @@ struct quagga_signal_t vrrp_signals[] = {  static const struct frr_yang_module_info *const vrrp_yang_modules[] = {  	&frr_interface_info, +	&frr_vrrpd_info,  };  #define VRRP_VTY_PORT 2619 diff --git a/vrrpd/vrrp_northbound.c b/vrrpd/vrrp_northbound.c new file mode 100644 index 0000000000..71fe6f1e43 --- /dev/null +++ b/vrrpd/vrrp_northbound.c @@ -0,0 +1,814 @@ +/* + * VRRP northbound bindings. + * Copyright (C) 2019  Cumulus Networks, Inc. + * Quentin Young + * + * 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 + */ + +#include <zebra.h> + +#include "if.h" +#include "log.h" +#include "prefix.h" +#include "table.h" +#include "command.h" +#include "northbound.h" +#include "libfrr.h" +#include "vrrp.h" +#include "vrrp_vty.h" + +/* + * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group + */ +static int lib_interface_vrrp_vrrp_group_create(enum nb_event event, +						const struct lyd_node *dnode, +						union nb_resource *resource) +{ +	struct interface *ifp; +	uint8_t vrid; +	uint8_t version = 3; +	struct vrrp_vrouter *vr; + +	if (event != NB_EV_APPLY) +		return NB_OK; + +	ifp = nb_running_get_entry(dnode, NULL, true); +	vrid = yang_dnode_get_uint8(dnode, "./virtual-router-id"); +	version = yang_dnode_get_enum(dnode, "./version"); +	vr = vrrp_vrouter_create(ifp, vrid, version); +	nb_running_set_entry(dnode, vr); + +	return NB_OK; +} + +static int lib_interface_vrrp_vrrp_group_destroy(enum nb_event event, +						 const struct lyd_node *dnode) +{ +	struct vrrp_vrouter *vr; + +	if (event != NB_EV_APPLY) +		return NB_OK; + +	vr = nb_running_unset_entry(dnode); +	vrrp_vrouter_destroy(vr); + +	return NB_OK; +} + +static const void * +lib_interface_vrrp_vrrp_group_get_next(const void *parent_list_entry, +				       const void *list_entry) +{ +	struct list *l = hash_to_list(vrrp_vrouters_hash); +	struct listnode *ln; +	const struct vrrp_vrouter *vr, *prev, *curr; +	const struct interface *ifp = parent_list_entry; + +	prev = curr = NULL; +	vr = list_entry; + +	/* +	 * If list_entry is null, we return the first vrrp instance with a +	 * matching interface +	 */ +	bool nextone = list_entry ? false : true; + +	for (ALL_LIST_ELEMENTS_RO(l, ln, curr)) { +		if (curr == list_entry) { +			nextone = true; +			continue; +		} + +		if (nextone && curr->ifp == ifp) +			goto done; + +		prev = curr; +	} + +	curr = NULL; + +done: +	list_delete(&l); +	return curr; +} + +static int lib_interface_vrrp_vrrp_group_get_keys(const void *list_entry, +						  struct yang_list_keys *keys) +{ +	const struct vrrp_vrouter *vr = list_entry; + +	keys->num = 1; +	snprintf(keys->key[0], sizeof(keys->key[0]), "%" PRIu32, vr->vrid); + +	return NB_OK; +} + +static const void * +lib_interface_vrrp_vrrp_group_lookup_entry(const void *parent_list_entry, +					   const struct yang_list_keys *keys) +{ +	uint32_t vrid = strtoul(keys->key[0], NULL, 10); +	const struct interface *ifp = parent_list_entry; + +	vrrp_lookup(ifp, vrid); + +	return NULL; +} + +/* + * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/version + */ +static int +lib_interface_vrrp_vrrp_group_version_modify(enum nb_event event, +					     const struct lyd_node *dnode, +					     union nb_resource *resource) +{ +	if (event != NB_EV_APPLY) +		return NB_OK; + +	struct vrrp_vrouter *vr; +	uint8_t version; + +	vr = nb_running_get_entry(dnode, NULL, true); +	vrrp_event(vr->v4, VRRP_EVENT_SHUTDOWN); +	vrrp_event(vr->v6, VRRP_EVENT_SHUTDOWN); +	version = yang_dnode_get_enum(dnode, NULL); +	vr->version = version; + +	vrrp_check_start(vr); + +	return NB_OK; +} + +static void vrrp_yang_add_del_virtual_address(const struct lyd_node *dnode, +					      bool add) +{ +	struct vrrp_vrouter *vr; +	struct ipaddr ip; + +	vr = nb_running_get_entry(dnode, NULL, true); +	yang_dnode_get_ip(&ip, dnode, NULL); +	if (add) +		vrrp_add_ip(vr, &ip); +	else +		vrrp_del_ip(vr, &ip); + +	vrrp_check_start(vr); +} + + +//----------- + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/virtual-address + */ +static int lib_interface_vrrp_vrrp_group_v4_virtual_address_create( +	enum nb_event event, const struct lyd_node *dnode, +	union nb_resource *resource) +{ +	if (event != NB_EV_APPLY) +		return NB_OK; + +	vrrp_yang_add_del_virtual_address(dnode, true); + +	return NB_OK; +} + +static int lib_interface_vrrp_vrrp_group_v4_virtual_address_destroy( +	enum nb_event event, const struct lyd_node *dnode) +{ +	if (event != NB_EV_APPLY) +		return NB_OK; + +	vrrp_yang_add_del_virtual_address(dnode, false); + +	return NB_OK; +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/current-priority + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v4_current_priority_get_elem( +	const char *xpath, const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; + +	return yang_data_new_uint8(xpath, vr->v4->priority); +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/vrrp-interface + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v4_vrrp_interface_get_elem(const char *xpath, +							 const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; + +	struct yang_data *val = NULL; + +	if (vr->v4->mvl_ifp) +		val = yang_data_new_string(xpath, vr->v4->mvl_ifp->name); + +	return val; +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/source-address + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v4_source_address_get_elem(const char *xpath, +							 const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; +	struct yang_data *val = NULL; +	struct ipaddr ip; + +	memset(&ip, 0x00, sizeof(ip)); + +	if (memcmp(&vr->v4->src.ipaddr_v4, &ip.ipaddr_v4, sizeof(ip.ipaddr_v4))) +		val = yang_data_new_ip(xpath, &vr->v4->src); + +	return val; +} + +/* + * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/state + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v4_state_get_elem(const char *xpath, +						const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; + +	return yang_data_new_enum(xpath, vr->v4->fsm.state); +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/master-advertisement-interval + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v4_master_advertisement_interval_get_elem( +	const char *xpath, const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; + +	return yang_data_new_uint16(xpath, vr->v4->master_adver_interval); +} + +/* + * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/skew-time + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v4_skew_time_get_elem(const char *xpath, +						    const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; + +	return yang_data_new_uint16(xpath, vr->v4->skew_time); +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/counter/state-transition + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v4_counter_state_transition_get_elem( +	const char *xpath, const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; + +	return yang_data_new_uint32(xpath, vr->v4->stats.trans_cnt); +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/counter/tx/advertisement + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v4_counter_tx_advertisement_get_elem( +	const char *xpath, const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; + +	return yang_data_new_uint32(xpath, vr->v4->stats.adver_tx_cnt); +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/counter/tx/gratuitous-arp + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v4_counter_tx_gratuitous_arp_get_elem( +	const char *xpath, const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; + +	return yang_data_new_uint32(xpath, vr->v4->stats.garp_tx_cnt); +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/counter/rx/advertisement + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v4_counter_rx_advertisement_get_elem( +	const char *xpath, const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; + +	return yang_data_new_uint32(xpath, vr->v4->stats.adver_rx_cnt); +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/virtual-address + */ +static int lib_interface_vrrp_vrrp_group_v6_virtual_address_create( +	enum nb_event event, const struct lyd_node *dnode, +	union nb_resource *resource) +{ +	if (event != NB_EV_APPLY) +		return NB_OK; + +	vrrp_yang_add_del_virtual_address(dnode, true); + +	return NB_OK; +} + +static int lib_interface_vrrp_vrrp_group_v6_virtual_address_destroy( +	enum nb_event event, const struct lyd_node *dnode) +{ +	if (event != NB_EV_APPLY) +		return NB_OK; + +	vrrp_yang_add_del_virtual_address(dnode, false); + +	return NB_OK; +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/current-priority + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v6_current_priority_get_elem( +	const char *xpath, const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; + +	return yang_data_new_uint8(xpath, vr->v6->priority); +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/vrrp-interface + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v6_vrrp_interface_get_elem(const char *xpath, +							 const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; +	struct yang_data *val = NULL; + +	if (vr->v6->mvl_ifp) +		val = yang_data_new_string(xpath, vr->v6->mvl_ifp->name); + +	return val; +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/source-address + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v6_source_address_get_elem(const char *xpath, +							 const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; +	struct yang_data *val = NULL; +	struct ipaddr ip; + +	memset(&ip, 0x00, sizeof(ip)); + +	if (memcmp(&vr->v6->src.ipaddr_v6, &ip.ipaddr_v6, sizeof(ip.ipaddr_v6))) +		val = yang_data_new_ip(xpath, &vr->v6->src); + +	return val; +} + +/* + * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/state + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v6_state_get_elem(const char *xpath, +						const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; + +	return yang_data_new_enum(xpath, vr->v6->fsm.state); +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/master-advertisement-interval + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v6_master_advertisement_interval_get_elem( +	const char *xpath, const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; + +	return yang_data_new_uint16(xpath, vr->v6->master_adver_interval); +} + +/* + * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/skew-time + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v6_skew_time_get_elem(const char *xpath, +						    const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; + +	return yang_data_new_uint16(xpath, vr->v6->skew_time); +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/counter/state-transition + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v6_counter_state_transition_get_elem( +	const char *xpath, const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; + +	return yang_data_new_uint32(xpath, vr->v6->stats.trans_cnt); +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/counter/tx/advertisement + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v6_counter_tx_advertisement_get_elem( +	const char *xpath, const void *list_entry) +{ +	const struct vrrp_vrouter *vr = list_entry; + +	return yang_data_new_uint32(xpath, vr->v6->stats.adver_tx_cnt); +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/counter/tx/neighbor-advertisement + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v6_counter_tx_neighbor_advertisement_get_elem( +	const char *xpath, const void *list_entry) +{ +	/* TODO: implement me. */ +	return NULL; +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/counter/rx/advertisement + */ +static struct yang_data * +lib_interface_vrrp_vrrp_group_v6_counter_rx_advertisement_get_elem( +	const char *xpath, const void *list_entry) +{ +	/* TODO: implement me. */ +	return NULL; +} + +/* + * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/priority + */ +static int +lib_interface_vrrp_vrrp_group_priority_modify(enum nb_event event, +					      const struct lyd_node *dnode, +					      union nb_resource *resource) +{ +	if (event != NB_EV_APPLY) +		return NB_OK; + +	struct vrrp_vrouter *vr; +	uint8_t priority; + +	vr = nb_running_get_entry(dnode, NULL, true); +	priority = yang_dnode_get_uint8(dnode, NULL); +	vrrp_set_priority(vr, priority); + +	return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/preempt + */ +static int +lib_interface_vrrp_vrrp_group_preempt_modify(enum nb_event event, +					     const struct lyd_node *dnode, +					     union nb_resource *resource) +{ +	if (event != NB_EV_APPLY) +		return NB_OK; + +	struct vrrp_vrouter *vr; +	bool preempt; + +	vr = nb_running_get_entry(dnode, NULL, true); +	preempt = yang_dnode_get_bool(dnode, NULL); +	vr->preempt_mode = preempt; + +	return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/accept-mode + */ +static int +lib_interface_vrrp_vrrp_group_accept_mode_modify(enum nb_event event, +						 const struct lyd_node *dnode, +						 union nb_resource *resource) +{ +	if (event != NB_EV_APPLY) +		return NB_OK; + +	struct vrrp_vrouter *vr; +	bool accept; + +	vr = nb_running_get_entry(dnode, NULL, true); +	accept = yang_dnode_get_bool(dnode, NULL); +	vr->accept_mode = accept; + +	return NB_OK; +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/advertisement-interval + */ +static int lib_interface_vrrp_vrrp_group_advertisement_interval_modify( +	enum nb_event event, const struct lyd_node *dnode, +	union nb_resource *resource) +{ +	if (event != NB_EV_APPLY) +		return NB_OK; + +	struct vrrp_vrouter *vr; +	uint16_t advert_int; + +	vr = nb_running_get_entry(dnode, NULL, true); +	advert_int = yang_dnode_get_uint16(dnode, NULL); +	vrrp_set_advertisement_interval(vr, advert_int); + +	return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/shutdown + */ +static int +lib_interface_vrrp_vrrp_group_shutdown_modify(enum nb_event event, +					      const struct lyd_node *dnode, +					      union nb_resource *resource) +{ +	if (event != NB_EV_APPLY) +		return NB_OK; + +	struct vrrp_vrouter *vr; +	bool shutdown; + +	vr = nb_running_get_entry(dnode, NULL, true); +	shutdown = yang_dnode_get_bool(dnode, NULL); + +	vr->shutdown = shutdown; + +	if (shutdown) { +		vrrp_event(vr->v4, VRRP_EVENT_SHUTDOWN); +		vrrp_event(vr->v6, VRRP_EVENT_SHUTDOWN); +	} else { +		vrrp_check_start(vr); +	} + +	return NB_OK; +} + +/* clang-format off */ +const struct frr_yang_module_info frr_vrrpd_info = { +	.name = "frr-vrrpd", +	.nodes = { +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group", +			.cbs = { +				.create = lib_interface_vrrp_vrrp_group_create, +				.destroy = lib_interface_vrrp_vrrp_group_destroy, +				.get_next = lib_interface_vrrp_vrrp_group_get_next, +				.get_keys = lib_interface_vrrp_vrrp_group_get_keys, +				.lookup_entry = lib_interface_vrrp_vrrp_group_lookup_entry, +				.cli_show = cli_show_vrrp, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/version", +			.cbs = { +				.modify = lib_interface_vrrp_vrrp_group_version_modify, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/priority", +			.cbs = { +				.modify = lib_interface_vrrp_vrrp_group_priority_modify, +				.cli_show = cli_show_priority, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/preempt", +			.cbs = { +				.modify = lib_interface_vrrp_vrrp_group_preempt_modify, +				.cli_show = cli_show_preempt, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/accept-mode", +			.cbs = { +				.modify = lib_interface_vrrp_vrrp_group_accept_mode_modify, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/advertisement-interval", +			.cbs = { +				.modify = lib_interface_vrrp_vrrp_group_advertisement_interval_modify, +				.cli_show = cli_show_advertisement_interval, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/shutdown", +			.cbs = { +				.modify = lib_interface_vrrp_vrrp_group_shutdown_modify, +				.cli_show = cli_show_shutdown, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/virtual-address", +			.cbs = { +				.create = lib_interface_vrrp_vrrp_group_v4_virtual_address_create, +				.destroy = lib_interface_vrrp_vrrp_group_v4_virtual_address_destroy, +				.cli_show = cli_show_ip, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/current-priority", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v4_current_priority_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/vrrp-interface", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v4_vrrp_interface_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/source-address", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v4_source_address_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/state", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v4_state_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/master-advertisement-interval", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v4_master_advertisement_interval_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/skew-time", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v4_skew_time_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/counter/state-transition", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v4_counter_state_transition_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/counter/tx/advertisement", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v4_counter_tx_advertisement_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/counter/tx/gratuitous-arp", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v4_counter_tx_gratuitous_arp_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/counter/rx/advertisement", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v4_counter_rx_advertisement_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/virtual-address", +			.cbs = { +				.create = lib_interface_vrrp_vrrp_group_v6_virtual_address_create, +				.destroy = lib_interface_vrrp_vrrp_group_v6_virtual_address_destroy, +				.cli_show = cli_show_ipv6, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/current-priority", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v6_current_priority_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/vrrp-interface", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v6_vrrp_interface_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/source-address", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v6_source_address_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/state", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v6_state_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/master-advertisement-interval", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v6_master_advertisement_interval_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/skew-time", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v6_skew_time_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/counter/state-transition", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v6_counter_state_transition_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/counter/tx/advertisement", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v6_counter_tx_advertisement_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/counter/tx/neighbor-advertisement", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v6_counter_tx_neighbor_advertisement_get_elem, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/counter/rx/advertisement", +			.cbs = { +				.get_elem = lib_interface_vrrp_vrrp_group_v6_counter_rx_advertisement_get_elem, +			} +		}, +		{ +			.xpath = NULL, +		}, +	} +}; diff --git a/vrrpd/vrrp_vty.c b/vrrpd/vrrp_vty.c index 239b02ee7f..4ccccc43a5 100644 --- a/vrrpd/vrrp_vty.c +++ b/vrrpd/vrrp_vty.c @@ -23,6 +23,7 @@  #include "lib/if.h"  #include "lib/ipaddr.h"  #include "lib/json.h" +#include "lib/northbound_cli.h"  #include "lib/prefix.h"  #include "lib/termtable.h"  #include "lib/vty.h" @@ -54,8 +55,13 @@  		}                                                              \  	} while (0) +#define VRRP_XPATH_ENTRY VRRP_XPATH "[virtual-router-id='%ld']" +  /* clang-format off */ +/* + * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group + */  DEFPY(vrrp_vrid,        vrrp_vrid_cmd,        "[no] vrrp (1-255)$vrid [version (2-3)]", @@ -65,27 +71,42 @@ DEFPY(vrrp_vrid,        VRRP_VERSION_STR        VRRP_VERSION_STR)  { -	VTY_DECLVAR_CONTEXT(interface, ifp); +	char valbuf[8]; -	struct vrrp_vrouter *vr = vrrp_lookup(ifp, vrid); +	snprintf(valbuf, sizeof(valbuf), "%ld", version ? version : vd.version); -	if (version == 0) -		version = 3; +	if (no) +		nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); +	else { +		nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); +		nb_cli_enqueue_change(vty, "./version", NB_OP_MODIFY, valbuf); +	} -	if (no && vr) -		vrrp_vrouter_destroy(vr); -	else if (no && !vr) -		vty_out(vty, "%% VRRP instance %ld does not exist on %s\n", -			vrid, ifp->name); -	else if (!vr) -		vrrp_vrouter_create(ifp, vrid, version); -	else if (vr) -		vty_out(vty, "%% VRRP instance %ld already exists on %s\n", -			vrid, ifp->name); +	return nb_cli_apply_changes(vty, VRRP_XPATH_ENTRY, vrid); +} -	return CMD_SUCCESS; +void cli_show_vrrp(struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ +	const char *vrid = yang_dnode_get_string(dnode, "./virtual-router-id"); +	const char *ver = yang_dnode_get_string(dnode, "./version"); +	const char *dver = +		yang_get_default_string("%s/version", VRRP_XPATH_FULL); + +	char verstr[16] = {}; + +	if (strmatch(dver, ver)) { +		if (show_defaults) +			snprintf(verstr, sizeof(verstr), "version %s", dver); +	} else { +		snprintf(verstr, sizeof(verstr), "version %s", ver); +	} + +	vty_out(vty, " vrrp %s %s\n", vrid, verstr);  } +/* + * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/shutdown + */  DEFPY(vrrp_shutdown,        vrrp_shutdown_cmd,        "[no] vrrp (1-255)$vrid shutdown", @@ -94,26 +115,24 @@ DEFPY(vrrp_shutdown,        VRRP_VRID_STR        "Force VRRP router into administrative shutdown\n")  { -	VTY_DECLVAR_CONTEXT(interface, ifp); - -	struct vrrp_vrouter *vr; +	nb_cli_enqueue_change(vty, "./shutdown", NB_OP_MODIFY, +			      no ? "false" : "true"); -	VROUTER_GET_VTY(vty, ifp, vrid, vr); +	return nb_cli_apply_changes(vty, VRRP_XPATH_ENTRY, vrid); +} -	if (!no) { -		if (vr->v4->fsm.state != VRRP_STATE_INITIALIZE) -			vrrp_event(vr->v4, VRRP_EVENT_SHUTDOWN); -		if (vr->v6->fsm.state != VRRP_STATE_INITIALIZE) -			vrrp_event(vr->v6, VRRP_EVENT_SHUTDOWN); -		vr->shutdown = true; -	} else { -		vr->shutdown = false; -		vrrp_check_start(vr); -	} +void cli_show_shutdown(struct vty *vty, struct lyd_node *dnode, +		       bool show_defaults) +{ +	const char *vrid = yang_dnode_get_string(dnode, "../virtual-router-id"); +	const bool shut = yang_dnode_get_bool(dnode, NULL); -	return CMD_SUCCESS; +	vty_out(vty, " %svrrp %s shutdown\n", shut ? "" : "no ", vrid);  } +/* + * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/priority + */  DEFPY(vrrp_priority,        vrrp_priority_cmd,        "[no] vrrp (1-255)$vrid priority (1-254)", @@ -123,45 +142,60 @@ DEFPY(vrrp_priority,        VRRP_PRIORITY_STR        "Priority value")  { -	VTY_DECLVAR_CONTEXT(interface, ifp); +	const char *val = no ? NULL : priority_str; -	struct vrrp_vrouter *vr; -	uint8_t newprio = no ? vd.priority : priority; +	nb_cli_enqueue_change(vty, "./priority", NB_OP_MODIFY, val); -	VROUTER_GET_VTY(vty, ifp, vrid, vr); +	return nb_cli_apply_changes(vty, VRRP_XPATH_ENTRY, vrid); +} -	vrrp_set_priority(vr, newprio); +void cli_show_priority(struct vty *vty, struct lyd_node *dnode, +		       bool show_defaults) +{ +	const char *vrid = yang_dnode_get_string(dnode, "../virtual-router-id"); +	const char *prio = yang_dnode_get_string(dnode, NULL); -	return CMD_SUCCESS; +	vty_out(vty, " vrrp %s priority %s\n", vrid, prio);  } +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/advertisement-interval + */  DEFPY(vrrp_advertisement_interval,        vrrp_advertisement_interval_cmd,        "[no] vrrp (1-255)$vrid advertisement-interval (10-40950)",        NO_STR VRRP_STR VRRP_VRID_STR VRRP_ADVINT_STR        "Advertisement interval in milliseconds; must be multiple of 10")  { -	VTY_DECLVAR_CONTEXT(interface, ifp); +	char valbuf[8]; +	const char *val; -	struct vrrp_vrouter *vr; -	uint16_t newadvint = -		no ? vd.advertisement_interval * CS2MS : advertisement_interval; +	/* all internal computations are in centiseconds */ +	advertisement_interval /= CS2MS; +	snprintf(valbuf, sizeof(valbuf), "%ld", advertisement_interval); -	if (newadvint % CS2MS != 0) { -		vty_out(vty, "%% Value must be a multiple of %u\n", -			(unsigned int)CS2MS); -		return CMD_WARNING_CONFIG_FAILED; -	} +	val = no ? NULL : valbuf; -	/* all internal computations are in centiseconds */ -	newadvint /= CS2MS; +	nb_cli_enqueue_change(vty, "./advertisement-interval", NB_OP_MODIFY, +			      val); -	VROUTER_GET_VTY(vty, ifp, vrid, vr); -	vrrp_set_advertisement_interval(vr, newadvint); +	return nb_cli_apply_changes(vty, VRRP_XPATH_ENTRY, vrid); +} -	return CMD_SUCCESS; +void cli_show_advertisement_interval(struct vty *vty, struct lyd_node *dnode, +				     bool show_defaults) +{ +	const char *vrid = yang_dnode_get_string(dnode, "../virtual-router-id"); +	const char *advi = yang_dnode_get_string(dnode, NULL); + +	vty_out(vty, " vrrp %s advertisement-interval %s\n", vrid, advi);  } +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/virtual-address + */  DEFPY(vrrp_ip,        vrrp_ip_cmd,        "[no] vrrp (1-255)$vrid ip A.B.C.D", @@ -171,51 +205,25 @@ DEFPY(vrrp_ip,        "Add IPv4 address\n"        VRRP_IP_STR)  { -	VTY_DECLVAR_CONTEXT(interface, ifp); +	int op = no ? NB_OP_DESTROY : NB_OP_CREATE; +	nb_cli_enqueue_change(vty, "./v4/virtual-address", op, ip_str); -	struct vrrp_vrouter *vr; -	bool deactivated = false; -	bool activated = false; -	bool failed = false; -	int ret = CMD_SUCCESS; -	int oldstate; - -	VROUTER_GET_VTY(vty, ifp, vrid, vr); - -	bool will_activate = (vr->v4->fsm.state == VRRP_STATE_INITIALIZE); - -	if (no) { -		oldstate = vr->v4->fsm.state; -		failed = vrrp_del_ipv4(vr, ip); -		vrrp_check_start(vr); -		deactivated = (vr->v4->fsm.state == VRRP_STATE_INITIALIZE -			       && oldstate != VRRP_STATE_INITIALIZE); -	} else { -		oldstate = vr->v4->fsm.state; -		failed = vrrp_add_ipv4(vr, ip); -		vrrp_check_start(vr); -		activated = (vr->v4->fsm.state != VRRP_STATE_INITIALIZE -			     && oldstate == VRRP_STATE_INITIALIZE); -	} +	return nb_cli_apply_changes(vty, VRRP_XPATH_ENTRY, vrid); +} -	if (activated) -		vty_out(vty, "%% Activated IPv4 Virtual Router %ld\n", vrid); -	if (deactivated) -		vty_out(vty, "%% Deactivated IPv4 Virtual Router %ld\n", vrid); -	if (failed) { -		vty_out(vty, "%% Failed to %s virtual IP\n", -			no ? "remove" : "add"); -		ret = CMD_WARNING_CONFIG_FAILED; -		if (will_activate && !activated) { -			vty_out(vty, -				"%% Failed to activate IPv4 Virtual Router %ld\n", -				vrid); -		} -	} +void cli_show_ip(struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ +	const char *vrid = +		yang_dnode_get_string(dnode, "../../virtual-router-id"); +	const char *ipv4 = yang_dnode_get_string(dnode, NULL); -	return ret; +	vty_out(vty, " vrrp %s ip %s\n", vrid, ipv4);  } +/* + * XPath: + * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/virtual-address + */  DEFPY(vrrp_ip6,        vrrp_ip6_cmd,        "[no] vrrp (1-255)$vrid ipv6 X:X::X:X", @@ -225,57 +233,24 @@ DEFPY(vrrp_ip6,        "Add IPv6 address\n"        VRRP_IP_STR)  { -	VTY_DECLVAR_CONTEXT(interface, ifp); - -	struct vrrp_vrouter *vr; -	bool deactivated = false; -	bool activated = false; -	bool failed = false; -	int ret = CMD_SUCCESS; -	int oldstate; - -	VROUTER_GET_VTY(vty, ifp, vrid, vr); - -	if (vr->version != 3) { -		vty_out(vty, -			"%% Cannot add IPv6 address to VRRPv2 virtual router\n"); -		return CMD_WARNING_CONFIG_FAILED; -	} +	int op = no ? NB_OP_DESTROY : NB_OP_CREATE; +	nb_cli_enqueue_change(vty, "./v6/virtual-address", op, ipv6_str); -	bool will_activate = (vr->v6->fsm.state == VRRP_STATE_INITIALIZE); - -	if (no) { -		oldstate = vr->v6->fsm.state; -		failed = vrrp_del_ipv6(vr, ipv6); -		vrrp_check_start(vr); -		deactivated = (vr->v6->fsm.state == VRRP_STATE_INITIALIZE -			       && oldstate != VRRP_STATE_INITIALIZE); -	} else { -		oldstate = vr->v6->fsm.state; -		failed = vrrp_add_ipv6(vr, ipv6); -		vrrp_check_start(vr); -		activated = (vr->v6->fsm.state != VRRP_STATE_INITIALIZE -			     && oldstate == VRRP_STATE_INITIALIZE); -	} +	return nb_cli_apply_changes(vty, VRRP_XPATH_ENTRY, vrid); +} -	if (activated) -		vty_out(vty, "%% Activated IPv6 Virtual Router %ld\n", vrid); -	if (deactivated) -		vty_out(vty, "%% Deactivated IPv6 Virtual Router %ld\n", vrid); -	if (failed) { -		vty_out(vty, "%% Failed to %s virtual IP\n", -			no ? "remove" : "add"); -		ret = CMD_WARNING_CONFIG_FAILED; -		if (will_activate && !activated) { -			vty_out(vty, -				"%% Failed to activate IPv6 Virtual Router %ld\n", -				vrid); -		} -	} +void cli_show_ipv6(struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ +	const char *vrid = +		yang_dnode_get_string(dnode, "../../virtual-router-id"); +	const char *ipv6 = yang_dnode_get_string(dnode, NULL); -	return ret; +	vty_out(vty, " vrrp %s ipv6 %s\n", vrid, ipv6);  } +/* + * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/preempt + */  DEFPY(vrrp_preempt,        vrrp_preempt_cmd,        "[no] vrrp (1-255)$vrid preempt", @@ -284,17 +259,22 @@ DEFPY(vrrp_preempt,        VRRP_VRID_STR        "Preempt mode\n")  { -	VTY_DECLVAR_CONTEXT(interface, ifp); - -	struct vrrp_vrouter *vr; +	nb_cli_enqueue_change(vty, "./preempt", NB_OP_MODIFY, +			      no ? "false" : "true"); -	VROUTER_GET_VTY(vty, ifp, vrid, vr); +	return nb_cli_apply_changes(vty, VRRP_XPATH_ENTRY, vrid); +} -	vr->preempt_mode = !no; +void cli_show_preempt(struct vty *vty, struct lyd_node *dnode, +		      bool show_defaults) +{ +	const char *vrid = yang_dnode_get_string(dnode, "../virtual-router-id"); +	const bool pre = yang_dnode_get_bool(dnode, NULL); -	return CMD_SUCCESS; +	vty_out(vty, " %svrrp %s preempt\n", pre ? "" : "no ", vrid);  } +/* XXX: yang conversion */  DEFPY(vrrp_autoconfigure,        vrrp_autoconfigure_cmd,        "[no] vrrp autoconfigure [version (2-3)]", @@ -314,6 +294,7 @@ DEFPY(vrrp_autoconfigure,  	return CMD_SUCCESS;  } +/* XXX: yang conversion */  DEFPY(vrrp_default,        vrrp_default_cmd,        "[no] vrrp default <advertisement-interval$adv (10-40950)$advint|preempt$p|priority$prio (1-254)$prioval|shutdown$s>", diff --git a/vrrpd/vrrp_vty.h b/vrrpd/vrrp_vty.h index 377321ec4a..6c6eef0327 100644 --- a/vrrpd/vrrp_vty.h +++ b/vrrpd/vrrp_vty.h @@ -20,6 +20,21 @@  #ifndef __VRRP_VTY_H__  #define __VRRP_VTY_H__ +#include "lib/northbound.h" +  void vrrp_vty_init(void); +/* Northbound callbacks */ +void cli_show_vrrp(struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_shutdown(struct vty *vty, struct lyd_node *dnode, +		       bool show_defaults); +void cli_show_priority(struct vty *vty, struct lyd_node *dnode, +		       bool show_defaults); +void cli_show_advertisement_interval(struct vty *vty, struct lyd_node *dnode, +				     bool show_defaults); +void cli_show_ip(struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_ipv6(struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_preempt(struct vty *vty, struct lyd_node *dnode, +		      bool show_defaults); +  #endif /* __VRRP_VTY_H__ */  | 
