summaryrefslogtreecommitdiffstats
path: root/zebra/zebra_nb_config.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 04:24:32 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 04:24:32 +0000
commit35cadacd2bb9383686753731e31bd7e145fb2506 (patch)
tree4489adbde75a837989533837185b2b8369a0bf68 /zebra/zebra_nb_config.c
parentAdding debian version 9.1-0.1. (diff)
downloadfrr-35cadacd2bb9383686753731e31bd7e145fb2506.tar.xz
frr-35cadacd2bb9383686753731e31bd7e145fb2506.zip
Merging upstream version 10.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'zebra/zebra_nb_config.c')
-rw-r--r--zebra/zebra_nb_config.c2783
1 files changed, 2529 insertions, 254 deletions
diff --git a/zebra/zebra_nb_config.c b/zebra/zebra_nb_config.c
index 5ea0311..5cb9985 100644
--- a/zebra/zebra_nb_config.c
+++ b/zebra/zebra_nb_config.c
@@ -23,6 +23,12 @@
#include "zebra/debug.h"
#include "zebra/zebra_vxlan_private.h"
#include "zebra/zebra_vxlan.h"
+#include "zebra/zebra_evpn_mh.h"
+#include "zebra/zebra_ptm.h"
+#include "zebra/router-id.h"
+#include "zebra/zebra_routemap.h"
+#include "zebra/zebra_rnh.h"
+#include "zebra/table_manager.h"
/*
* XPath: /frr-zebra:zebra/mcast-rpf-lookup
@@ -264,6 +270,43 @@ int zebra_dplane_queue_limit_modify(struct nb_cb_modify_args *args)
return NB_OK;
}
+#if HAVE_BFDD == 0
+/*
+ * XPath: /frr-zebra:zebra/ptm-enable
+ */
+int zebra_ptm_enable_modify(struct nb_cb_modify_args *args)
+{
+ bool ptm;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ptm = yang_dnode_get_bool(args->dnode, NULL);
+
+ if (ptm)
+ zebra_global_ptm_enable();
+ else
+ zebra_global_ptm_disable();
+
+ return NB_OK;
+}
+#endif
+
+/*
+ * XPath: /frr-zebra:zebra/route-map-delay
+ */
+int zebra_route_map_delay_modify(struct nb_cb_modify_args *args)
+{
+ uint32_t delay = yang_dnode_get_uint32(args->dnode, NULL);
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ zebra_route_map_set_delay_timer(delay);
+
+ return NB_OK;
+}
+
/*
* XPath: /frr-zebra:zebra/debugs/debug-events
*/
@@ -823,28 +866,26 @@ int zebra_debugs_debug_mlag_destroy(struct nb_cb_destroy_args *args)
}
/*
- * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip-addrs
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv4-addrs
*/
-int lib_interface_zebra_ip_addrs_create(struct nb_cb_create_args *args)
+int lib_interface_zebra_ipv4_addrs_create(struct nb_cb_create_args *args)
{
struct interface *ifp;
- struct prefix prefix;
+ struct prefix p;
+ const char *label = NULL;
+
+ p.family = AF_INET;
+ yang_dnode_get_ipv4(&p.u.prefix4, args->dnode, "ip");
+ p.prefixlen = yang_dnode_get_uint8(args->dnode, "prefix-length");
- // addr_family = yang_dnode_get_enum(dnode, "./address-family");
- yang_dnode_get_prefix(&prefix, args->dnode, "./ip-prefix");
- apply_mask(&prefix);
+ if (yang_dnode_exists(args->dnode, "label"))
+ label = yang_dnode_get_string(args->dnode, "label");
switch (args->event) {
case NB_EV_VALIDATE:
- if (prefix.family == AF_INET
- && ipv4_martian(&prefix.u.prefix4)) {
+ if (ipv4_martian(&p.u.prefix4)) {
snprintfrr(args->errmsg, args->errmsg_len,
- "invalid address %pFX", &prefix);
- return NB_ERR_VALIDATION;
- } else if (prefix.family == AF_INET6
- && ipv6_martian(&prefix.u.prefix6)) {
- snprintfrr(args->errmsg, args->errmsg_len,
- "invalid address %pFX", &prefix);
+ "invalid address %pFX", &p);
return NB_ERR_VALIDATION;
}
break;
@@ -853,65 +894,105 @@ int lib_interface_zebra_ip_addrs_create(struct nb_cb_create_args *args)
break;
case NB_EV_APPLY:
ifp = nb_running_get_entry(args->dnode, NULL, true);
- if (prefix.family == AF_INET)
- if_ip_address_install(ifp, &prefix, NULL, NULL);
- else if (prefix.family == AF_INET6)
- if_ipv6_address_install(ifp, &prefix, NULL);
+ if_ip_address_install(ifp, &p, label, NULL);
+ /* set something for checking on label modify */
+ nb_running_set_entry(args->dnode, (void *)0x1);
break;
}
return NB_OK;
}
-int lib_interface_zebra_ip_addrs_destroy(struct nb_cb_destroy_args *args)
+int lib_interface_zebra_ipv4_addrs_destroy(struct nb_cb_destroy_args *args)
{
struct interface *ifp;
- struct prefix prefix;
- struct connected *ifc;
+ struct prefix p;
- yang_dnode_get_prefix(&prefix, args->dnode, "./ip-prefix");
- apply_mask(&prefix);
+ p.family = AF_INET;
+ yang_dnode_get_ipv4(&p.u.prefix4, args->dnode, "ip");
+ p.prefixlen = yang_dnode_get_uint8(args->dnode, "prefix-length");
switch (args->event) {
case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ nb_running_unset_entry(args->dnode);
+
ifp = nb_running_get_entry(args->dnode, NULL, false);
- if (!ifp)
- return NB_OK;
-
- if (prefix.family == AF_INET) {
- /* Check current interface address. */
- ifc = connected_check_ptp(ifp, &prefix, NULL);
- if (!ifc) {
- snprintf(args->errmsg, args->errmsg_len,
- "interface %s Can't find address\n",
- ifp->name);
- return NB_ERR_VALIDATION;
- }
- } else if (prefix.family == AF_INET6) {
- /* Check current interface address. */
- ifc = connected_check(ifp, &prefix);
- if (!ifc) {
- snprintf(args->errmsg, args->errmsg_len,
- "interface can't find address %s",
- ifp->name);
- return NB_ERR_VALIDATION;
- }
- } else
- return NB_ERR_VALIDATION;
+ if_ip_address_uninstall(ifp, &p, NULL);
+ break;
+ }
+
+ return NB_OK;
+}
- /* This is not configured address. */
- if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) {
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv4-addrs/label
+ */
+int lib_interface_zebra_ipv4_addrs_label_modify(struct nb_cb_modify_args *args)
+{
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ if (nb_running_get_entry_non_rec(lyd_parent(args->dnode), NULL,
+ false)) {
snprintf(args->errmsg, args->errmsg_len,
- "interface %s not configured", ifp->name);
+ "Changing label is not allowed");
return NB_ERR_VALIDATION;
}
+ break;
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ case NB_EV_APPLY:
+ break;
+ }
+
+ return NB_OK;
+}
- /* This is not real address or interface is not active. */
- if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
- || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
- listnode_delete(ifp->connected, ifc);
- connected_free(&ifc);
+int lib_interface_zebra_ipv4_addrs_label_destroy(struct nb_cb_destroy_args *args)
+{
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ snprintf(args->errmsg, args->errmsg_len,
+ "Removing label is not allowed");
+ return NB_ERR_VALIDATION;
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ case NB_EV_APPLY:
+ break;
+ }
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv4-p2p-addrs
+ */
+int lib_interface_zebra_ipv4_p2p_addrs_create(struct nb_cb_create_args *args)
+{
+ struct interface *ifp;
+ struct prefix p, pp;
+ const char *label = NULL;
+
+ p.family = AF_INET;
+ yang_dnode_get_ipv4(&p.u.prefix4, args->dnode, "ip");
+ p.prefixlen = 32;
+
+ pp.family = AF_INET;
+ yang_dnode_get_ipv4(&pp.u.prefix4, args->dnode, "peer-ip");
+ pp.prefixlen = yang_dnode_get_uint8(args->dnode, "peer-prefix-length");
+
+ if (yang_dnode_exists(args->dnode, "label"))
+ label = yang_dnode_get_string(args->dnode, "label");
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ if (ipv4_martian(&p.u.prefix4)) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "invalid address %pFX", &p);
return NB_ERR_VALIDATION;
}
break;
@@ -920,7 +1001,39 @@ int lib_interface_zebra_ip_addrs_destroy(struct nb_cb_destroy_args *args)
break;
case NB_EV_APPLY:
ifp = nb_running_get_entry(args->dnode, NULL, true);
- if_ip_address_uinstall(ifp, &prefix);
+ if_ip_address_install(ifp, &p, label, &pp);
+
+ /* set something for checking on label modify */
+ nb_running_set_entry(args->dnode, (void *)0x1);
+ break;
+ }
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_ipv4_p2p_addrs_destroy(struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+ struct prefix p, pp;
+
+ p.family = AF_INET;
+ yang_dnode_get_ipv4(&p.u.prefix4, args->dnode, "ip");
+ p.prefixlen = 32;
+
+ pp.family = AF_INET;
+ yang_dnode_get_ipv4(&pp.u.prefix4, args->dnode, "peer-ip");
+ pp.prefixlen = yang_dnode_get_uint8(args->dnode, "peer-prefix-length");
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ nb_running_unset_entry(args->dnode);
+
+ ifp = nb_running_get_entry(args->dnode, NULL, false);
+ if_ip_address_uninstall(ifp, &p, &pp);
break;
}
@@ -928,30 +1041,39 @@ int lib_interface_zebra_ip_addrs_destroy(struct nb_cb_destroy_args *args)
}
/*
- * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip-addrs/label
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv4-p2p-addrs/label
*/
-int lib_interface_zebra_ip_addrs_label_modify(struct nb_cb_modify_args *args)
+int lib_interface_zebra_ipv4_p2p_addrs_label_modify(struct nb_cb_modify_args *args)
{
switch (args->event) {
case NB_EV_VALIDATE:
+ if (nb_running_get_entry_non_rec(lyd_parent(args->dnode), NULL,
+ false)) {
+ snprintf(args->errmsg, args->errmsg_len,
+ "Changing label is not allowed");
+ return NB_ERR_VALIDATION;
+ }
+ break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
- /* TODO: implement me. */
break;
}
return NB_OK;
}
-int lib_interface_zebra_ip_addrs_label_destroy(struct nb_cb_destroy_args *args)
+int lib_interface_zebra_ipv4_p2p_addrs_label_destroy(
+ struct nb_cb_destroy_args *args)
{
switch (args->event) {
case NB_EV_VALIDATE:
+ snprintf(args->errmsg, args->errmsg_len,
+ "Removing label is not allowed");
+ return NB_ERR_VALIDATION;
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
- /* TODO: implement me. */
break;
}
@@ -959,31 +1081,54 @@ int lib_interface_zebra_ip_addrs_label_destroy(struct nb_cb_destroy_args *args)
}
/*
- * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip-addrs/ip4-peer
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-addrs
*/
-int lib_interface_zebra_ip_addrs_ip4_peer_modify(struct nb_cb_modify_args *args)
+int lib_interface_zebra_ipv6_addrs_create(struct nb_cb_create_args *args)
{
+ struct interface *ifp;
+ struct prefix p;
+
+ p.family = AF_INET6;
+ yang_dnode_get_ipv6(&p.u.prefix6, args->dnode, "ip");
+ p.prefixlen = yang_dnode_get_uint8(args->dnode, "prefix-length");
+
switch (args->event) {
case NB_EV_VALIDATE:
+ if (ipv6_martian(&p.u.prefix6)) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "invalid address %pFX", &p);
+ return NB_ERR_VALIDATION;
+ }
+ break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
+ break;
case NB_EV_APPLY:
- /* TODO: implement me. */
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ if_ipv6_address_install(ifp, &p);
break;
}
return NB_OK;
}
-int lib_interface_zebra_ip_addrs_ip4_peer_destroy(
- struct nb_cb_destroy_args *args)
+int lib_interface_zebra_ipv6_addrs_destroy(struct nb_cb_destroy_args *args)
{
+ struct interface *ifp;
+ struct prefix p;
+
+ p.family = AF_INET6;
+ yang_dnode_get_ipv6(&p.u.prefix6, args->dnode, "ip");
+ p.prefixlen = yang_dnode_get_uint8(args->dnode, "prefix-length");
+
switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
+ break;
case NB_EV_APPLY:
- /* TODO: implement me. */
+ ifp = nb_running_get_entry(args->dnode, NULL, false);
+ if_ipv6_address_uninstall(ifp, &p);
break;
}
@@ -999,10 +1144,14 @@ int lib_interface_zebra_multicast_modify(struct nb_cb_modify_args *args)
return NB_OK;
struct interface *ifp;
+ bool multicast = yang_dnode_get_bool(args->dnode, NULL);
ifp = nb_running_get_entry(args->dnode, NULL, true);
- if_multicast_set(ifp);
+ if (multicast)
+ if_multicast_set(ifp);
+ else
+ if_multicast_unset(ifp);
return NB_OK;
}
@@ -1013,10 +1162,12 @@ int lib_interface_zebra_multicast_destroy(struct nb_cb_destroy_args *args)
return NB_OK;
struct interface *ifp;
+ struct zebra_if *zif;
ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
- if_multicast_unset(ifp);
+ zif->multicast = IF_ZEBRA_DATA_UNSPEC;
return NB_OK;
}
@@ -1033,23 +1184,7 @@ int lib_interface_zebra_link_detect_modify(struct nb_cb_modify_args *args)
bool link_detect;
ifp = nb_running_get_entry(args->dnode, NULL, true);
- link_detect = yang_dnode_get_bool(args->dnode, "./link-detect");
-
- if_linkdetect(ifp, link_detect);
-
- return NB_OK;
-}
-
-int lib_interface_zebra_link_detect_destroy(struct nb_cb_destroy_args *args)
-{
- if (args->event != NB_EV_APPLY)
- return NB_OK;
-
- struct interface *ifp;
- bool link_detect;
-
- ifp = nb_running_get_entry(args->dnode, NULL, true);
- link_detect = yang_dnode_get_bool(args->dnode, "./link-detect");
+ link_detect = yang_dnode_get_bool(args->dnode, NULL);
if_linkdetect(ifp, link_detect);
@@ -1057,32 +1192,39 @@ int lib_interface_zebra_link_detect_destroy(struct nb_cb_destroy_args *args)
}
/*
- * XPath: /frr-interface:lib/interface/frr-zebra:zebra/shutdown
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/enabled
*/
-int lib_interface_zebra_shutdown_modify(struct nb_cb_modify_args *args)
+int lib_interface_zebra_enabled_modify(struct nb_cb_modify_args *args)
{
if (args->event != NB_EV_APPLY)
return NB_OK;
struct interface *ifp;
+ bool enabled;
ifp = nb_running_get_entry(args->dnode, NULL, true);
+ enabled = yang_dnode_get_bool(args->dnode, NULL);
- if_shutdown(ifp);
+ if (enabled)
+ if_no_shutdown(ifp);
+ else
+ if_shutdown(ifp);
return NB_OK;
}
-int lib_interface_zebra_shutdown_destroy(struct nb_cb_destroy_args *args)
+int lib_interface_zebra_enabled_destroy(struct nb_cb_destroy_args *args)
{
if (args->event != NB_EV_APPLY)
return NB_OK;
struct interface *ifp;
+ struct zebra_if *zif;
ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
- if_no_shutdown(ifp);
+ zif->shutdown = IF_ZEBRA_DATA_UNSPEC;
return NB_OK;
}
@@ -1143,7 +1285,7 @@ int lib_interface_zebra_bandwidth_modify(struct nb_cb_modify_args *args)
uint32_t bandwidth;
ifp = nb_running_get_entry(args->dnode, NULL, true);
- bandwidth = yang_dnode_get_uint32(args->dnode, "./bandwidth");
+ bandwidth = yang_dnode_get_uint32(args->dnode, NULL);
ifp->bandwidth = bandwidth;
@@ -1173,58 +1315,425 @@ int lib_interface_zebra_bandwidth_destroy(struct nb_cb_destroy_args *args)
}
/*
- * XPath:
- * /frr-interface:lib/interface/frr-zebra:zebra/link-params/legacy-admin-group
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params
*/
-int lib_interface_zebra_legacy_admin_group_modify(
+int lib_interface_zebra_link_params_create(struct nb_cb_create_args *args)
+{
+ struct interface *ifp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ if_link_params_enable(ifp);
+
+ /*
+ * The interface is updated in the apply_finish callback after all
+ * parameters are set in the corresponding callbacks.
+ */
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_link_params_destroy(struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ if_link_params_free(ifp);
+ if (if_is_operative(ifp))
+ zebra_interface_parameters_update(ifp);
+
+ return NB_OK;
+}
+
+void lib_interface_zebra_link_params_apply_finish(
+ struct nb_cb_apply_finish_args *args)
+{
+ struct interface *ifp;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ if (if_is_operative(ifp))
+ zebra_interface_parameters_update(ifp);
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/metric
+ */
+int lib_interface_zebra_link_params_metric_modify(struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+ uint32_t metric;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+ metric = yang_dnode_get_uint32(args->dnode, NULL);
+
+ link_param_cmd_set_uint32(ifp, &iflp->te_metric, LP_TE_METRIC, metric);
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_link_params_metric_destroy(struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+
+ link_param_cmd_unset(ifp, LP_TE_METRIC);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/max-bandwidth
+ */
+int lib_interface_zebra_link_params_max_bandwidth_modify(
struct nb_cb_modify_args *args)
{
struct interface *ifp;
struct if_link_params *iflp;
- uint32_t admin_group_value;
+ float max_bw, res_bw, ava_bw, use_bw;
+
+ max_bw = yang_dnode_get_bandwidth_ieee_float32(args->dnode, NULL);
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ if (yang_dnode_exists(args->dnode, "../residual-bandwidth")) {
+ res_bw = yang_dnode_get_bandwidth_ieee_float32(
+ args->dnode, "../residual-bandwidth");
+ if (max_bw < res_bw) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "max-bandwidth %f is less than residual-bandwidth %f",
+ max_bw, res_bw);
+ return NB_ERR_VALIDATION;
+ }
+ }
+ if (yang_dnode_exists(args->dnode, "../available-bandwidth")) {
+ ava_bw = yang_dnode_get_bandwidth_ieee_float32(
+ args->dnode, "../available-bandwidth");
+ if (max_bw < ava_bw) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "max-bandwidth %f is less than available-bandwidth %f",
+ max_bw, ava_bw);
+ return NB_ERR_VALIDATION;
+ }
+ }
+ if (yang_dnode_exists(args->dnode, "../utilized-bandwidth")) {
+ use_bw = yang_dnode_get_bandwidth_ieee_float32(
+ args->dnode, "../utilized-bandwidth");
+ if (max_bw < use_bw) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "max-bandwidth %f is less than utilized-bandwidth %f",
+ max_bw, use_bw);
+ return NB_ERR_VALIDATION;
+ }
+ }
+ break;
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+ link_param_cmd_set_float(ifp, &iflp->max_bw, LP_MAX_BW, max_bw);
+ break;
+ }
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_link_params_max_bandwidth_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ if (args->event == NB_EV_VALIDATE) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "Removing max-bandwidth is not allowed");
+ return NB_ERR_VALIDATION;
+ }
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/max-reservable-bandwidth
+ */
+int lib_interface_zebra_link_params_max_reservable_bandwidth_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+ float max_rsv_bw;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ max_rsv_bw = yang_dnode_get_bandwidth_ieee_float32(args->dnode, NULL);
ifp = nb_running_get_entry(args->dnode, NULL, true);
- admin_group_value = yang_dnode_get_uint32(args->dnode, ".");
+ iflp = if_link_params_get(ifp);
+ link_param_cmd_set_float(ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW,
+ max_rsv_bw);
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_link_params_max_reservable_bandwidth_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ if (args->event == NB_EV_VALIDATE) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "Removing max-reservable-bandwidth is not allowed");
+ return NB_ERR_VALIDATION;
+ }
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/unreserved-bandwidths/unreserved-bandwidth
+ */
+int lib_interface_zebra_link_params_unreserved_bandwidths_unreserved_bandwidth_create(
+ struct nb_cb_create_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+ uint8_t priority;
+ float unrsv_bw;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ priority = yang_dnode_get_uint8(args->dnode, "priority");
+ unrsv_bw = yang_dnode_get_bandwidth_ieee_float32(args->dnode,
+ "unreserved-bandwidth");
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+ link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW,
+ unrsv_bw);
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_link_params_unreserved_bandwidths_unreserved_bandwidth_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ if (args->event == NB_EV_VALIDATE) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "Removing unreserved-bandwidth is not allowed");
+ return NB_ERR_VALIDATION;
+ }
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/unreserved-bandwidths/unreserved-bandwidth/unreserved-bandwidth
+ */
+int lib_interface_zebra_link_params_unreserved_bandwidths_unreserved_bandwidth_unreserved_bandwidth_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+ uint8_t priority;
+ float unrsv_bw;
- if (!ifp)
- return NB_ERR_RESOURCE;
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+ priority = yang_dnode_get_uint8(args->dnode, "../priority");
+ unrsv_bw = yang_dnode_get_bandwidth_ieee_float32(args->dnode, NULL);
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
iflp = if_link_params_get(ifp);
+ link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW,
+ unrsv_bw);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/residual-bandwidth
+ */
+int lib_interface_zebra_link_params_residual_bandwidth_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+ float max_bw, res_bw;
+
+ res_bw = yang_dnode_get_bandwidth_ieee_float32(args->dnode, NULL);
switch (args->event) {
case NB_EV_VALIDATE:
+ if (yang_dnode_exists(args->dnode, "../max-bandwidth")) {
+ max_bw =
+ yang_dnode_get_bandwidth_ieee_float32(args->dnode,
+ "../max-bandwidth");
+ if (max_bw < res_bw) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "max-bandwidth %f is less than residual-bandwidth %f",
+ max_bw, res_bw);
+ return NB_ERR_VALIDATION;
+ }
+ }
+ break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
case NB_EV_APPLY:
- if (!iflp)
- iflp = if_link_params_enable(ifp);
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+ link_param_cmd_set_float(ifp, &iflp->res_bw, LP_RES_BW, res_bw);
+ break;
+ }
- iflp->admin_grp = admin_group_value;
- SET_PARAM(iflp, LP_ADM_GRP);
+ return NB_OK;
+}
+
+int lib_interface_zebra_link_params_residual_bandwidth_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ link_param_cmd_unset(ifp, LP_RES_BW);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/available-bandwidth
+ */
+int lib_interface_zebra_link_params_available_bandwidth_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+ float max_bw, ava_bw;
- admin_group_clear(&iflp->ext_admin_grp);
- UNSET_PARAM(iflp, LP_EXTEND_ADM_GRP);
+ ava_bw = yang_dnode_get_bandwidth_ieee_float32(args->dnode, NULL);
- if (if_is_operative(ifp))
- zebra_interface_parameters_update(ifp);
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ if (yang_dnode_exists(args->dnode, "../max-bandwidth")) {
+ max_bw =
+ yang_dnode_get_bandwidth_ieee_float32(args->dnode,
+ "../max-bandwidth");
+ if (max_bw < ava_bw) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "max-bandwidth %f is less than available-bandwidth %f",
+ max_bw, ava_bw);
+ return NB_ERR_VALIDATION;
+ }
+ }
+ break;
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+ link_param_cmd_set_float(ifp, &iflp->ava_bw, LP_AVA_BW, ava_bw);
break;
}
+
return NB_OK;
}
-int lib_interface_zebra_legacy_admin_group_destroy(
+int lib_interface_zebra_link_params_available_bandwidth_destroy(
struct nb_cb_destroy_args *args)
{
struct interface *ifp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ link_param_cmd_unset(ifp, LP_AVA_BW);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/utilized-bandwidth
+ */
+int lib_interface_zebra_link_params_utilized_bandwidth_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
struct if_link_params *iflp;
+ float max_bw, use_bw;
+
+ use_bw = yang_dnode_get_bandwidth_ieee_float32(args->dnode, NULL);
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ if (yang_dnode_exists(args->dnode, "../max-bandwidth")) {
+ max_bw =
+ yang_dnode_get_bandwidth_ieee_float32(args->dnode,
+ "../max-bandwidth");
+ if (max_bw < use_bw) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "max-bandwidth %f is less than utilized-bandwidth %f",
+ max_bw, use_bw);
+ return NB_ERR_VALIDATION;
+ }
+ }
+ break;
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+ link_param_cmd_set_float(ifp, &iflp->use_bw, LP_USE_BW, use_bw);
+ break;
+ }
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_link_params_utilized_bandwidth_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
ifp = nb_running_get_entry(args->dnode, NULL, true);
+ link_param_cmd_unset(ifp, LP_USE_BW);
- if (!ifp)
- return NB_ERR_RESOURCE;
+ return NB_OK;
+}
- iflp = if_link_params_get(ifp);
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-zebra:zebra/link-params/legacy-admin-group
+ */
+int lib_interface_zebra_legacy_admin_group_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+ uint32_t admin_group_value;
+
+ admin_group_value = yang_dnode_get_uint32(args->dnode, ".");
switch (args->event) {
case NB_EV_VALIDATE:
@@ -1232,14 +1741,33 @@ int lib_interface_zebra_legacy_admin_group_destroy(
case NB_EV_ABORT:
break;
case NB_EV_APPLY:
- if (!iflp)
- iflp = if_link_params_enable(ifp);
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+
+ iflp->admin_grp = admin_group_value;
+ SET_PARAM(iflp, LP_ADM_GRP);
+ break;
+ }
+ return NB_OK;
+}
+
+int lib_interface_zebra_legacy_admin_group_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
iflp->admin_grp = 0;
UNSET_PARAM(iflp, LP_ADM_GRP);
-
- if (if_is_operative(ifp))
- zebra_interface_parameters_update(ifp);
break;
}
return NB_OK;
@@ -1247,6 +1775,35 @@ int lib_interface_zebra_legacy_admin_group_destroy(
/*
* XPath:
+ * /frr-interface:lib/interface/frr-zebra:zebra/link-params/affinities
+ */
+int lib_interface_zebra_affinities_create(struct nb_cb_create_args *args)
+{
+ return NB_OK;
+}
+
+int lib_interface_zebra_affinities_destroy(struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+
+ iflp->admin_grp = 0;
+ UNSET_PARAM(iflp, LP_ADM_GRP);
+
+ admin_group_clear(&iflp->ext_admin_grp);
+ UNSET_PARAM(iflp, LP_EXTEND_ADM_GRP);
+
+ return NB_OK;
+}
+
+/*
+ * XPath:
* /frr-interface:lib/interface/frr-zebra:zebra/link-params/affinities/affinity
*/
int lib_interface_zebra_affinity_create(struct nb_cb_create_args *args)
@@ -1257,39 +1814,18 @@ int lib_interface_zebra_affinity_create(struct nb_cb_create_args *args)
struct affinity_map *affmap;
enum affinity_mode affinity_mode;
-
- ifp = nb_running_get_entry(args->dnode, NULL, true);
affname = yang_dnode_get_string(args->dnode, ".");
affinity_mode = yang_dnode_get_enum(args->dnode, "../../affinity-mode");
- if (!ifp)
- return NB_ERR_RESOURCE;
-
- affmap = affinity_map_get(affname);
- iflp = if_link_params_get(ifp);
-
switch (args->event) {
case NB_EV_VALIDATE:
- if (!affmap) {
- snprintf(args->errmsg, args->errmsg_len,
- "affinity-map %s not found.", affname);
- return NB_ERR_VALIDATION;
- }
- if (affinity_mode == AFFINITY_MODE_STANDARD &&
- affmap->bit_position > 31) {
- snprintf(
- args->errmsg, args->errmsg_len,
- "affinity %s bit-position %d is not compatible with affinity-mode standard (bit-position > 31).",
- affname, affmap->bit_position);
- return NB_ERR_VALIDATION;
- }
- break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
case NB_EV_APPLY:
- if (!iflp)
- iflp = if_link_params_enable(ifp);
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+ affmap = affinity_map_get(affname);
if (affmap->bit_position < 32 &&
(affinity_mode == AFFINITY_MODE_STANDARD ||
@@ -1303,9 +1839,6 @@ int lib_interface_zebra_affinity_create(struct nb_cb_create_args *args)
affmap->bit_position);
SET_PARAM(iflp, LP_EXTEND_ADM_GRP);
}
-
- if (if_is_operative(ifp))
- zebra_interface_parameters_update(ifp);
break;
}
return NB_OK;
@@ -1319,30 +1852,19 @@ int lib_interface_zebra_affinity_destroy(struct nb_cb_destroy_args *args)
struct affinity_map *affmap;
enum affinity_mode affinity_mode;
- ifp = nb_running_get_entry(args->dnode, NULL, true);
affname = yang_dnode_get_string(args->dnode, ".");
affinity_mode = yang_dnode_get_enum(args->dnode, "../../affinity-mode");
- if (!ifp)
- return NB_ERR_RESOURCE;
-
- affmap = affinity_map_get(affname);
- iflp = if_link_params_get(ifp);
-
switch (args->event) {
case NB_EV_VALIDATE:
- if (!affmap) {
- snprintf(args->errmsg, args->errmsg_len,
- "affinity-map %s not found.", affname);
- return NB_ERR_VALIDATION;
- }
- break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
case NB_EV_APPLY:
- if (!iflp)
- return NB_OK;
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+ affmap = affinity_map_get(affname);
+
if (affmap->bit_position < 32 &&
(affinity_mode == AFFINITY_MODE_STANDARD ||
affinity_mode == AFFINITY_MODE_BOTH)) {
@@ -1357,9 +1879,6 @@ int lib_interface_zebra_affinity_destroy(struct nb_cb_destroy_args *args)
if (admin_group_zero(&iflp->ext_admin_grp))
UNSET_PARAM(iflp, LP_EXTEND_ADM_GRP);
}
-
- if (if_is_operative(ifp))
- zebra_interface_parameters_update(ifp);
break;
}
return NB_OK;
@@ -1375,31 +1894,17 @@ int lib_interface_zebra_affinity_mode_modify(struct nb_cb_modify_args *args)
struct if_link_params *iflp;
enum affinity_mode affinity_mode;
-
- ifp = nb_running_get_entry(args->dnode, NULL, true);
affinity_mode = yang_dnode_get_enum(args->dnode, ".");
- if (!ifp)
- return NB_ERR_RESOURCE;
-
- iflp = if_link_params_get(ifp);
-
switch (args->event) {
case NB_EV_VALIDATE:
- if (affinity_mode == AFFINITY_MODE_STANDARD &&
- admin_group_nb_words(&iflp->ext_admin_grp) > 1) {
- snprintf(
- args->errmsg, args->errmsg_len,
- "affinity-mode standard cannot be set when a bit-position > 31 is set.");
- return NB_ERR_VALIDATION;
- }
- break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
case NB_EV_APPLY:
- if (!iflp)
- iflp = if_link_params_enable(ifp);
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+
if (affinity_mode == AFFINITY_MODE_STANDARD) {
if (!IS_PARAM_SET(iflp, LP_ADM_GRP) &&
IS_PARAM_SET(iflp, LP_EXTEND_ADM_GRP)) {
@@ -1433,84 +1938,1880 @@ int lib_interface_zebra_affinity_mode_modify(struct nb_cb_modify_args *args)
SET_PARAM(iflp, LP_ADM_GRP);
}
}
+ break;
+ }
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/neighbor
+ */
+int lib_interface_zebra_link_params_neighbor_create(struct nb_cb_create_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+ struct in_addr ip;
+ uint32_t as;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ as = yang_dnode_get_uint32(args->dnode, "remote-as");
+ yang_dnode_get_ipv4(&ip, args->dnode, "ipv4-remote-id");
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+
+ iflp->rmt_as = as;
+ iflp->rmt_ip = ip;
+ SET_PARAM(iflp, LP_RMT_AS);
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_link_params_neighbor_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+
+ iflp->rmt_as = 0;
+ iflp->rmt_ip.s_addr = 0;
+ UNSET_PARAM(iflp, LP_RMT_AS);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/neighbor/remote-as
+ */
+int lib_interface_zebra_link_params_neighbor_remote_as_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+ uint32_t as;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ as = yang_dnode_get_uint32(args->dnode, NULL);
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+
+ iflp->rmt_as = as;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/neighbor/ipv4-remote-id
+ */
+int lib_interface_zebra_link_params_neighbor_ipv4_remote_id_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+ struct in_addr ip;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ yang_dnode_get_ipv4(&ip, args->dnode, NULL);
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+
+ iflp->rmt_ip = ip;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/delay
+ */
+int lib_interface_zebra_link_params_delay_modify(struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+ uint32_t delay;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ delay = yang_dnode_get_uint32(args->dnode, NULL);
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+
+ link_param_cmd_set_uint32(ifp, &iflp->av_delay, LP_DELAY, delay);
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_link_params_delay_destroy(struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+
+ iflp->av_delay = 0;
+ link_param_cmd_unset(ifp, LP_DELAY);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/min-max-delay
+ */
+int lib_interface_zebra_link_params_min_max_delay_create(
+ struct nb_cb_create_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+ uint32_t delay_min, delay_max;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ delay_min = yang_dnode_get_uint32(args->dnode, "delay-min");
+ delay_max = yang_dnode_get_uint32(args->dnode, "delay-max");
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+
+ iflp->min_delay = delay_min;
+ iflp->max_delay = delay_max;
+ SET_PARAM(iflp, LP_MM_DELAY);
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_link_params_min_max_delay_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+
+ iflp->min_delay = 0;
+ iflp->max_delay = 0;
+ UNSET_PARAM(iflp, LP_MM_DELAY);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/min-max-delay/delay-min
+ */
+int lib_interface_zebra_link_params_min_max_delay_delay_min_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+ uint32_t delay_min;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ delay_min = yang_dnode_get_uint32(args->dnode, NULL);
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+
+ iflp->min_delay = delay_min;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/min-max-delay/delay-max
+ */
+int lib_interface_zebra_link_params_min_max_delay_delay_max_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+ uint32_t delay_max;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ delay_max = yang_dnode_get_uint32(args->dnode, NULL);
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+
+ iflp->max_delay = delay_max;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/delay-variation
+ */
+int lib_interface_zebra_link_params_delay_variation_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+ uint32_t delay_var;
- if (if_is_operative(ifp))
- zebra_interface_parameters_update(ifp);
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ delay_var = yang_dnode_get_uint32(args->dnode, NULL);
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+
+ link_param_cmd_set_uint32(ifp, &iflp->delay_var, LP_DELAY_VAR,
+ delay_var);
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_link_params_delay_variation_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+
+ link_param_cmd_unset(ifp, LP_DELAY_VAR);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/packet-loss
+ */
+int lib_interface_zebra_link_params_packet_loss_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct if_link_params *iflp;
+ double packet_loss;
+ uint32_t value;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ packet_loss = yang_dnode_get_dec64(args->dnode, NULL);
+ value = (uint32_t)(packet_loss / LOSS_PRECISION);
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ iflp = if_link_params_get(ifp);
+
+ link_param_cmd_set_uint32(ifp, &iflp->pkt_loss, LP_PKT_LOSS, value);
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_link_params_packet_loss_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+
+ link_param_cmd_unset(ifp, LP_PKT_LOSS);
+
+ return NB_OK;
+}
+
+static bool evpn_mh_dnode_to_esi(const struct lyd_node *dnode, esi_t *esi)
+{
+ if (yang_dnode_exists(dnode, "type-0/esi")) {
+ if (!str_to_esi(yang_dnode_get_string(dnode, "type-0/esi"), esi))
+ assert(false);
+ } else if (yang_dnode_exists(dnode, "type-3/system-mac") &&
+ yang_dnode_exists(dnode, "type-3/local-discriminator")) {
+ struct ethaddr mac;
+ uint32_t lid;
+
+ yang_dnode_get_mac(&mac, dnode, "type-3/system-mac");
+ lid = yang_dnode_get_uint32(dnode, "type-3/local-discriminator");
+
+ zebra_build_type3_esi(lid, &mac, esi);
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+struct esi_cmp_iter_arg {
+ struct lyd_node *dnode;
+ esi_t esi;
+ bool exists;
+};
+
+static int esi_cmp_iter_cb(const struct lyd_node *dnode, void *arg)
+{
+ struct esi_cmp_iter_arg *iter = arg;
+ esi_t esi;
+
+ if (dnode == iter->dnode)
+ return YANG_ITER_CONTINUE;
+
+ if (!evpn_mh_dnode_to_esi(dnode, &esi))
+ return YANG_ITER_CONTINUE;
+
+ if (!memcmp(&esi, &iter->esi, ESI_BYTES)) {
+ iter->exists = true;
+ return YANG_ITER_STOP;
+ }
+
+ return YANG_ITER_CONTINUE;
+}
+
+/* evpn-mh should be passed to this function */
+static bool esi_unique(struct lyd_node *dnode)
+{
+ struct esi_cmp_iter_arg iter;
+
+ iter.dnode = dnode;
+ evpn_mh_dnode_to_esi(dnode, &iter.esi);
+ iter.exists = false;
+
+ yang_dnode_iterate(esi_cmp_iter_cb, &iter, dnode,
+ "/frr-interface:lib/interface/frr-zebra:zebra/evpn-mh");
+
+ if (iter.exists)
+ return false;
+
+ return true;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/type-0
+ */
+int lib_interface_zebra_evpn_mh_type_0_create(struct nb_cb_create_args *args)
+{
+ return NB_OK;
+}
+
+int lib_interface_zebra_evpn_mh_type_0_destroy(struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zebra_evpn_es_type0_esi_update(ifp->info, NULL);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/type-0/esi
+ */
+int lib_interface_zebra_evpn_mh_type_0_esi_modify(struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ esi_t esi;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ if (!esi_unique(lyd_parent(lyd_parent(args->dnode)))) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "ESI already exists on a different interface");
+ return NB_ERR_VALIDATION;
+ }
+ break;
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ if (!str_to_esi(yang_dnode_get_string(args->dnode, NULL), &esi))
+ assert(false);
+ zebra_evpn_es_type0_esi_update(ifp->info, &esi);
break;
}
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_evpn_mh_type_0_esi_destroy(struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zebra_evpn_es_type0_esi_update(ifp->info, NULL);
+
return NB_OK;
}
/*
- * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/l3vni-id
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/type-3
*/
-int lib_vrf_zebra_l3vni_id_modify(struct nb_cb_modify_args *args)
+int lib_interface_zebra_evpn_mh_type_3_create(struct nb_cb_create_args *args)
{
- struct vrf *vrf;
- struct zebra_vrf *zvrf;
- vni_t vni = 0;
- struct zebra_l3vni *zl3vni = NULL;
- char err[ERR_STR_SZ];
- bool pfx_only = false;
- const struct lyd_node *pn_dnode;
- const char *vrfname;
+ return NB_OK;
+}
+
+int lib_interface_zebra_evpn_mh_type_3_destroy(struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zebra_evpn_es_sys_mac_update(ifp->info, NULL);
+ zebra_evpn_es_lid_update(ifp->info, 0);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/type-3/system-mac
+ */
+int lib_interface_zebra_evpn_mh_type_3_system_mac_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct ethaddr mac;
+
+ yang_dnode_get_mac(&mac, args->dnode, NULL);
switch (args->event) {
+ case NB_EV_VALIDATE:
+ if (is_zero_mac(&mac)) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "MAC cannot be all-zeroes");
+ return NB_ERR_VALIDATION;
+ }
+ if (!esi_unique(lyd_parent(lyd_parent(args->dnode)))) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "ESI already exists on a different interface");
+ return NB_ERR_VALIDATION;
+ }
+ break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zebra_evpn_es_sys_mac_update(ifp->info, &mac);
+ break;
+ }
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_evpn_mh_type_3_system_mac_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+
+ if (args->event != NB_EV_APPLY)
return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zebra_evpn_es_sys_mac_update(ifp->info, NULL);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/type-3/local-discriminator
+ */
+int lib_interface_zebra_evpn_mh_type_3_local_discriminator_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ uint32_t lid;
+
+ switch (args->event) {
case NB_EV_VALIDATE:
- vni = yang_dnode_get_uint32(args->dnode, NULL);
- /* Get vrf info from parent node, reject configuration
- * if zebra vrf already mapped to different vni id.
- */
- pn_dnode = yang_dnode_get_parent(args->dnode, "vrf");
- vrfname = yang_dnode_get_string(pn_dnode, "./name");
- zvrf = zebra_vrf_lookup_by_name(vrfname);
- if (!zvrf) {
- snprintf(args->errmsg, args->errmsg_len,
- "zebra vrf info not found for vrf:%s.",
- vrfname);
+ if (!esi_unique(lyd_parent(lyd_parent(args->dnode)))) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "ESI already exists on a different interface");
+ return NB_ERR_VALIDATION;
+ }
+ break;
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ lid = yang_dnode_get_uint32(args->dnode, NULL);
+ zebra_evpn_es_lid_update(ifp->info, lid);
+ break;
+ }
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_evpn_mh_type_3_local_discriminator_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zebra_evpn_es_lid_update(ifp->info, 0);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/df-preference
+ */
+int lib_interface_zebra_evpn_mh_df_preference_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ uint16_t df_pref;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ df_pref = yang_dnode_get_uint16(args->dnode, NULL);
+ zebra_evpn_es_df_pref_update(ifp->info, df_pref);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/bypass
+ */
+int lib_interface_zebra_evpn_mh_bypass_modify(struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ bool bypass;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ bypass = yang_dnode_get_bool(args->dnode, NULL);
+ zebra_evpn_es_bypass_cfg_update(ifp->info, bypass);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/uplink
+ */
+int lib_interface_zebra_evpn_mh_uplink_modify(struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ bool uplink;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ uplink = yang_dnode_get_bool(args->dnode, NULL);
+ zebra_evpn_mh_uplink_cfg_update(ifp->info, uplink);
+
+ return NB_OK;
+}
+
+#if defined(HAVE_RTADV)
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/send-advertisements
+ */
+int lib_interface_zebra_ipv6_router_advertisements_send_advertisements_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+ bool send_adv;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+
+ send_adv = yang_dnode_get_bool(args->dnode, NULL);
+
+ if (send_adv) {
+ ipv6_nd_suppress_ra_set(ifp, RA_ENABLE);
+ SET_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED);
+ } else {
+ if (!CHECK_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED))
+ ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS);
+ UNSET_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED);
+ }
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/max-rtr-adv-interval
+ */
+int lib_interface_zebra_ipv6_router_advertisements_max_rtr_adv_interval_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ uint32_t interval;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ interval = yang_dnode_get_uint32(args->dnode, NULL);
+
+ ipv6_nd_interval_set(ifp, interval);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/managed-flag
+ */
+int lib_interface_zebra_ipv6_router_advertisements_managed_flag_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+ bool managed_flag;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+
+ managed_flag = yang_dnode_get_bool(args->dnode, NULL);
+
+ zif->rtadv.AdvManagedFlag = managed_flag;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/other-config-flag
+ */
+int lib_interface_zebra_ipv6_router_advertisements_other_config_flag_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+ bool other_config_flag;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+
+ other_config_flag = yang_dnode_get_bool(args->dnode, NULL);
+
+ zif->rtadv.AdvOtherConfigFlag = other_config_flag;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/home-agent-flag
+ */
+int lib_interface_zebra_ipv6_router_advertisements_home_agent_flag_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+ bool home_agent_flag;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+
+ home_agent_flag = yang_dnode_get_bool(args->dnode, NULL);
+
+ zif->rtadv.AdvHomeAgentFlag = home_agent_flag;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/link-mtu
+ */
+int lib_interface_zebra_ipv6_router_advertisements_link_mtu_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+ uint32_t mtu;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+
+ mtu = yang_dnode_get_uint32(args->dnode, NULL);
+
+ zif->rtadv.AdvLinkMTU = mtu;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/reachable-time
+ */
+int lib_interface_zebra_ipv6_router_advertisements_reachable_time_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+ uint32_t time;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+ time = yang_dnode_get_uint32(args->dnode, NULL);
+
+ zif->rtadv.AdvReachableTime = time;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/retrans-timer
+ */
+int lib_interface_zebra_ipv6_router_advertisements_retrans_timer_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+ uint32_t timer;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+ timer = yang_dnode_get_uint32(args->dnode, NULL);
+
+ zif->rtadv.AdvRetransTimer = timer;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/cur-hop-limit
+ */
+int lib_interface_zebra_ipv6_router_advertisements_cur_hop_limit_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+ uint8_t limit;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+ limit = yang_dnode_get_uint8(args->dnode, NULL);
+
+ zif->rtadv.AdvCurHopLimit = limit;
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_ipv6_router_advertisements_cur_hop_limit_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+
+ zif->rtadv.AdvCurHopLimit = RTADV_DEFAULT_HOPLIMIT;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/default-lifetime
+ */
+int lib_interface_zebra_ipv6_router_advertisements_default_lifetime_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+ uint16_t lifetime;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+
+ lifetime = yang_dnode_get_uint16(args->dnode, NULL);
+
+ zif->rtadv.AdvDefaultLifetime = lifetime;
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_ipv6_router_advertisements_default_lifetime_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+
+ zif->rtadv.AdvDefaultLifetime = -1;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/fast-retransmit
+ */
+int lib_interface_zebra_ipv6_router_advertisements_fast_retransmit_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+ bool fast_retransmit;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+
+ fast_retransmit = yang_dnode_get_bool(args->dnode, NULL);
+
+ zif->rtadv.UseFastRexmit = fast_retransmit;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/advertisement-interval-option
+ */
+int lib_interface_zebra_ipv6_router_advertisements_advertisement_interval_option_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+ bool option;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+
+ option = yang_dnode_get_bool(args->dnode, NULL);
+
+ zif->rtadv.AdvIntervalOption = option;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/home-agent-preference
+ */
+int lib_interface_zebra_ipv6_router_advertisements_home_agent_preference_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+ uint16_t preference;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+
+ preference = yang_dnode_get_uint16(args->dnode, NULL);
+
+ zif->rtadv.HomeAgentPreference = preference;
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_ipv6_router_advertisements_home_agent_preference_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+
+ zif->rtadv.HomeAgentPreference = 0;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/home-agent-lifetime
+ */
+int lib_interface_zebra_ipv6_router_advertisements_home_agent_lifetime_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+ uint16_t lifetime;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+
+ lifetime = yang_dnode_get_uint16(args->dnode, NULL);
+
+ zif->rtadv.HomeAgentLifetime = lifetime;
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_ipv6_router_advertisements_home_agent_lifetime_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+
+ zif->rtadv.HomeAgentLifetime = -1;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/default-router-preference
+ */
+int lib_interface_zebra_ipv6_router_advertisements_default_router_preference_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct zebra_if *zif;
+ int preference;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ zif = ifp->info;
+
+ preference = yang_dnode_get_enum(args->dnode, NULL);
+
+ zif->rtadv.DefaultPreference = preference;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix
+ */
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_create(
+ struct nb_cb_create_args *args)
+{
+ struct interface *ifp;
+ struct rtadv_prefix rp, *prefix;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+
+ yang_dnode_get_ipv6p(&rp.prefix, args->dnode, "prefix-spec");
+ rp.AdvOnLinkFlag = yang_dnode_get_bool(args->dnode, "on-link-flag");
+ rp.AdvAutonomousFlag = yang_dnode_get_bool(args->dnode,
+ "autonomous-flag");
+ rp.AdvRouterAddressFlag = yang_dnode_get_bool(args->dnode,
+ "router-address-flag");
+ rp.AdvValidLifetime = yang_dnode_get_uint32(args->dnode,
+ "valid-lifetime");
+ rp.AdvPreferredLifetime = yang_dnode_get_uint32(args->dnode,
+ "preferred-lifetime");
+
+ prefix = rtadv_add_prefix_manual(ifp->info, &rp);
+ nb_running_set_entry(args->dnode, prefix);
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+ struct rtadv_prefix *prefix;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ prefix = nb_running_unset_entry(args->dnode);
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+
+ rtadv_delete_prefix_manual(ifp->info, prefix);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/valid-lifetime
+ */
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_valid_lifetime_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct rtadv_prefix *prefix;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ prefix = nb_running_get_entry(args->dnode, NULL, true);
+
+ prefix->AdvValidLifetime = yang_dnode_get_uint32(args->dnode, NULL);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/on-link-flag
+ */
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_on_link_flag_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct rtadv_prefix *prefix;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ prefix = nb_running_get_entry(args->dnode, NULL, true);
+
+ prefix->AdvOnLinkFlag = yang_dnode_get_bool(args->dnode, NULL);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/preferred-lifetime
+ */
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_preferred_lifetime_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct rtadv_prefix *prefix;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ prefix = nb_running_get_entry(args->dnode, NULL, true);
+
+ prefix->AdvPreferredLifetime = yang_dnode_get_uint32(args->dnode, NULL);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/autonomous-flag
+ */
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_autonomous_flag_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct rtadv_prefix *prefix;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ prefix = nb_running_get_entry(args->dnode, NULL, true);
+
+ prefix->AdvAutonomousFlag = yang_dnode_get_bool(args->dnode, NULL);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/router-address-flag
+ */
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_router_address_flag_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct rtadv_prefix *prefix;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ prefix = nb_running_get_entry(args->dnode, NULL, true);
+
+ prefix->AdvRouterAddressFlag = yang_dnode_get_bool(args->dnode, NULL);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/rdnss/rdnss-address
+ */
+int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_create(
+ struct nb_cb_create_args *args)
+{
+ struct interface *ifp;
+ struct rtadv_rdnss rdnss = {0}, *p;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+
+ yang_dnode_get_ipv6(&rdnss.addr, args->dnode, "address");
+ if (yang_dnode_exists(args->dnode, "lifetime")) {
+ rdnss.lifetime = yang_dnode_get_uint32(args->dnode, "lifetime");
+ rdnss.lifetime_set = 1;
+ } else {
+ rdnss.lifetime_set = 0;
+ }
+
+ p = rtadv_rdnss_set(ifp->info, &rdnss);
+ nb_running_set_entry(args->dnode, p);
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+ struct rtadv_rdnss *p;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ p = nb_running_unset_entry(args->dnode);
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+
+ rtadv_rdnss_reset(ifp->info, p);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/rdnss/rdnss-address/lifetime
+ */
+int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_lifetime_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct rtadv_rdnss *p;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ p = nb_running_get_entry(args->dnode, NULL, true);
+
+ p->lifetime = yang_dnode_get_uint32(args->dnode, NULL);
+ p->lifetime_set = 1;
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_lifetime_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct rtadv_rdnss *p;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ p = nb_running_get_entry(args->dnode, NULL, true);
+
+ p->lifetime_set = 0;
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/dnssl/dnssl-domain
+ */
+int lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_create(
+ struct nb_cb_create_args *args)
+{
+ struct interface *ifp;
+ struct rtadv_dnssl dnssl = {0}, *p;
+ int ret;
+
+ strlcpy(dnssl.name, yang_dnode_get_string(args->dnode, "domain"),
+ sizeof(dnssl.name));
+ ret = rtadv_dnssl_encode(dnssl.encoded_name, dnssl.name);
+
+ if (args->event == NB_EV_VALIDATE) {
+ if (ret < 0) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "Malformed DNS search domain");
return NB_ERR_VALIDATION;
}
- if (zvrf->l3vni && zvrf->l3vni != vni) {
- snprintf(
- args->errmsg, args->errmsg_len,
- "vni %u cannot be configured as vni %u is already configured under the vrf",
- vni, zvrf->l3vni);
+ }
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+
+ if (yang_dnode_exists(args->dnode, "lifetime")) {
+ dnssl.lifetime = yang_dnode_get_uint32(args->dnode, "lifetime");
+ dnssl.lifetime_set = 1;
+ } else {
+ dnssl.lifetime_set = 0;
+ }
+
+ p = rtadv_dnssl_set(ifp->info, &dnssl);
+ nb_running_set_entry(args->dnode, p);
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct interface *ifp;
+ struct rtadv_dnssl *p;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ p = nb_running_unset_entry(args->dnode);
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+
+ rtadv_dnssl_reset(ifp->info, p);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/dnssl/dnssl-domain/lifetime
+ */
+int lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_lifetime_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct rtadv_dnssl *p;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ p = nb_running_get_entry(args->dnode, NULL, true);
+
+ p->lifetime = yang_dnode_get_uint32(args->dnode, NULL);
+ p->lifetime_set = 1;
+
+ return NB_OK;
+}
+
+int lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_lifetime_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct rtadv_dnssl *p;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ p = nb_running_get_entry(args->dnode, NULL, true);
+
+ p->lifetime_set = 0;
+
+ return NB_OK;
+}
+#endif /* defined(HAVE_RTADV) */
+
+#if HAVE_BFDD == 0
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ptm-enable
+ */
+int lib_interface_zebra_ptm_enable_modify(struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ bool ptm;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+
+ ptm = yang_dnode_get_bool(args->dnode, NULL);
+ if (ptm)
+ zebra_if_ptm_enable(ifp);
+ else
+ zebra_if_ptm_disable(ifp);
+
+ return NB_OK;
+}
+#endif
+
+/*
+ * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/router-id
+ */
+int lib_vrf_zebra_router_id_modify(struct nb_cb_modify_args *args)
+{
+ struct vrf *vrf;
+ struct prefix p;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+
+ yang_dnode_get_ipv4p(&p, args->dnode, NULL);
+
+ router_id_set(AFI_IP, &p, vrf->info);
+
+ return NB_OK;
+}
+
+int lib_vrf_zebra_router_id_destroy(struct nb_cb_destroy_args *args)
+{
+ struct vrf *vrf;
+ struct prefix p;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+
+ memset(&p, 0, sizeof(p));
+ p.family = AF_INET;
+
+ router_id_set(AFI_IP, &p, vrf->info);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ipv6-router-id
+ */
+int lib_vrf_zebra_ipv6_router_id_modify(struct nb_cb_modify_args *args)
+{
+ struct vrf *vrf;
+ struct prefix p;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+
+ yang_dnode_get_ipv6p(&p, args->dnode, NULL);
+
+ router_id_set(AFI_IP6, &p, vrf->info);
+
+ return NB_OK;
+}
+
+int lib_vrf_zebra_ipv6_router_id_destroy(struct nb_cb_destroy_args *args)
+{
+ struct vrf *vrf;
+ struct prefix p;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+
+ memset(&p, 0, sizeof(p));
+ p.family = AF_INET6;
+
+ router_id_set(AFI_IP6, &p, vrf->info);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/filter-protocol
+ */
+int lib_vrf_zebra_filter_protocol_create(struct nb_cb_create_args *args)
+{
+ const char *proto = yang_dnode_get_string(args->dnode, "protocol");
+ int rtype;
+
+ if (strcasecmp(proto, "any") == 0)
+ rtype = ZEBRA_ROUTE_MAX;
+ else
+ rtype = proto_name2num(proto);
+
+ if (args->event == NB_EV_VALIDATE)
+ if (rtype < 0) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "invalid protocol name \"%s\"", proto);
return NB_ERR_VALIDATION;
}
- /* Check if this VNI is already present in the system */
- zl3vni = zl3vni_lookup(vni);
- if (zl3vni) {
- snprintf(args->errmsg, args->errmsg_len,
- "VNI %u is already configured as L3-VNI", vni);
+ /* the creation finishes in the apply_finish callback */
+
+ return NB_OK;
+}
+
+int lib_vrf_zebra_filter_protocol_destroy(struct nb_cb_destroy_args *args)
+{
+ struct vrf *vrf;
+ const char *afi_safi = yang_dnode_get_string(args->dnode, "afi-safi");
+ const char *proto = yang_dnode_get_string(args->dnode, "protocol");
+ const char *rmap = yang_dnode_get_string(args->dnode, "route-map");
+ afi_t afi;
+ safi_t safi;
+ int rtype;
+
+ yang_afi_safi_identity2value(afi_safi, &afi, &safi);
+
+ if (strcasecmp(proto, "any") == 0)
+ rtype = ZEBRA_ROUTE_MAX;
+ else
+ rtype = proto_name2num(proto);
+
+ /* deleting an existing entry, it can't be invalid */
+ assert(rtype >= 0);
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+
+ ip_protocol_rm_del(vrf->info, rmap, rtype, afi, safi);
+
+ return NB_OK;
+}
+
+void lib_vrf_zebra_filter_protocol_apply_finish(
+ struct nb_cb_apply_finish_args *args)
+{
+ struct vrf *vrf;
+ const char *afi_safi = yang_dnode_get_string(args->dnode, "afi-safi");
+ const char *proto = yang_dnode_get_string(args->dnode, "protocol");
+ const char *rmap = yang_dnode_get_string(args->dnode, "route-map");
+ afi_t afi;
+ safi_t safi;
+ int rtype;
+
+ yang_afi_safi_identity2value(afi_safi, &afi, &safi);
+
+ if (strcasecmp(proto, "any") == 0)
+ rtype = ZEBRA_ROUTE_MAX;
+ else
+ rtype = proto_name2num(proto);
+
+ /* finishing apply for a validated entry, it can't be invalid */
+ assert(rtype >= 0);
+
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+
+ ip_protocol_rm_add(vrf->info, rmap, rtype, afi, safi);
+}
+
+/*
+ * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/filter-protocol/route-map
+ */
+int lib_vrf_zebra_filter_protocol_route_map_modify(struct nb_cb_modify_args *args)
+{
+ /* the update is done in the apply_finish callback */
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/filter-nht
+ */
+int lib_vrf_zebra_filter_nht_create(struct nb_cb_create_args *args)
+{
+ const char *afi_safi = yang_dnode_get_string(args->dnode, "afi-safi");
+ const char *proto = yang_dnode_get_string(args->dnode, "protocol");
+ afi_t afi;
+ safi_t safi;
+ int rtype;
+
+ yang_afi_safi_identity2value(afi_safi, &afi, &safi);
+
+ if (strcasecmp(proto, "any") == 0)
+ rtype = ZEBRA_ROUTE_MAX;
+ else
+ rtype = proto_name2num(proto);
+
+ if (args->event == NB_EV_VALIDATE) {
+ if (rtype < 0) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "invalid protocol name \"%s\"", proto);
+ return NB_ERR_VALIDATION;
+ }
+ if (safi != SAFI_UNICAST) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "only SAFI unicast is supported");
+ return NB_ERR_VALIDATION;
+ }
+ }
+
+ /* the creation finishes in the apply_finish callback */
+
+ return NB_OK;
+}
+
+int lib_vrf_zebra_filter_nht_destroy(struct nb_cb_destroy_args *args)
+{
+ struct vrf *vrf;
+ const char *afi_safi = yang_dnode_get_string(args->dnode, "afi-safi");
+ const char *proto = yang_dnode_get_string(args->dnode, "protocol");
+ const char *rmap = yang_dnode_get_string(args->dnode, "route-map");
+ afi_t afi;
+ safi_t safi;
+ int rtype;
+
+ yang_afi_safi_identity2value(afi_safi, &afi, &safi);
+
+ if (strcasecmp(proto, "any") == 0)
+ rtype = ZEBRA_ROUTE_MAX;
+ else
+ rtype = proto_name2num(proto);
+
+ /* deleting an existing entry, it can't be invalid */
+ assert(rtype >= 0);
+ assert(safi == SAFI_UNICAST);
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+
+ ip_nht_rm_del(vrf->info, rmap, rtype, afi);
+
+ return NB_OK;
+}
+
+void lib_vrf_zebra_filter_nht_apply_finish(struct nb_cb_apply_finish_args *args)
+{
+ struct vrf *vrf;
+ const char *afi_safi = yang_dnode_get_string(args->dnode, "afi-safi");
+ const char *proto = yang_dnode_get_string(args->dnode, "protocol");
+ const char *rmap = yang_dnode_get_string(args->dnode, "route-map");
+ afi_t afi;
+ safi_t safi;
+ int rtype;
+
+ yang_afi_safi_identity2value(afi_safi, &afi, &safi);
+
+ if (strcasecmp(proto, "any") == 0)
+ rtype = ZEBRA_ROUTE_MAX;
+ else
+ rtype = proto_name2num(proto);
+
+ /* finishing apply for an existing entry, it can't be invalid */
+ assert(rtype >= 0);
+ assert(safi == SAFI_UNICAST);
+
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+
+ ip_nht_rm_add(vrf->info, rmap, rtype, afi);
+}
+
+/*
+ * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/filter-nht/route-map
+ */
+int lib_vrf_zebra_filter_nht_route_map_modify(struct nb_cb_modify_args *args)
+{
+ /* the update is done in the apply_finish callback */
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/resolve-via-default
+ */
+int lib_vrf_zebra_resolve_via_default_modify(struct nb_cb_modify_args *args)
+{
+ struct vrf *vrf;
+ struct zebra_vrf *zvrf;
+ bool resolve_via_default;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ zvrf = vrf->info;
+
+ resolve_via_default = yang_dnode_get_bool(args->dnode, NULL);
+
+ if (zvrf->zebra_rnh_ip_default_route == resolve_via_default)
+ return NB_OK;
+
+ zvrf->zebra_rnh_ip_default_route = resolve_via_default;
+
+ zebra_evaluate_rnh(zvrf, AFI_IP, 0, NULL, SAFI_UNICAST);
+
+ return NB_OK;
+}
+
+int lib_vrf_zebra_resolve_via_default_destroy(struct nb_cb_destroy_args *args)
+{
+ struct vrf *vrf;
+ struct zebra_vrf *zvrf;
+ bool resolve_via_default;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ zvrf = vrf->info;
+
+ resolve_via_default = DFLT_ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT;
+
+ if (zvrf->zebra_rnh_ip_default_route == resolve_via_default)
+ return NB_OK;
+
+ zvrf->zebra_rnh_ip_default_route = resolve_via_default;
+
+ zebra_evaluate_rnh(zvrf, AFI_IP, 0, NULL, SAFI_UNICAST);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ipv6-resolve-via-default
+ */
+int lib_vrf_zebra_ipv6_resolve_via_default_modify(struct nb_cb_modify_args *args)
+{
+ struct vrf *vrf;
+ struct zebra_vrf *zvrf;
+ bool resolve_via_default;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ zvrf = vrf->info;
+
+ resolve_via_default = yang_dnode_get_bool(args->dnode, NULL);
+
+ if (zvrf->zebra_rnh_ipv6_default_route == resolve_via_default)
+ return NB_OK;
+
+ zvrf->zebra_rnh_ipv6_default_route = resolve_via_default;
+
+ zebra_evaluate_rnh(zvrf, AFI_IP6, 0, NULL, SAFI_UNICAST);
+
+ return NB_OK;
+}
+
+int lib_vrf_zebra_ipv6_resolve_via_default_destroy(struct nb_cb_destroy_args *args)
+{
+ struct vrf *vrf;
+ struct zebra_vrf *zvrf;
+ bool resolve_via_default;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ zvrf = vrf->info;
+
+ resolve_via_default = DFLT_ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT;
+
+ if (zvrf->zebra_rnh_ipv6_default_route == resolve_via_default)
+ return NB_OK;
+
+ zvrf->zebra_rnh_ipv6_default_route = resolve_via_default;
+
+ zebra_evaluate_rnh(zvrf, AFI_IP6, 0, NULL, SAFI_UNICAST);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/netns/table-range
+ */
+static int table_range_validate(uint32_t start, uint32_t end, char *errmsg,
+ size_t errmsg_len)
+{
+#if defined(GNU_LINUX)
+ if ((start >= RT_TABLE_ID_COMPAT && start <= RT_TABLE_ID_LOCAL) ||
+ (end >= RT_TABLE_ID_COMPAT && end <= RT_TABLE_ID_LOCAL)) {
+ snprintfrr(errmsg, errmsg_len,
+ "Values forbidden in range [%u;%u]",
+ RT_TABLE_ID_COMPAT, RT_TABLE_ID_LOCAL);
+ return NB_ERR_VALIDATION;
+ }
+ if (start < RT_TABLE_ID_COMPAT && end > RT_TABLE_ID_LOCAL) {
+ snprintfrr(errmsg, errmsg_len,
+ "Range overlaps range [%u;%u] forbidden",
+ RT_TABLE_ID_COMPAT, RT_TABLE_ID_LOCAL);
+ return NB_ERR_VALIDATION;
+ }
+#endif
+ return NB_OK;
+}
+
+int lib_vrf_zebra_netns_table_range_create(struct nb_cb_create_args *args)
+{
+ struct vrf *vrf;
+ uint32_t start, end;
+ const char *vrf_name;
+
+ start = yang_dnode_get_uint32(args->dnode, "start");
+ end = yang_dnode_get_uint32(args->dnode, "end");
+
+ if (args->event == NB_EV_VALIDATE) {
+ vrf_name = yang_dnode_get_string(args->dnode, "../../../name");
+ if (!vrf_is_backend_netns() &&
+ strcmp(vrf_name, VRF_DEFAULT_NAME)) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "Configuration is not available in non-default VRFs when using VRF-lite backend.");
return NB_ERR_VALIDATION;
}
+ return table_range_validate(start, end, args->errmsg,
+ args->errmsg_len);
+ }
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+
+ table_manager_range(true, vrf->info, start, end);
+
+ return NB_OK;
+}
+
+int lib_vrf_zebra_netns_table_range_destroy(struct nb_cb_destroy_args *args)
+{
+ struct vrf *vrf;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+
+ table_manager_range(false, vrf->info, 0, 0);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/netns/table-range/start
+ */
+int lib_vrf_zebra_netns_table_range_start_modify(struct nb_cb_modify_args *args)
+{
+ struct vrf *vrf;
+ uint32_t start, end;
+
+ start = yang_dnode_get_uint32(args->dnode, NULL);
+ end = yang_dnode_get_uint32(args->dnode, "../end");
+
+ if (args->event == NB_EV_VALIDATE)
+ return table_range_validate(start, end, args->errmsg,
+ args->errmsg_len);
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+
+ table_manager_range(true, vrf->info, start, end);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/netns/table-range/end
+ */
+int lib_vrf_zebra_netns_table_range_end_modify(struct nb_cb_modify_args *args)
+{
+ struct vrf *vrf;
+ uint32_t start, end;
+
+ start = yang_dnode_get_uint32(args->dnode, "../start");
+ end = yang_dnode_get_uint32(args->dnode, NULL);
+
+ if (args->event == NB_EV_VALIDATE)
+ return table_range_validate(start, end, args->errmsg,
+ args->errmsg_len);
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+
+ table_manager_range(true, vrf->info, start, end);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/l3vni-id
+ */
+int lib_vrf_zebra_l3vni_id_modify(struct nb_cb_modify_args *args)
+{
+ struct vrf *vrf;
+ vni_t vni = 0;
+ bool pfx_only = false;
+ uint32_t count;
+
+ vni = yang_dnode_get_uint32(args->dnode, NULL);
+
+ switch (args->event) {
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ return NB_OK;
+ case NB_EV_VALIDATE:
+ count = yang_dnode_count(args->dnode,
+ "/frr-vrf:lib/vrf/frr-zebra:zebra[l3vni-id='%u']",
+ vni);
+ if (count > 1) {
+ snprintfrr(args->errmsg, args->errmsg_len,
+ "vni %u is already mapped to another vrf",
+ vni);
+ return NB_ERR_VALIDATION;
+ }
break;
case NB_EV_APPLY:
-
vrf = nb_running_get_entry(args->dnode, NULL, true);
- zvrf = zebra_vrf_lookup_by_name(vrf->name);
- vni = yang_dnode_get_uint32(args->dnode, NULL);
- /* Note: This covers lib_vrf_zebra_prefix_only_modify() config
- * along with l3vni config
- */
pfx_only = yang_dnode_get_bool(args->dnode, "../prefix-only");
- if (zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
- pfx_only ? 1 : 0, 1)
- != 0) {
- if (IS_ZEBRA_DEBUG_VXLAN)
- snprintf(
- args->errmsg, args->errmsg_len,
- "vrf vni %u mapping failed with error: %s",
- vni, err);
- return NB_ERR;
- }
-
+ zebra_vxlan_process_vrf_vni_cmd(vrf->info, vni,
+ pfx_only ? 1 : 0, 1);
break;
}
@@ -1520,10 +3821,7 @@ int lib_vrf_zebra_l3vni_id_modify(struct nb_cb_modify_args *args)
int lib_vrf_zebra_l3vni_id_destroy(struct nb_cb_destroy_args *args)
{
struct vrf *vrf;
- struct zebra_vrf *zvrf;
vni_t vni = 0;
- char err[ERR_STR_SZ];
- uint8_t filter = 0;
switch (args->event) {
case NB_EV_PREPARE:
@@ -1532,32 +3830,9 @@ int lib_vrf_zebra_l3vni_id_destroy(struct nb_cb_destroy_args *args)
return NB_OK;
case NB_EV_APPLY:
vrf = nb_running_get_entry(args->dnode, NULL, true);
- zvrf = zebra_vrf_lookup_by_name(vrf->name);
vni = yang_dnode_get_uint32(args->dnode, NULL);
- if (!zl3vni_lookup(vni))
- return NB_OK;
-
- if (zvrf->l3vni != vni) {
- snprintf(args->errmsg, args->errmsg_len,
- "vrf %s has different vni %u mapped",
- vrf->name, zvrf->l3vni);
- return NB_ERR;
- }
-
- if (is_l3vni_for_prefix_routes_only(zvrf->l3vni))
- filter = 1;
-
- if (zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
- filter, 0)
- != 0) {
- if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug(
- "vrf vni %u unmapping failed with error: %s",
- vni, err);
- return NB_ERR;
- }
-
+ zebra_vxlan_process_vrf_vni_cmd(vrf->info, vni, 0, 0);
break;
}