summaryrefslogtreecommitdiffstats
path: root/vrrpd/vrrp_northbound.c
diff options
context:
space:
mode:
Diffstat (limited to 'vrrpd/vrrp_northbound.c')
-rw-r--r--vrrpd/vrrp_northbound.c800
1 files changed, 800 insertions, 0 deletions
diff --git a/vrrpd/vrrp_northbound.c b/vrrpd/vrrp_northbound.c
new file mode 100644
index 0000000..d25dc0a
--- /dev/null
+++ b/vrrpd/vrrp_northbound.c
@@ -0,0 +1,800 @@
+/*
+ * 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(struct nb_cb_create_args *args)
+{
+ struct interface *ifp;
+ uint8_t vrid;
+ uint8_t version = 3;
+ struct vrrp_vrouter *vr;
+
+ vrid = yang_dnode_get_uint8(args->dnode, "./virtual-router-id");
+ version = yang_dnode_get_enum(args->dnode, "./version");
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ ifp = nb_running_get_entry(args->dnode, NULL, false);
+ if (ifp) {
+ vr = vrrp_lookup(ifp, vrid);
+ if (vr && vr->autoconf) {
+ snprintf(
+ args->errmsg, args->errmsg_len,
+ "Virtual Router with ID %d already exists on interface '%s'; created by VRRP autoconfiguration",
+ vrid, ifp->name);
+ return NB_ERR_VALIDATION;
+ }
+ }
+ return NB_OK;
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ return NB_OK;
+ case NB_EV_APPLY:
+ break;
+ }
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ vr = vrrp_vrouter_create(ifp, vrid, version);
+ nb_running_set_entry(args->dnode, vr);
+
+ return NB_OK;
+}
+
+static int
+lib_interface_vrrp_vrrp_group_destroy(struct nb_cb_destroy_args *args)
+{
+ struct vrrp_vrouter *vr;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vr = nb_running_unset_entry(args->dnode);
+ vrrp_vrouter_destroy(vr);
+
+ return NB_OK;
+}
+
+static const void *
+lib_interface_vrrp_vrrp_group_get_next(struct nb_cb_get_next_args *args)
+{
+ struct list *l = hash_to_list(vrrp_vrouters_hash);
+ struct listnode *ln;
+ const struct vrrp_vrouter *curr;
+ const struct interface *ifp = args->parent_list_entry;
+
+ /*
+ * If list_entry is null, we return the first vrrp instance with a
+ * matching interface
+ */
+ bool nextone = args->list_entry ? false : true;
+
+ for (ALL_LIST_ELEMENTS_RO(l, ln, curr)) {
+ if (curr == args->list_entry) {
+ nextone = true;
+ continue;
+ }
+
+ if (nextone && curr->ifp == ifp)
+ goto done;
+ }
+
+ curr = NULL;
+
+done:
+ list_delete(&l);
+ return curr;
+}
+
+static int
+lib_interface_vrrp_vrrp_group_get_keys(struct nb_cb_get_keys_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+
+ args->keys->num = 1;
+ snprintf(args->keys->key[0], sizeof(args->keys->key[0]), "%u",
+ vr->vrid);
+
+ return NB_OK;
+}
+
+static const void *
+lib_interface_vrrp_vrrp_group_lookup_entry(struct nb_cb_lookup_entry_args *args)
+{
+ uint32_t vrid = strtoul(args->keys->key[0], NULL, 10);
+ const struct interface *ifp = args->parent_list_entry;
+
+ return vrrp_lookup(ifp, vrid);
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/version
+ */
+static int
+lib_interface_vrrp_vrrp_group_version_modify(struct nb_cb_modify_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ struct vrrp_vrouter *vr;
+ uint8_t version;
+
+ vr = nb_running_get_entry(args->dnode, NULL, true);
+ vrrp_event(vr->v4, VRRP_EVENT_SHUTDOWN);
+ vrrp_event(vr->v6, VRRP_EVENT_SHUTDOWN);
+ version = yang_dnode_get_enum(args->dnode, NULL);
+ vr->version = version;
+
+ vrrp_check_start(vr);
+
+ return NB_OK;
+}
+
+/*
+ * Helper function for address list OP_MODIFY callbacks.
+ */
+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(
+ struct nb_cb_create_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrrp_yang_add_del_virtual_address(args->dnode, true);
+
+ return NB_OK;
+}
+
+static int lib_interface_vrrp_vrrp_group_v4_virtual_address_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrrp_yang_add_del_virtual_address(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+
+ return yang_data_new_uint8(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+
+ struct yang_data *val = NULL;
+
+ if (vr->v4->mvl_ifp)
+ val = yang_data_new_string(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+ struct yang_data *val = NULL;
+
+ if (!ipaddr_is_zero(&vr->v4->src))
+ val = yang_data_new_ip(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+
+ return yang_data_new_enum(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+
+ return yang_data_new_uint16(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+
+ return yang_data_new_uint16(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+
+ return yang_data_new_uint32(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+
+ return yang_data_new_uint32(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+
+ return yang_data_new_uint32(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+
+ return yang_data_new_uint32(args->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(
+ struct nb_cb_create_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrrp_yang_add_del_virtual_address(args->dnode, true);
+
+ return NB_OK;
+}
+
+static int lib_interface_vrrp_vrrp_group_v6_virtual_address_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrrp_yang_add_del_virtual_address(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+
+ return yang_data_new_uint8(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+ struct yang_data *val = NULL;
+
+ if (vr->v6->mvl_ifp)
+ val = yang_data_new_string(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+ struct yang_data *val = NULL;
+
+ if (!ipaddr_is_zero(&vr->v6->src))
+ val = yang_data_new_ip(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+
+ return yang_data_new_enum(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+
+ return yang_data_new_uint16(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+
+ return yang_data_new_uint16(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+
+ return yang_data_new_uint32(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ const struct vrrp_vrouter *vr = args->list_entry;
+
+ return yang_data_new_uint32(args->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(
+ struct nb_cb_get_elem_args *args)
+{
+ /* 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(
+ struct nb_cb_get_elem_args *args)
+{
+ /* 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(struct nb_cb_modify_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ struct vrrp_vrouter *vr;
+ uint8_t priority;
+
+ vr = nb_running_get_entry(args->dnode, NULL, true);
+ priority = yang_dnode_get_uint8(args->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(struct nb_cb_modify_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ struct vrrp_vrouter *vr;
+ bool preempt;
+
+ vr = nb_running_get_entry(args->dnode, NULL, true);
+ preempt = yang_dnode_get_bool(args->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(struct nb_cb_modify_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ struct vrrp_vrouter *vr;
+ bool accept;
+
+ vr = nb_running_get_entry(args->dnode, NULL, true);
+ accept = yang_dnode_get_bool(args->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(
+ struct nb_cb_modify_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ struct vrrp_vrouter *vr;
+ uint16_t advert_int;
+
+ vr = nb_running_get_entry(args->dnode, NULL, true);
+ advert_int = yang_dnode_get_uint16(args->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(struct nb_cb_modify_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ struct vrrp_vrouter *vr;
+ bool shutdown;
+
+ vr = nb_running_get_entry(args->dnode, NULL, true);
+ shutdown = yang_dnode_get_bool(args->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,
+ },
+ }
+};