mirror of
				https://git.proxmox.com/git/mirror_frr
				synced 2025-11-03 23:47:16 +00:00 
			
		
		
		
	Implement all BFD integration northbound callbacks and integrate BFD with `staticd` route installation procedure. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
		
			
				
	
	
		
			1128 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1128 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (C) 2018        Vmware
 | 
						|
 *                           Vishal Dhingra
 | 
						|
 *
 | 
						|
 * 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 "northbound.h"
 | 
						|
#include "libfrr.h"
 | 
						|
#include "log.h"
 | 
						|
#include "lib_errors.h"
 | 
						|
#include "prefix.h"
 | 
						|
#include "table.h"
 | 
						|
#include "vrf.h"
 | 
						|
#include "nexthop.h"
 | 
						|
#include "srcdest_table.h"
 | 
						|
 | 
						|
#include "static_vrf.h"
 | 
						|
#include "static_routes.h"
 | 
						|
#include "static_nb.h"
 | 
						|
 | 
						|
 | 
						|
static int static_path_list_create(struct nb_cb_create_args *args)
 | 
						|
{
 | 
						|
	struct route_node *rn;
 | 
						|
	struct static_path *pn;
 | 
						|
	const struct lyd_node *vrf_dnode;
 | 
						|
	const char *vrf;
 | 
						|
	uint8_t distance;
 | 
						|
	uint32_t table_id;
 | 
						|
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
		vrf_dnode = yang_dnode_get_parent(args->dnode,
 | 
						|
						  "control-plane-protocol");
 | 
						|
		vrf = yang_dnode_get_string(vrf_dnode, "./vrf");
 | 
						|
		table_id = yang_dnode_get_uint32(args->dnode, "./table-id");
 | 
						|
 | 
						|
		/*
 | 
						|
		 * TableId is not applicable for VRF. Consider the case of
 | 
						|
		 * l3mdev, there is one uint32_t space to work with.
 | 
						|
		 * A l3mdev device points at a specific table that it
 | 
						|
		 * relates to and a set of interfaces it belongs to.
 | 
						|
		 */
 | 
						|
		if (table_id && (strcmp(vrf, vrf_get_default_name()) != 0)
 | 
						|
		    && !vrf_is_backend_netns()) {
 | 
						|
			snprintf(
 | 
						|
				args->errmsg, args->errmsg_len,
 | 
						|
				"%% table param only available when running on netns-based vrfs");
 | 
						|
			return NB_ERR_VALIDATION;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	case NB_EV_ABORT:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		rn = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
		distance = yang_dnode_get_uint8(args->dnode, "./distance");
 | 
						|
		table_id = yang_dnode_get_uint32(args->dnode, "./table-id");
 | 
						|
		pn = static_add_path(rn, table_id, distance);
 | 
						|
		nb_running_set_entry(args->dnode, pn);
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
static int static_path_list_destroy(struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	struct static_path *pn;
 | 
						|
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		pn = nb_running_unset_entry(args->dnode);
 | 
						|
		static_del_path(pn);
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
static int static_path_list_tag_modify(struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	struct static_path *pn;
 | 
						|
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		pn = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
		pn->tag = yang_dnode_get_uint32(args->dnode, NULL);
 | 
						|
		static_install_path(pn);
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
struct nexthop_iter {
 | 
						|
	uint32_t count;
 | 
						|
	bool blackhole;
 | 
						|
};
 | 
						|
 | 
						|
static int nexthop_iter_cb(const struct lyd_node *dnode, void *arg)
 | 
						|
{
 | 
						|
	struct nexthop_iter *iter = arg;
 | 
						|
	enum static_nh_type nh_type;
 | 
						|
 | 
						|
	nh_type = yang_dnode_get_enum(dnode, "./nh-type");
 | 
						|
 | 
						|
	if (nh_type == STATIC_BLACKHOLE)
 | 
						|
		iter->blackhole = true;
 | 
						|
 | 
						|
	iter->count++;
 | 
						|
 | 
						|
	return YANG_ITER_CONTINUE;
 | 
						|
}
 | 
						|
 | 
						|
static bool static_nexthop_create(struct nb_cb_create_args *args)
 | 
						|
{
 | 
						|
	const struct lyd_node *pn_dnode;
 | 
						|
	struct nexthop_iter iter;
 | 
						|
	struct static_path *pn;
 | 
						|
	struct ipaddr ipaddr;
 | 
						|
	struct static_nexthop *nh;
 | 
						|
	enum static_nh_type nh_type;
 | 
						|
	const char *ifname;
 | 
						|
	const char *nh_vrf;
 | 
						|
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
		ifname = yang_dnode_get_string(args->dnode, "./interface");
 | 
						|
		if (ifname != NULL) {
 | 
						|
			if (strcasecmp(ifname, "Null0") == 0
 | 
						|
			    || strcasecmp(ifname, "reject") == 0
 | 
						|
			    || strcasecmp(ifname, "blackhole") == 0) {
 | 
						|
				snprintf(args->errmsg, args->errmsg_len,
 | 
						|
					"%s: Nexthop interface name can not be from reserved keywords(Null0, reject, blackhole)",
 | 
						|
					ifname);
 | 
						|
				return NB_ERR_VALIDATION;
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		iter.count = 0;
 | 
						|
		iter.blackhole = false;
 | 
						|
 | 
						|
		pn_dnode = yang_dnode_get_parent(args->dnode, "path-list");
 | 
						|
		yang_dnode_iterate(nexthop_iter_cb, &iter, pn_dnode,
 | 
						|
				   "./frr-nexthops/nexthop");
 | 
						|
 | 
						|
		if (iter.blackhole && iter.count > 1) {
 | 
						|
			snprintf(
 | 
						|
				args->errmsg, args->errmsg_len,
 | 
						|
				"Route cannot have blackhole and non-blackhole nexthops simultaneously");
 | 
						|
			return NB_ERR_VALIDATION;
 | 
						|
		} else if (iter.count > zebra_ecmp_count) {
 | 
						|
			snprintf(args->errmsg, args->errmsg_len,
 | 
						|
				"Route cannot have more than %d ECMP nexthops",
 | 
						|
				 zebra_ecmp_count);
 | 
						|
			return NB_ERR_VALIDATION;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		yang_dnode_get_ip(&ipaddr, args->dnode, "./gateway");
 | 
						|
		nh_type = yang_dnode_get_enum(args->dnode, "./nh-type");
 | 
						|
		ifname = yang_dnode_get_string(args->dnode, "./interface");
 | 
						|
		nh_vrf = yang_dnode_get_string(args->dnode, "./vrf");
 | 
						|
		pn = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
 | 
						|
		if (!static_add_nexthop_validate(nh_vrf, nh_type, &ipaddr))
 | 
						|
			flog_warn(
 | 
						|
				EC_LIB_NB_CB_CONFIG_VALIDATE,
 | 
						|
				"Warning!! Local connected address is configured as Gateway IP((%s))",
 | 
						|
				yang_dnode_get_string(args->dnode,
 | 
						|
						      "./gateway"));
 | 
						|
		nh = static_add_nexthop(pn, nh_type, &ipaddr, ifname, nh_vrf,
 | 
						|
					0);
 | 
						|
		nb_running_set_entry(args->dnode, nh);
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
static bool static_nexthop_destroy(struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *nh;
 | 
						|
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		nh = nb_running_unset_entry(args->dnode);
 | 
						|
		static_delete_nexthop(nh);
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
static int nexthop_mpls_label_stack_entry_create(struct nb_cb_create_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *nh;
 | 
						|
	uint32_t pos;
 | 
						|
	uint8_t index;
 | 
						|
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
		if (!mpls_enabled) {
 | 
						|
			snprintf(
 | 
						|
				args->errmsg, args->errmsg_len,
 | 
						|
				"%% MPLS not turned on in kernel ignoring static route");
 | 
						|
			return NB_ERR_VALIDATION;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		nh = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
		pos = yang_get_list_pos(args->dnode);
 | 
						|
		if (!pos) {
 | 
						|
			flog_warn(EC_LIB_NB_CB_CONFIG_APPLY,
 | 
						|
				  "libyang returns invalid label position");
 | 
						|
			return NB_ERR;
 | 
						|
		}
 | 
						|
		/* Mapping to array = list-index -1 */
 | 
						|
		index = pos - 1;
 | 
						|
		nh->snh_label.label[index] = 0;
 | 
						|
		nh->snh_label.num_labels++;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
nexthop_mpls_label_stack_entry_destroy(struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *nh;
 | 
						|
	uint32_t pos;
 | 
						|
	uint8_t index;
 | 
						|
	uint old_num_labels;
 | 
						|
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		nh = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
		pos = yang_get_list_pos(args->dnode);
 | 
						|
		if (!pos) {
 | 
						|
			flog_warn(EC_LIB_NB_CB_CONFIG_APPLY,
 | 
						|
				  "libyang returns invalid label position");
 | 
						|
			return NB_ERR;
 | 
						|
		}
 | 
						|
		index = pos - 1;
 | 
						|
		old_num_labels = nh->snh_label.num_labels;
 | 
						|
		nh->snh_label.label[index] = 0;
 | 
						|
		nh->snh_label.num_labels--;
 | 
						|
 | 
						|
		if (old_num_labels != nh->snh_label.num_labels)
 | 
						|
			nh->state = STATIC_START;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
static int static_nexthop_mpls_label_modify(struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *nh;
 | 
						|
	uint32_t pos;
 | 
						|
	uint8_t index;
 | 
						|
	mpls_label_t old_label;
 | 
						|
 | 
						|
	nh = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
	pos = yang_get_list_pos(lyd_parent(args->dnode));
 | 
						|
	if (!pos) {
 | 
						|
		flog_warn(EC_LIB_NB_CB_CONFIG_APPLY,
 | 
						|
			  "libyang returns invalid label position");
 | 
						|
		return NB_ERR;
 | 
						|
	}
 | 
						|
	/* Mapping to array = list-index -1 */
 | 
						|
	index = pos - 1;
 | 
						|
 | 
						|
	old_label = nh->snh_label.label[index];
 | 
						|
	nh->snh_label.label[index] = yang_dnode_get_uint32(args->dnode, NULL);
 | 
						|
 | 
						|
	if (old_label != nh->snh_label.label[index])
 | 
						|
		nh->state = STATIC_START;
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
static int static_nexthop_onlink_modify(struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *nh;
 | 
						|
	enum static_nh_type nh_type;
 | 
						|
	bool old_onlink;
 | 
						|
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
		nh_type = yang_dnode_get_enum(args->dnode, "../nh-type");
 | 
						|
		if ((nh_type != STATIC_IPV4_GATEWAY_IFNAME)
 | 
						|
		    && (nh_type != STATIC_IPV6_GATEWAY_IFNAME)) {
 | 
						|
			snprintf(
 | 
						|
				args->errmsg, args->errmsg_len,
 | 
						|
				"nexthop type is not the ipv4 or ipv6 interface type");
 | 
						|
			return NB_ERR_VALIDATION;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		nh = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
		old_onlink = nh->onlink;
 | 
						|
		nh->onlink = yang_dnode_get_bool(args->dnode, NULL);
 | 
						|
 | 
						|
		if (old_onlink != nh->onlink)
 | 
						|
			nh->state = STATIC_START;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
static int static_nexthop_color_modify(struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *nh;
 | 
						|
	uint32_t old_color;
 | 
						|
 | 
						|
	nh = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
	old_color = nh->color;
 | 
						|
	nh->color = yang_dnode_get_uint32(args->dnode, NULL);
 | 
						|
 | 
						|
	if (old_color != nh->color)
 | 
						|
		nh->state = STATIC_START;
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
static int static_nexthop_color_destroy(struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *nh;
 | 
						|
	uint32_t old_color;
 | 
						|
 | 
						|
	nh = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
	old_color = nh->color;
 | 
						|
	nh->color = 0;
 | 
						|
 | 
						|
	if (old_color != nh->color)
 | 
						|
		nh->state = STATIC_START;
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
static int static_nexthop_bh_type_modify(struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *nh;
 | 
						|
	enum static_nh_type nh_type;
 | 
						|
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
		nh_type = yang_dnode_get_enum(args->dnode, "../nh-type");
 | 
						|
		if (nh_type != STATIC_BLACKHOLE) {
 | 
						|
			snprintf(args->errmsg, args->errmsg_len,
 | 
						|
				 "nexthop type is not the blackhole type");
 | 
						|
			return NB_ERR_VALIDATION;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		nh = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
		nh->bh_type = yang_dnode_get_enum(args->dnode, NULL);
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
void routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_apply_finish(
 | 
						|
	struct nb_cb_apply_finish_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *nh;
 | 
						|
 | 
						|
	nh = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
 | 
						|
	static_install_nexthop(nh);
 | 
						|
}
 | 
						|
 | 
						|
void routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_apply_finish(
 | 
						|
	struct nb_cb_apply_finish_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *nh;
 | 
						|
 | 
						|
	nh = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
 | 
						|
	static_install_nexthop(nh);
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_pre_validate(
 | 
						|
	struct nb_cb_pre_validate_args *args)
 | 
						|
{
 | 
						|
	const struct lyd_node *mls_dnode;
 | 
						|
	uint32_t count;
 | 
						|
 | 
						|
	mls_dnode = yang_dnode_get(args->dnode, "./mpls-label-stack");
 | 
						|
	count = yang_get_list_elements_count(lyd_child(mls_dnode));
 | 
						|
 | 
						|
	if (count > MPLS_MAX_LABELS) {
 | 
						|
		snprintf(args->errmsg, args->errmsg_len,
 | 
						|
			"Too many labels, Enter %d or fewer",
 | 
						|
			MPLS_MAX_LABELS);
 | 
						|
		return NB_ERR_VALIDATION;
 | 
						|
	}
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_name_validate(
 | 
						|
	struct nb_cb_create_args *args)
 | 
						|
{
 | 
						|
	const char *name;
 | 
						|
 | 
						|
	name = yang_dnode_get_string(args->dnode, "./name");
 | 
						|
	if (!strmatch(name, "staticd")) {
 | 
						|
		snprintf(args->errmsg, args->errmsg_len,
 | 
						|
			"static routing supports only one instance with name staticd");
 | 
						|
		return NB_ERR_VALIDATION;
 | 
						|
	}
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_create(
 | 
						|
	struct nb_cb_create_args *args)
 | 
						|
{
 | 
						|
	struct vrf *vrf;
 | 
						|
	struct static_vrf *s_vrf;
 | 
						|
	struct route_node *rn;
 | 
						|
	const struct lyd_node *vrf_dnode;
 | 
						|
	struct prefix prefix;
 | 
						|
	const char *afi_safi;
 | 
						|
	afi_t prefix_afi;
 | 
						|
	afi_t afi;
 | 
						|
	safi_t safi;
 | 
						|
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
		yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
 | 
						|
		afi_safi = yang_dnode_get_string(args->dnode, "./afi-safi");
 | 
						|
		yang_afi_safi_identity2value(afi_safi, &afi, &safi);
 | 
						|
		prefix_afi = family2afi(prefix.family);
 | 
						|
		if (afi != prefix_afi) {
 | 
						|
			flog_warn(
 | 
						|
				EC_LIB_NB_CB_CONFIG_VALIDATE,
 | 
						|
				"route node %s creation failed",
 | 
						|
				yang_dnode_get_string(args->dnode, "./prefix"));
 | 
						|
			return NB_ERR_VALIDATION;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		vrf_dnode = yang_dnode_get_parent(args->dnode,
 | 
						|
						  "control-plane-protocol");
 | 
						|
		vrf = nb_running_get_entry(vrf_dnode, NULL, true);
 | 
						|
		s_vrf = vrf->info;
 | 
						|
 | 
						|
		yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
 | 
						|
		afi_safi = yang_dnode_get_string(args->dnode, "./afi-safi");
 | 
						|
		yang_afi_safi_identity2value(afi_safi, &afi, &safi);
 | 
						|
 | 
						|
		rn = static_add_route(afi, safi, &prefix, NULL, s_vrf);
 | 
						|
		if (vrf->vrf_id == VRF_UNKNOWN)
 | 
						|
			snprintf(
 | 
						|
				args->errmsg, args->errmsg_len,
 | 
						|
				"Static Route to %s not installed currently because dependent config not fully available",
 | 
						|
				yang_dnode_get_string(args->dnode, "./prefix"));
 | 
						|
		nb_running_set_entry(args->dnode, rn);
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_destroy(
 | 
						|
	struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	struct route_node *rn;
 | 
						|
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		rn = nb_running_unset_entry(args->dnode);
 | 
						|
		static_del_route(rn);
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_create(
 | 
						|
	struct nb_cb_create_args *args)
 | 
						|
{
 | 
						|
	return static_path_list_create(args);
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_destroy(
 | 
						|
	struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	return static_path_list_destroy(args);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/tag
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_tag_modify(
 | 
						|
	struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	return static_path_list_tag_modify(args);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_create(
 | 
						|
	struct nb_cb_create_args *args)
 | 
						|
{
 | 
						|
	return static_nexthop_create(args);
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_destroy(
 | 
						|
	struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	return static_nexthop_destroy(args);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/bh-type
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_modify(
 | 
						|
	struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	return static_nexthop_bh_type_modify(args);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/onlink
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_modify(
 | 
						|
	struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	return static_nexthop_onlink_modify(args);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/srte-color
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_color_modify(
 | 
						|
	struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		if (static_nexthop_color_modify(args) != NB_OK)
 | 
						|
			return NB_ERR;
 | 
						|
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_color_destroy(
 | 
						|
	struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		if (static_nexthop_color_destroy(args) != NB_OK)
 | 
						|
			return NB_ERR;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create(
 | 
						|
	struct nb_cb_create_args *args)
 | 
						|
{
 | 
						|
	return nexthop_mpls_label_stack_entry_create(args);
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_destroy(
 | 
						|
	struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	return nexthop_mpls_label_stack_entry_destroy(args);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/label
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_modify(
 | 
						|
	struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		if (static_nexthop_mpls_label_modify(args) != NB_OK)
 | 
						|
			return NB_ERR;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_destroy(
 | 
						|
	struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	/*
 | 
						|
	 * No operation is required in this call back.
 | 
						|
	 * nexthop_mpls_label_stack_entry_destroy() will take care
 | 
						|
	 * to reset the label vaue.
 | 
						|
	 */
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/ttl
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_modify(
 | 
						|
	struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_destroy(
 | 
						|
	struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/traffic-class
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_modify(
 | 
						|
	struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_destroy(
 | 
						|
	struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/bfd-monitoring
 | 
						|
 */
 | 
						|
int route_next_hop_bfd_create(struct nb_cb_create_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *sn;
 | 
						|
 | 
						|
	if (args->event != NB_EV_APPLY)
 | 
						|
		return NB_OK;
 | 
						|
 | 
						|
	sn = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
	static_next_hop_bfd_monitor_enable(sn, args->dnode);
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
int route_next_hop_bfd_destroy(struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *sn;
 | 
						|
 | 
						|
	if (args->event != NB_EV_APPLY)
 | 
						|
		return NB_OK;
 | 
						|
 | 
						|
	sn = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
	static_next_hop_bfd_monitor_disable(sn);
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/bfd-monitoring/source
 | 
						|
 */
 | 
						|
int route_next_hop_bfd_source_modify(struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *sn;
 | 
						|
	struct ipaddr source;
 | 
						|
 | 
						|
	if (args->event != NB_EV_APPLY)
 | 
						|
		return NB_OK;
 | 
						|
 | 
						|
	sn = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
	yang_dnode_get_ip(&source, args->dnode, NULL);
 | 
						|
	static_next_hop_bfd_source(sn, &source);
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
int route_next_hop_bfd_source_destroy(struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *sn;
 | 
						|
 | 
						|
	if (args->event != NB_EV_APPLY)
 | 
						|
		return NB_OK;
 | 
						|
 | 
						|
	sn = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
	static_next_hop_bfd_auto_source(sn);
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/bfd-monitoring/multi-hop
 | 
						|
 */
 | 
						|
int route_next_hop_bfd_multi_hop_modify(struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *sn;
 | 
						|
 | 
						|
	if (args->event != NB_EV_APPLY)
 | 
						|
		return NB_OK;
 | 
						|
 | 
						|
	sn = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
	static_next_hop_bfd_multi_hop(sn,
 | 
						|
				      yang_dnode_get_bool(args->dnode, NULL));
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/bfd-monitoring/profile
 | 
						|
 */
 | 
						|
int route_next_hop_bfd_profile_modify(struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *sn;
 | 
						|
 | 
						|
	if (args->event != NB_EV_APPLY)
 | 
						|
		return NB_OK;
 | 
						|
 | 
						|
	sn = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
	static_next_hop_bfd_profile(sn,
 | 
						|
				    yang_dnode_get_string(args->dnode, NULL));
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
int route_next_hop_bfd_profile_destroy(struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	struct static_nexthop *sn;
 | 
						|
 | 
						|
	if (args->event != NB_EV_APPLY)
 | 
						|
		return NB_OK;
 | 
						|
 | 
						|
	sn = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
	static_next_hop_bfd_profile(sn, NULL);
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_create(
 | 
						|
	struct nb_cb_create_args *args)
 | 
						|
{
 | 
						|
	struct static_vrf *s_vrf;
 | 
						|
	struct route_node *rn;
 | 
						|
	struct route_node *src_rn;
 | 
						|
	struct prefix_ipv6 src_prefix = {};
 | 
						|
	struct stable_info *info;
 | 
						|
	afi_t afi;
 | 
						|
	safi_t safi = SAFI_UNICAST;
 | 
						|
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		rn = nb_running_get_entry(args->dnode, NULL, true);
 | 
						|
		info = route_table_get_info(rn->table);
 | 
						|
		s_vrf = info->svrf;
 | 
						|
		yang_dnode_get_ipv6p(&src_prefix, args->dnode, "./src-prefix");
 | 
						|
		afi = family2afi(src_prefix.family);
 | 
						|
		src_rn =
 | 
						|
			static_add_route(afi, safi, &rn->p, &src_prefix, s_vrf);
 | 
						|
		nb_running_set_entry(args->dnode, src_rn);
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_destroy(
 | 
						|
	struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	struct route_node *src_rn;
 | 
						|
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		src_rn = nb_running_unset_entry(args->dnode);
 | 
						|
		static_del_route(src_rn);
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_create(
 | 
						|
	struct nb_cb_create_args *args)
 | 
						|
{
 | 
						|
	return static_path_list_create(args);
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_destroy(
 | 
						|
	struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	return static_path_list_destroy(args);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/tag
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_tag_modify(
 | 
						|
	struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	return static_path_list_tag_modify(args);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_create(
 | 
						|
	struct nb_cb_create_args *args)
 | 
						|
{
 | 
						|
	return static_nexthop_create(args);
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_destroy(
 | 
						|
	struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	return static_nexthop_destroy(args);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/bh-type
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_modify(
 | 
						|
	struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	return static_nexthop_bh_type_modify(args);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/onlink
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_modify(
 | 
						|
	struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	return static_nexthop_onlink_modify(args);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/srte-color
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_modify(
 | 
						|
	struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		if (static_nexthop_color_modify(args) != NB_OK)
 | 
						|
			return NB_ERR;
 | 
						|
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_destroy(
 | 
						|
	struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		if (static_nexthop_color_destroy(args) != NB_OK)
 | 
						|
			return NB_ERR;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create(
 | 
						|
	struct nb_cb_create_args *args)
 | 
						|
{
 | 
						|
	return nexthop_mpls_label_stack_entry_create(args);
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_destroy(
 | 
						|
	struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	return nexthop_mpls_label_stack_entry_destroy(args);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/label
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_modify(
 | 
						|
	struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
		break;
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		if (static_nexthop_mpls_label_modify(args) != NB_OK)
 | 
						|
			return NB_ERR;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_destroy(
 | 
						|
	struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	/*
 | 
						|
	 * No operation is required in this call back.
 | 
						|
	 * nexthop_mpls_label_stack_entry_destroy() will take care
 | 
						|
	 * to reset the label vaue.
 | 
						|
	 */
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/ttl
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_modify(
 | 
						|
	struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_destroy(
 | 
						|
	struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XPath:
 | 
						|
 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/traffic-class
 | 
						|
 */
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_modify(
 | 
						|
	struct nb_cb_modify_args *args)
 | 
						|
{
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 | 
						|
 | 
						|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_destroy(
 | 
						|
	struct nb_cb_destroy_args *args)
 | 
						|
{
 | 
						|
	switch (args->event) {
 | 
						|
	case NB_EV_VALIDATE:
 | 
						|
	case NB_EV_PREPARE:
 | 
						|
	case NB_EV_ABORT:
 | 
						|
	case NB_EV_APPLY:
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return NB_OK;
 | 
						|
}
 |