diff options
Diffstat (limited to 'zebra/zebra_nb_config.c')
| -rw-r--r-- | zebra/zebra_nb_config.c | 271 | 
1 files changed, 271 insertions, 0 deletions
diff --git a/zebra/zebra_nb_config.c b/zebra/zebra_nb_config.c index dfb55b0d6d..f68ecc3076 100644 --- a/zebra/zebra_nb_config.c +++ b/zebra/zebra_nb_config.c @@ -19,6 +19,8 @@  #include <zebra.h> +#include "lib/admin_group.h" +#include "lib/affinitymap.h"  #include "lib/log.h"  #include "lib/northbound.h"  #include "lib/printfrr.h" @@ -1140,6 +1142,275 @@ 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 + */ +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; + +	ifp = nb_running_get_entry(args->dnode, NULL, true); +	admin_group_value = yang_dnode_get_uint32(args->dnode, "."); + +	if (!ifp) +		return NB_ERR_RESOURCE; + +	iflp = if_link_params_get(ifp); + +	switch (args->event) { +	case NB_EV_VALIDATE: +	case NB_EV_PREPARE: +	case NB_EV_ABORT: +		break; +	case NB_EV_APPLY: +		if (!iflp) +			iflp = if_link_params_enable(ifp); + +		iflp->admin_grp = admin_group_value; +		SET_PARAM(iflp, LP_ADM_GRP); + +		admin_group_clear(&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; +} + +int lib_interface_zebra_legacy_admin_group_destroy( +	struct nb_cb_destroy_args *args) +{ +	struct interface *ifp; +	struct if_link_params *iflp; + +	ifp = nb_running_get_entry(args->dnode, NULL, true); + +	if (!ifp) +		return NB_ERR_RESOURCE; + +	iflp = if_link_params_get(ifp); + +	switch (args->event) { +	case NB_EV_VALIDATE: +	case NB_EV_PREPARE: +	case NB_EV_ABORT: +		break; +	case NB_EV_APPLY: +		if (!iflp) +			iflp = if_link_params_enable(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; +} + +/* + * 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; + + +	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); + +		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); +		} + +		if (if_is_operative(ifp)) +			zebra_interface_parameters_update(ifp); +		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; + +	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; +		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); +		} + +		if (if_is_operative(ifp)) +			zebra_interface_parameters_update(ifp); +		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; + + +	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); +		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); +			} +		} + +		if (if_is_operative(ifp)) +			zebra_interface_parameters_update(ifp); +		break; +	} +	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)  | 
