// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2019 Cumulus Networks, Inc. * Chirag Shah */ #include #include "lib/admin_group.h" #include "lib/affinitymap.h" #include "lib/log.h" #include "lib/northbound.h" #include "lib/printfrr.h" #include "libfrr.h" #include "lib/command.h" #include "lib/routemap.h" #include "zebra/zebra_nb.h" #include "zebra/rib.h" #include "zebra_nb.h" #include "zebra/interface.h" #include "zebra/connected.h" #include "zebra/zebra_router.h" #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 */ int zebra_mcast_rpf_lookup_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/ip-forwarding */ int zebra_ip_forwarding_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_ip_forwarding_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/ipv6-forwarding */ int zebra_ipv6_forwarding_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_ipv6_forwarding_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/workqueue-hold-timer */ int zebra_workqueue_hold_timer_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/zapi-packets */ int zebra_zapi_packets_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/import-kernel-table/table-id */ int zebra_import_kernel_table_table_id_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_import_kernel_table_table_id_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/import-kernel-table/distance */ int zebra_import_kernel_table_distance_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/import-kernel-table/route-map */ int zebra_import_kernel_table_route_map_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_import_kernel_table_route_map_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/allow-external-route-update */ int zebra_allow_external_route_update_create(struct nb_cb_create_args *args) { switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: case NB_EV_APPLY: /* TODO: implement me. */ break; } return NB_OK; } int zebra_allow_external_route_update_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/dplane-queue-limit */ int zebra_dplane_queue_limit_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: /* TODO: implement me. */ break; } 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 */ int zebra_debugs_debug_events_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_events_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-zapi-send */ int zebra_debugs_debug_zapi_send_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_zapi_send_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-zapi-recv */ int zebra_debugs_debug_zapi_recv_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_zapi_recv_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-zapi-detail */ int zebra_debugs_debug_zapi_detail_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_zapi_detail_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-kernel */ int zebra_debugs_debug_kernel_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_kernel_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-kernel-msg-send */ int zebra_debugs_debug_kernel_msg_send_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_kernel_msg_send_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-kernel-msg-recv */ int zebra_debugs_debug_kernel_msg_recv_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_kernel_msg_recv_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-rib */ int zebra_debugs_debug_rib_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_rib_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-rib-detail */ int zebra_debugs_debug_rib_detail_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_rib_detail_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-fpm */ int zebra_debugs_debug_fpm_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_fpm_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-nht */ int zebra_debugs_debug_nht_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_nht_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-nht-detail */ int zebra_debugs_debug_nht_detail_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_nht_detail_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-mpls */ int zebra_debugs_debug_mpls_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_mpls_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-vxlan */ int zebra_debugs_debug_vxlan_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_vxlan_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-pw */ int zebra_debugs_debug_pw_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_pw_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-dplane */ int zebra_debugs_debug_dplane_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_dplane_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-dplane-detail */ int zebra_debugs_debug_dplane_detail_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_dplane_detail_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-zebra:zebra/debugs/debug-mlag */ int zebra_debugs_debug_mlag_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: /* TODO: implement me. */ break; } return NB_OK; } int zebra_debugs_debug_mlag_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: /* TODO: implement me. */ break; } return NB_OK; } /* * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv4-addrs */ int lib_interface_zebra_ipv4_addrs_create(struct nb_cb_create_args *args) { struct interface *ifp; 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"); 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; case NB_EV_PREPARE: case NB_EV_ABORT: break; case NB_EV_APPLY: ifp = nb_running_get_entry(args->dnode, NULL, true); 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_ipv4_addrs_destroy(struct nb_cb_destroy_args *args) { struct interface *ifp; struct prefix p; 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_ip_address_uninstall(ifp, &p, NULL); break; } return NB_OK; } /* * 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, "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; } 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; case NB_EV_PREPARE: case NB_EV_ABORT: break; case NB_EV_APPLY: ifp = nb_running_get_entry(args->dnode, NULL, true); 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; } return NB_OK; } /* * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv4-p2p-addrs/label */ 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: break; } return NB_OK; } 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: break; } return NB_OK; } /* * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-addrs */ 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: ifp = nb_running_get_entry(args->dnode, NULL, true); if_ipv6_address_install(ifp, &p); break; } return NB_OK; } 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: ifp = nb_running_get_entry(args->dnode, NULL, false); if_ipv6_address_uninstall(ifp, &p); break; } return NB_OK; } /* * XPath: /frr-interface:lib/interface/frr-zebra:zebra/multicast */ int lib_interface_zebra_multicast_modify(struct nb_cb_modify_args *args) { if (args->event != NB_EV_APPLY) 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) if_multicast_set(ifp); else if_multicast_unset(ifp); return NB_OK; } int lib_interface_zebra_multicast_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; zif->multicast = IF_ZEBRA_DATA_UNSPEC; return NB_OK; } /* * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-detect */ int lib_interface_zebra_link_detect_modify(struct nb_cb_modify_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, NULL); if_linkdetect(ifp, link_detect); return NB_OK; } /* * XPath: /frr-interface:lib/interface/frr-zebra:zebra/enabled */ 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 (enabled) if_no_shutdown(ifp); else if_shutdown(ifp); return NB_OK; } 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; zif->shutdown = IF_ZEBRA_DATA_UNSPEC; return NB_OK; } /* * XPath: /frr-interface:lib/interface/frr-zebra:zebra/mpls */ int lib_interface_zebra_mpls_modify(struct nb_cb_modify_args *args) { struct interface *ifp; bool mpls; 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; mpls = yang_dnode_get_bool(args->dnode, NULL); if (mpls) zif->mpls_config = IF_ZEBRA_DATA_ON; else zif->mpls_config = IF_ZEBRA_DATA_OFF; dplane_intf_mpls_modify_state(ifp, mpls); return NB_OK; } int lib_interface_zebra_mpls_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->mpls_config = IF_ZEBRA_DATA_UNSPEC; /* keep the state as it is */ return NB_OK; } /* * XPath: /frr-interface:lib/interface/frr-zebra:zebra/bandwidth */ int lib_interface_zebra_bandwidth_modify(struct nb_cb_modify_args *args) { if (args->event != NB_EV_APPLY) return NB_OK; struct interface *ifp; uint32_t bandwidth; ifp = nb_running_get_entry(args->dnode, NULL, true); bandwidth = yang_dnode_get_uint32(args->dnode, NULL); ifp->bandwidth = bandwidth; /* force protocols to recalculate routes due to cost change */ if (if_is_operative(ifp)) zebra_interface_up_update(ifp); return NB_OK; } int lib_interface_zebra_bandwidth_destroy(struct nb_cb_destroy_args *args) { if (args->event != NB_EV_APPLY) return NB_OK; struct interface *ifp; ifp = nb_running_get_entry(args->dnode, NULL, true); ifp->bandwidth = 0; /* force protocols to recalculate routes due to cost change */ if (if_is_operative(ifp)) zebra_interface_up_update(ifp); return NB_OK; } /* * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params */ 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; 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); 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 (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: 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; } 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; ava_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 < 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_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); return NB_OK; } /* * 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: 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 = 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); break; } return NB_OK; } /* * 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) { struct interface *ifp; const char *affname; struct if_link_params *iflp; struct affinity_map *affmap; enum affinity_mode affinity_mode; affname = yang_dnode_get_string(args->dnode, "."); affinity_mode = yang_dnode_get_enum(args->dnode, "../../affinity-mode"); 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); affmap = affinity_map_get(affname); if (affmap->bit_position < 32 && (affinity_mode == AFFINITY_MODE_STANDARD || affinity_mode == AFFINITY_MODE_BOTH)) { iflp->admin_grp |= 1 << affmap->bit_position; SET_PARAM(iflp, LP_ADM_GRP); } if (affinity_mode == AFFINITY_MODE_EXTENDED || affinity_mode == AFFINITY_MODE_BOTH) { admin_group_set(&iflp->ext_admin_grp, affmap->bit_position); SET_PARAM(iflp, LP_EXTEND_ADM_GRP); } break; } return NB_OK; } int lib_interface_zebra_affinity_destroy(struct nb_cb_destroy_args *args) { struct interface *ifp; const char *affname; struct if_link_params *iflp; struct affinity_map *affmap; enum affinity_mode affinity_mode; affname = yang_dnode_get_string(args->dnode, "."); affinity_mode = yang_dnode_get_enum(args->dnode, "../../affinity-mode"); 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); affmap = affinity_map_get(affname); if (affmap->bit_position < 32 && (affinity_mode == AFFINITY_MODE_STANDARD || affinity_mode == AFFINITY_MODE_BOTH)) { iflp->admin_grp &= ~(1 << affmap->bit_position); if (iflp->admin_grp == 0) UNSET_PARAM(iflp, LP_ADM_GRP); } if (affinity_mode == AFFINITY_MODE_EXTENDED || affinity_mode == AFFINITY_MODE_BOTH) { admin_group_unset(&iflp->ext_admin_grp, affmap->bit_position); if (admin_group_zero(&iflp->ext_admin_grp)) UNSET_PARAM(iflp, LP_EXTEND_ADM_GRP); } break; } return NB_OK; } /* * XPath: * /frr-interface:lib/interface/frr-zebra:zebra/link-params/affinity-mode */ int lib_interface_zebra_affinity_mode_modify(struct nb_cb_modify_args *args) { struct interface *ifp; struct if_link_params *iflp; enum affinity_mode affinity_mode; affinity_mode = yang_dnode_get_enum(args->dnode, "."); 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); if (affinity_mode == AFFINITY_MODE_STANDARD) { if (!IS_PARAM_SET(iflp, LP_ADM_GRP) && IS_PARAM_SET(iflp, LP_EXTEND_ADM_GRP)) { iflp->admin_grp = admin_group_get_offset( &iflp->ext_admin_grp, 0); SET_PARAM(iflp, LP_ADM_GRP); } admin_group_clear(&iflp->ext_admin_grp); UNSET_PARAM(iflp, LP_EXTEND_ADM_GRP); } if (affinity_mode == AFFINITY_MODE_EXTENDED) { if (!IS_PARAM_SET(iflp, LP_EXTEND_ADM_GRP) && IS_PARAM_SET(iflp, LP_ADM_GRP)) { admin_group_bulk_set(&iflp->ext_admin_grp, iflp->admin_grp, 0); SET_PARAM(iflp, LP_EXTEND_ADM_GRP); } iflp->admin_grp = 0; UNSET_PARAM(iflp, LP_ADM_GRP); } if (affinity_mode == AFFINITY_MODE_BOTH) { if (!IS_PARAM_SET(iflp, LP_EXTEND_ADM_GRP) && IS_PARAM_SET(iflp, LP_ADM_GRP)) { admin_group_bulk_set(&iflp->ext_admin_grp, iflp->admin_grp, 0); SET_PARAM(iflp, LP_EXTEND_ADM_GRP); } else if (!IS_PARAM_SET(iflp, LP_ADM_GRP) && IS_PARAM_SET(iflp, LP_EXTEND_ADM_GRP)) { iflp->admin_grp = admin_group_get_offset( &iflp->ext_admin_grp, 0); 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 (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-interface:lib/interface/frr-zebra:zebra/evpn-mh/type-3 */ int lib_interface_zebra_evpn_mh_type_3_create(struct nb_cb_create_args *args) { 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: 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); dnssl.encoded_len = ret; if (args->event == NB_EV_VALIDATE) { if (ret < 0) { snprintfrr(args->errmsg, args->errmsg_len, "Malformed DNS search domain"); return NB_ERR_VALIDATION; } } 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; } /* 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); pfx_only = yang_dnode_get_bool(args->dnode, "../prefix-only"); zebra_vxlan_process_vrf_vni_cmd(vrf->info, vni, pfx_only ? 1 : 0, 1); break; } return NB_OK; } int lib_vrf_zebra_l3vni_id_destroy(struct nb_cb_destroy_args *args) { struct vrf *vrf; vni_t vni = 0; switch (args->event) { case NB_EV_PREPARE: case NB_EV_ABORT: case NB_EV_VALIDATE: return NB_OK; case NB_EV_APPLY: vrf = nb_running_get_entry(args->dnode, NULL, true); vni = yang_dnode_get_uint32(args->dnode, NULL); zebra_vxlan_process_vrf_vni_cmd(vrf->info, vni, 0, 0); break; } return NB_OK; } /* * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/prefix-only */ int lib_vrf_zebra_prefix_only_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: /* TODO: implement me. */ break; } return NB_OK; }