diff options
| author | Louis Scalbert <louis.scalbert@6wind.com> | 2022-11-08 17:59:33 +0100 | 
|---|---|---|
| committer | Louis Scalbert <louis.scalbert@6wind.com> | 2023-02-10 11:31:05 +0100 | 
| commit | 158332617d80fc24bad4e8590bcf19b4af19404e (patch) | |
| tree | fe55b77056a95a41e115316adfb8a98aa5b930a0 /zebra/zebra_nb_config.c | |
| parent | c86a325285f66a5a43a4097a373c890ad4703e87 (diff) | |
lib,yang,zebra: add extended admin-group support
Add the support of Extended Admin-Group (RFC7308) to the zebra interface
link-params Traffic-Engineering context.
Extended admin-groups can be configured with the affinity-map:
> affinity-map blue bit-position 221
> int eth-rt1
>  link-params
>   affinity blue
>  exit-link-params
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
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)  | 
