summaryrefslogtreecommitdiff
path: root/zebra/zebra_nb_config.c
diff options
context:
space:
mode:
authorLouis Scalbert <louis.scalbert@6wind.com>2022-11-08 17:59:33 +0100
committerLouis Scalbert <louis.scalbert@6wind.com>2023-02-10 11:31:05 +0100
commit158332617d80fc24bad4e8590bcf19b4af19404e (patch)
treefe55b77056a95a41e115316adfb8a98aa5b930a0 /zebra/zebra_nb_config.c
parentc86a325285f66a5a43a4097a373c890ad4703e87 (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.c271
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)