diff --git a/proto/context.proto b/proto/context.proto
index 4d61572df1db6c95b64e9ce1cbfdd9e0db111078..01e096233e364be8ad4e3810e7619e8f522e66e6 100644
--- a/proto/context.proto
+++ b/proto/context.proto
@@ -223,6 +223,9 @@ enum DeviceDriverEnum {
   DEVICEDRIVER_IETF_ACTN = 10;
   DEVICEDRIVER_OC = 11;
   DEVICEDRIVER_QKD = 12;
+  DEVICEDRIVER_IETF_L3VPN = 13;
+  DEVICEDRIVER_IETF_SLICE = 14;
+  DEVICEDRIVER_NCE = 15;
 }
 
 enum DeviceOperationalStatusEnum {
diff --git a/scripts/run_tests_locally-nbi-ietf-slice.sh b/scripts/run_tests_locally-nbi-ietf-slice.sh
new file mode 100755
index 0000000000000000000000000000000000000000..bf53f18b9a37f9248b072ae2c699b5874fa2c869
--- /dev/null
+++ b/scripts/run_tests_locally-nbi-ietf-slice.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+
+# Run unitary tests and analyze coverage of code at same time
+# helpful pytest flags: --log-level=INFO -o log_cli=true --verbose --maxfail=1 --durations=0
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    nbi/tests/test_slice_2.py
diff --git a/src/common/DeviceTypes.py b/src/common/DeviceTypes.py
index eb315352b47bbe501f66868c0181a0d34cd6cfed..9a982d1eb71e8b139d2a86fe1a774154239c7147 100644
--- a/src/common/DeviceTypes.py
+++ b/src/common/DeviceTypes.py
@@ -38,6 +38,7 @@ class DeviceTypeEnum(Enum):
     CLIENT                          = 'client'
     DATACENTER                      = 'datacenter'
     IP_SDN_CONTROLLER               = 'ip-sdn-controller'
+    NCE                             = 'nce'
     MICROWAVE_RADIO_SYSTEM          = 'microwave-radio-system'
     OPEN_LINE_SYSTEM                = 'open-line-system'
     OPTICAL_ROADM                   = 'optical-roadm'
@@ -52,3 +53,4 @@ class DeviceTypeEnum(Enum):
 
     # ETSI TeraFlowSDN controller
     TERAFLOWSDN_CONTROLLER          = 'teraflowsdn'
+    IETF_SLICE                      = 'ietf-slice'
diff --git a/src/common/tools/context_queries/Slice.py b/src/common/tools/context_queries/Slice.py
index c826c59ce79adbe1e399d674ffd46a421ddd9b5e..12bd8c03c68ab0baea5b4db91b7468e2eae7f1a9 100644
--- a/src/common/tools/context_queries/Slice.py
+++ b/src/common/tools/context_queries/Slice.py
@@ -12,12 +12,20 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import grpc, logging
-from typing import Optional
+import logging
+import grpc
+from typing import Optional, Tuple, Union
+from uuid import UUID, uuid5
 from common.Constants import DEFAULT_CONTEXT_NAME
-from common.proto.context_pb2 import Slice, SliceFilter, SliceId
+from common.method_wrappers.ServiceExceptions import InvalidArgumentsException
+from common.proto.context_pb2 import ContextId, Slice, SliceFilter, SliceId
+from common.method_wrappers.ServiceExceptions import InvalidArgumentsException
+from common.proto.context_pb2 import ContextId, Slice, SliceFilter, SliceId
 from context.client.ContextClient import ContextClient
 
+
+NAMESPACE_TFS = UUID("200e3a1f-2223-534f-a100-758e29c37f40")
+
 LOGGER = logging.getLogger(__name__)
 
 def get_slice_by_id(
@@ -59,3 +67,96 @@ def get_slice_by_uuid(
         context_client, slice_id, rw_copy=rw_copy, include_endpoint_ids=include_endpoint_ids,
         include_constraints=include_constraints, include_service_ids=include_service_ids,
         include_subslice_ids=include_subslice_ids, include_config_rules=include_config_rules)
+
+
+def get_uuid_from_string(
+    str_uuid_or_name: Union[str, UUID], prefix_for_name: Optional[str] = None
+) -> str:
+    # if UUID given, assume it is already a valid UUID
+    if isinstance(str_uuid_or_name, UUID):
+        return str_uuid_or_name
+    if not isinstance(str_uuid_or_name, str):
+        MSG = "Parameter({:s}) cannot be used to produce a UUID"
+        raise Exception(MSG.format(str(repr(str_uuid_or_name))))
+    try:
+        # try to parse as UUID
+        return str(UUID(str_uuid_or_name))
+    except:  # pylint: disable=bare-except
+        # produce a UUID within TFS namespace from parameter
+        if prefix_for_name is not None:
+            str_uuid_or_name = "{:s}/{:s}".format(prefix_for_name, str_uuid_or_name)
+        return str(uuid5(NAMESPACE_TFS, str_uuid_or_name))
+
+
+def context_get_uuid(
+    context_id: ContextId,
+    context_name: str = "",
+    allow_random: bool = False,
+    allow_default: bool = False,
+) -> str:
+    context_uuid = context_id.context_uuid.uuid
+
+    if len(context_uuid) > 0:
+        return get_uuid_from_string(context_uuid)
+    if len(context_name) > 0:
+        return get_uuid_from_string(context_name)
+    if allow_default:
+        return get_uuid_from_string(DEFAULT_CONTEXT_NAME)
+
+    raise InvalidArgumentsException(
+        [
+            ("context_id.context_uuid.uuid", context_uuid),
+            ("name", context_name),
+        ],
+        extra_details=["At least one is required to produce a Context UUID"],
+    )
+
+
+def slice_get_uuid(slice_id: SliceId) -> Tuple[str, str]:
+    context_uuid = context_get_uuid(slice_id.context_id, allow_random=False)
+    raw_slice_uuid = slice_id.slice_uuid.uuid
+
+    if len(raw_slice_uuid) > 0:
+        return context_uuid, get_uuid_from_string(
+            raw_slice_uuid, prefix_for_name=context_uuid
+        )
+
+    raise InvalidArgumentsException(
+        [
+            ("slice_id.slice_uuid.uuid", raw_slice_uuid),
+        ],
+        extra_details=["At least one is required to produce a Slice UUID"],
+    )
+
+def get_slice_by_defualt_id(
+    context_client : ContextClient, default_slice_id : SliceId, context_uuid : str = DEFAULT_CONTEXT_NAME,
+    rw_copy : bool = False, include_endpoint_ids : bool = True, include_constraints : bool = True,
+    include_service_ids : bool = True, include_subslice_ids : bool = True, include_config_rules : bool = True
+) -> Optional[Slice]:
+    context_uuid, slice_uuid = slice_get_uuid(default_slice_id)
+    LOGGER.debug(f'P60: {context_uuid} {slice_uuid}')
+    slice_id = SliceId()
+    slice_id.context_id.context_uuid.uuid = context_uuid    # pylint: disable=no-member
+    slice_id.slice_uuid.uuid = slice_uuid                   # pylint: disable=no-member
+    return get_slice_by_id(
+        context_client, slice_id, rw_copy=rw_copy, include_endpoint_ids=include_endpoint_ids,
+        include_constraints=include_constraints, include_service_ids=include_service_ids,
+        include_subslice_ids=include_subslice_ids, include_config_rules=include_config_rules)
+
+
+def get_slice_by_defualt_name(
+    context_client : ContextClient, slice_name : str, context_uuid : str = DEFAULT_CONTEXT_NAME,
+    rw_copy : bool = False, include_endpoint_ids : bool = True, include_constraints : bool = True,
+    include_service_ids : bool = True, include_subslice_ids : bool = True, include_config_rules : bool = True
+) -> Optional[Slice]:
+    default_slice_id = SliceId()
+    default_slice_id.context_id.context_uuid.uuid = context_uuid    # pylint: disable=no-member
+    default_slice_id.slice_uuid.uuid = slice_name                   # pylint: disable=no-member
+    context_uuid, slice_uuid = slice_get_uuid(default_slice_id)
+    slice_id = SliceId()
+    slice_id.context_id.context_uuid.uuid = context_uuid    # pylint: disable=no-member
+    slice_id.slice_uuid.uuid = slice_uuid                   # pylint: disable=no-member
+    return get_slice_by_id(
+        context_client, slice_id, rw_copy=rw_copy, include_endpoint_ids=include_endpoint_ids,
+        include_constraints=include_constraints, include_service_ids=include_service_ids,
+        include_subslice_ids=include_subslice_ids, include_config_rules=include_config_rules)
diff --git a/src/common/tools/descriptor/Tools.py b/src/common/tools/descriptor/Tools.py
index c8807cef0d1357c732d34b11580d1f73e157501a..2ecd38ae146f5c5e3a04a84ad3bb05385554f659 100644
--- a/src/common/tools/descriptor/Tools.py
+++ b/src/common/tools/descriptor/Tools.py
@@ -115,6 +115,8 @@ CONTROLLER_DEVICE_TYPES = {
     DeviceTypeEnum.MICROWAVE_RADIO_SYSTEM.value,
     DeviceTypeEnum.OPEN_LINE_SYSTEM.value,
     DeviceTypeEnum.TERAFLOWSDN_CONTROLLER.value,
+    DeviceTypeEnum.IETF_SLICE.value,
+    DeviceTypeEnum.NCE.value,
 }
 
 def split_controllers_and_network_devices(devices : List[Dict]) -> Tuple[List[Dict], List[Dict]]:
diff --git a/src/common/tools/grpc/ConfigRules.py b/src/common/tools/grpc/ConfigRules.py
index c8919273e65c6f6edb0f3e0ca6f060a5471e8f0e..0cf5165e9a15e1bcbaa4067db1e866ab01fbe33c 100644
--- a/src/common/tools/grpc/ConfigRules.py
+++ b/src/common/tools/grpc/ConfigRules.py
@@ -54,14 +54,13 @@ def update_config_rule_custom(
 
     config_rule.custom.resource_value = json.dumps(json_resource_value, sort_keys=True)
 
-def copy_config_rules(source_config_rules, target_config_rules):
+def copy_config_rules(source_config_rules, target_config_rules, raise_if_differs = True):
     for source_config_rule in source_config_rules:
         config_rule_kind = source_config_rule.WhichOneof('config_rule')
         if config_rule_kind == 'custom':
             custom = source_config_rule.custom
             resource_key = custom.resource_key
             resource_value = json.loads(custom.resource_value)
-            raise_if_differs = True
             fields = {name:(value, raise_if_differs) for name,value in resource_value.items()}
             update_config_rule_custom(target_config_rules, resource_key, fields)
 
diff --git a/src/context/service/database/models/enums/DeviceDriver.py b/src/context/service/database/models/enums/DeviceDriver.py
index 5342f788a7b273aa7f6ae3c5779774165cd852bc..fe0d83fb1886a42526b1c71304b7e3ecc2b0b7d7 100644
--- a/src/context/service/database/models/enums/DeviceDriver.py
+++ b/src/context/service/database/models/enums/DeviceDriver.py
@@ -33,6 +33,9 @@ class ORM_DeviceDriverEnum(enum.Enum):
     GNMI_OPENCONFIG       = DeviceDriverEnum.DEVICEDRIVER_GNMI_OPENCONFIG
     OPTICAL_TFS           = DeviceDriverEnum.DEVICEDRIVER_OPTICAL_TFS
     IETF_ACTN             = DeviceDriverEnum.DEVICEDRIVER_IETF_ACTN
+    IETF_L3VPN            = DeviceDriverEnum.DEVICEDRIVER_IETF_L3VPN
+    NCE                   = DeviceDriverEnum.DEVICEDRIVER_NCE
+    IETF_SLICE            = DeviceDriverEnum.DEVICEDRIVER_IETF_SLICE
     OC                    = DeviceDriverEnum.DEVICEDRIVER_OC
     QKD                   = DeviceDriverEnum.DEVICEDRIVER_QKD
 
diff --git a/src/device/service/drivers/__init__.py b/src/device/service/drivers/__init__.py
index b99ee50ca8319ab96f9062a3c58c356fa2ae7ec7..e3102cdf523a4e0b551873bb8f0c423db00aebf0 100644
--- a/src/device/service/drivers/__init__.py
+++ b/src/device/service/drivers/__init__.py
@@ -81,6 +81,16 @@ DRIVERS.append(
         }
     ]))
 
+
+from .ietf_l3vpn.driver import IetfL3VpnDriver # pylint: disable=wrong-import-position
+DRIVERS.append(
+    (IetfL3VpnDriver, [
+        {
+            FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.TERAFLOWSDN_CONTROLLER,
+            FilterFieldEnum.DRIVER: DeviceDriverEnum.DEVICEDRIVER_IETF_L3VPN,
+        }
+    ]))
+
 from .ietf_actn.IetfActnDriver import IetfActnDriver # pylint: disable=wrong-import-position
 DRIVERS.append(
     (IetfActnDriver, [
@@ -90,6 +100,24 @@ DRIVERS.append(
         }
     ]))
 
+from .ietf_slice.driver import IetfSliceDriver # pylint: disable=wrong-import-position
+DRIVERS.append(
+    (IetfSliceDriver, [
+        {
+            FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.IETF_SLICE,
+            FilterFieldEnum.DRIVER: DeviceDriverEnum.DEVICEDRIVER_IETF_SLICE,
+        }
+    ]))
+
+from .nce.driver import NCEDriver # pylint: disable=wrong-import-position
+DRIVERS.append(
+    (NCEDriver, [
+        {
+            FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.NCE,
+            FilterFieldEnum.DRIVER: DeviceDriverEnum.DEVICEDRIVER_NCE,
+        }
+    ]))
+
 if LOAD_ALL_DEVICE_DRIVERS:
     from .openconfig.OpenConfigDriver import OpenConfigDriver # pylint: disable=wrong-import-position
     DRIVERS.append(
diff --git a/src/device/service/drivers/emulated/Tools.py b/src/device/service/drivers/emulated/Tools.py
index 9f2a105c0d9735f486f41fab5bc3069ec9327f65..2a6f9c95d351f447f7368584d0ad07889eaecd7c 100644
--- a/src/device/service/drivers/emulated/Tools.py
+++ b/src/device/service/drivers/emulated/Tools.py
@@ -82,6 +82,26 @@ def compose_resource_endpoint(endpoint_data : Dict[str, Any]) -> Optional[Tuple[
     
         if 'location' in endpoint_data:
             endpoint_resource_value['location'] = endpoint_data['location']
+
+        if "site_location" in endpoint_data:
+            endpoint_resource_value["site_location"] = endpoint_data["site_location"]
+
+        if "ce-ip" in endpoint_data:
+            endpoint_resource_value["ce-ip"] = endpoint_data["ce-ip"]
+
+        if "address_ip" in endpoint_data:
+            endpoint_resource_value["address_ip"] = endpoint_data["address_ip"]
+
+        if "address_prefix" in endpoint_data:
+            endpoint_resource_value["address_prefix"] = endpoint_data["address_prefix"]
+
+        if "mtu" in endpoint_data:
+            endpoint_resource_value["mtu"] = endpoint_data["mtu"]
+
+        if "ipv4_lan_prefixes" in endpoint_data:
+            endpoint_resource_value["ipv4_lan_prefixes"] = endpoint_data[
+                "ipv4_lan_prefixes"
+            ]
             
         return endpoint_resource_key, endpoint_resource_value
     except: # pylint: disable=bare-except
diff --git a/src/device/service/drivers/ietf_l3vpn/Constants.py b/src/device/service/drivers/ietf_l3vpn/Constants.py
new file mode 100644
index 0000000000000000000000000000000000000000..df66eb16b3d78c1b388a086011ed6f6b75b8099f
--- /dev/null
+++ b/src/device/service/drivers/ietf_l3vpn/Constants.py
@@ -0,0 +1,25 @@
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from device.service.driver_api._Driver import (
+    RESOURCE_ENDPOINTS,
+    RESOURCE_INTERFACES,
+    RESOURCE_NETWORK_INSTANCES,
+)
+
+SPECIAL_RESOURCE_MAPPINGS = {
+    RESOURCE_ENDPOINTS: "/endpoints",
+    RESOURCE_INTERFACES: "/interfaces",
+    RESOURCE_NETWORK_INSTANCES: "/net-instances",
+}
diff --git a/src/device/service/drivers/ietf_l3vpn/TfsApiClient.py b/src/device/service/drivers/ietf_l3vpn/TfsApiClient.py
new file mode 100644
index 0000000000000000000000000000000000000000..1ca965f8777aa23287ad379c8ac2cd0d92d9c28f
--- /dev/null
+++ b/src/device/service/drivers/ietf_l3vpn/TfsApiClient.py
@@ -0,0 +1,187 @@
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+from typing import Dict, List, Optional
+
+import requests
+from requests.auth import HTTPBasicAuth
+
+from device.service.driver_api.ImportTopologyEnum import ImportTopologyEnum
+
+GET_DEVICES_URL = "{:s}://{:s}:{:d}/tfs-api/devices"
+GET_LINKS_URL = "{:s}://{:s}:{:d}/tfs-api/links"
+L3VPN_URL = "{:s}://{:s}:{:d}/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services"
+TIMEOUT = 30
+
+HTTP_OK_CODES = {
+    200,  # OK
+    201,  # Created
+    202,  # Accepted
+    204,  # No Content
+}
+
+MAPPING_STATUS = {
+    "DEVICEOPERATIONALSTATUS_UNDEFINED": 0,
+    "DEVICEOPERATIONALSTATUS_DISABLED": 1,
+    "DEVICEOPERATIONALSTATUS_ENABLED": 2,
+}
+
+MAPPING_DRIVER = {
+    "DEVICEDRIVER_UNDEFINED": 0,
+    "DEVICEDRIVER_OPENCONFIG": 1,
+    "DEVICEDRIVER_TRANSPORT_API": 2,
+    "DEVICEDRIVER_P4": 3,
+    "DEVICEDRIVER_IETF_NETWORK_TOPOLOGY": 4,
+    "DEVICEDRIVER_ONF_TR_532": 5,
+    "DEVICEDRIVER_XR": 6,
+    "DEVICEDRIVER_IETF_L2VPN": 7,
+    "DEVICEDRIVER_GNMI_OPENCONFIG": 8,
+    "DEVICEDRIVER_OPTICAL_TFS": 9,
+    "DEVICEDRIVER_IETF_ACTN": 10,
+    "DEVICEDRIVER_OC": 11,
+}
+
+MSG_ERROR = "Could not retrieve devices in remote TeraFlowSDN instance({:s}). status_code={:s} reply={:s}"
+
+LOGGER = logging.getLogger(__name__)
+
+
+class TfsApiClient:
+    def __init__(
+        self,
+        address: str,
+        port: int,
+        scheme: str = "http",
+        username: Optional[str] = None,
+        password: Optional[str] = None,
+    ) -> None:
+        self._devices_url = GET_DEVICES_URL.format(scheme, address, port)
+        self._links_url = GET_LINKS_URL.format(scheme, address, port)
+        self._l3vpn_url = L3VPN_URL.format(scheme, address, port)
+        self._auth = None
+        # (
+        #     HTTPBasicAuth(username, password)
+        #     if username is not None and password is not None
+        #     else None
+        # )
+
+    def get_devices_endpoints(
+        self, import_topology: ImportTopologyEnum = ImportTopologyEnum.DEVICES
+    ) -> List[Dict]:
+        LOGGER.debug("[get_devices_endpoints] begin")
+        LOGGER.debug(
+            "[get_devices_endpoints] import_topology={:s}".format(str(import_topology))
+        )
+
+        reply = requests.get(self._devices_url, timeout=TIMEOUT, auth=self._auth)
+        if reply.status_code not in HTTP_OK_CODES:
+            msg = MSG_ERROR.format(
+                str(self._devices_url), str(reply.status_code), str(reply)
+            )
+            LOGGER.error(msg)
+            raise Exception(msg)
+
+        if import_topology == ImportTopologyEnum.DISABLED:
+            raise Exception(
+                "Unsupported import_topology mode: {:s}".format(str(import_topology))
+            )
+
+        result = list()
+        for json_device in reply.json()["devices"]:
+            device_uuid: str = json_device["device_id"]["device_uuid"]["uuid"]
+            device_type: str = json_device["device_type"]
+            device_status = json_device["device_operational_status"]
+            device_url = "/devices/device[{:s}]".format(device_uuid)
+            device_data = {
+                "uuid": json_device["device_id"]["device_uuid"]["uuid"],
+                "name": json_device["name"],
+                "type": device_type,
+                "status": MAPPING_STATUS[device_status],
+                "drivers": [
+                    MAPPING_DRIVER[driver] for driver in json_device["device_drivers"]
+                ],
+            }
+            result.append((device_url, device_data))
+
+            for json_endpoint in json_device["device_endpoints"]:
+                endpoint_uuid = json_endpoint["endpoint_id"]["endpoint_uuid"]["uuid"]
+                endpoint_url = "/endpoints/endpoint[{:s}]".format(endpoint_uuid)
+                endpoint_data = {
+                    "device_uuid": device_uuid,
+                    "uuid": endpoint_uuid,
+                    "name": json_endpoint["name"],
+                    "type": json_endpoint["endpoint_type"],
+                }
+                result.append((endpoint_url, endpoint_data))
+
+        if import_topology == ImportTopologyEnum.DEVICES:
+            LOGGER.debug("[get_devices_endpoints] devices only; returning")
+            return result
+
+        reply = requests.get(self._links_url, timeout=TIMEOUT, auth=self._auth)
+        if reply.status_code not in HTTP_OK_CODES:
+            msg = MSG_ERROR.format(
+                str(self._links_url), str(reply.status_code), str(reply)
+            )
+            LOGGER.error(msg)
+            raise Exception(msg)
+
+        for json_link in reply.json()["links"]:
+            link_uuid: str = json_link["link_id"]["link_uuid"]["uuid"]
+            link_url = "/links/link[{:s}]".format(link_uuid)
+            link_endpoint_ids = [
+                (
+                    json_endpoint_id["device_id"]["device_uuid"]["uuid"],
+                    json_endpoint_id["endpoint_uuid"]["uuid"],
+                )
+                for json_endpoint_id in json_link["link_endpoint_ids"]
+            ]
+            link_data = {
+                "uuid": json_link["link_id"]["link_uuid"]["uuid"],
+                "name": json_link["name"],
+                "endpoints": link_endpoint_ids,
+            }
+            result.append((link_url, link_data))
+
+        LOGGER.debug("[get_devices_endpoints] topology; returning")
+        return result
+
+    def create_connectivity_service(self, l3vpn_data: dict) -> None:
+        try:
+            requests.post(self._l3vpn_url, json=l3vpn_data)
+            LOGGER.debug(
+                "[create_connectivity_service] l3vpn_data={:s}".format(str(l3vpn_data))
+            )
+        except requests.exceptions.ConnectionError:
+            raise Exception("faild to send post request to TFS L3VPN NBI")
+
+    def update_connectivity_service(self, l3vpn_data: dict) -> None:
+        vpn_id = l3vpn_data['ietf-l3vpn-svc:l3vpn-svc']["vpn-services"]["vpn-service"][0]["vpn-id"]
+        url = self._l3vpn_url + f"/vpn-service={vpn_id}"
+        try:
+            requests.put(url, json=l3vpn_data)
+            LOGGER.debug(
+                "[update_connectivity_service] l3vpn_data={:s}".format(str(l3vpn_data))
+            )
+        except requests.exceptions.ConnectionError:
+            raise Exception("faild to send post request to TFS L3VPN NBI")
+
+    def delete_connectivity_service(self, service_uuid: str) -> None:
+        url = self._l3vpn_url + f"/vpn-service={service_uuid}"
+        try:
+            requests.delete(url, auth=self._auth)
+            LOGGER.debug("[delete_connectivity_service] url={:s}".format(str(url)))
+        except requests.exceptions.ConnectionError:
+            raise Exception("faild to send delete request to TFS L3VPN NBI")
diff --git a/src/device/service/drivers/ietf_l3vpn/Tools.py b/src/device/service/drivers/ietf_l3vpn/Tools.py
new file mode 100644
index 0000000000000000000000000000000000000000..7caaa27a52cacf03d9822e933f0a6b74fd0e4db8
--- /dev/null
+++ b/src/device/service/drivers/ietf_l3vpn/Tools.py
@@ -0,0 +1,198 @@
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import logging
+from typing import Any, Dict, Optional, Tuple, TypedDict
+
+import requests
+
+from common.proto.kpi_sample_types_pb2 import KpiSampleType
+from common.type_checkers.Checkers import chk_attribute, chk_string, chk_type
+from device.service.driver_api._Driver import RESOURCE_ENDPOINTS
+
+from .Constants import SPECIAL_RESOURCE_MAPPINGS
+
+
+class LANPrefixesDict(TypedDict):
+    lan: str
+    lan_tag: str
+
+
+LOGGER = logging.getLogger(__name__)
+
+SITE_NETWORK_ACCESS_TYPE = "ietf-l3vpn-svc:multipoint"
+
+
+def service_exists(wim_url: str, auth, service_uuid: str) -> bool:
+    try:
+        get_connectivity_service(wim_url, auth, service_uuid)
+        return True
+    except:  # pylint: disable=bare-except
+        return False
+
+
+def get_all_active_connectivity_services(wim_url: str, auth):
+    try:
+        LOGGER.info("Sending get all connectivity services")
+        servicepoint = f"{wim_url}/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services"
+        response = requests.get(servicepoint, auth=auth)
+
+        if response.status_code != requests.codes.ok:
+            raise Exception(
+                "Unable to get all connectivity services",
+                http_code=response.status_code,
+            )
+
+        return response
+    except requests.exceptions.ConnectionError:
+        raise Exception("Request Timeout", http_code=408)
+
+
+def get_connectivity_service(wim_url, auth, service_uuid):
+    try:
+        LOGGER.info("Sending get connectivity service")
+        servicepoint = f"{wim_url}/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services/vpn-service={service_uuid}"
+
+        response = requests.get(servicepoint)
+
+        if response.status_code != requests.codes.ok:
+            raise Exception(
+                "Unable to get connectivity service{:s}".format(str(service_uuid)),
+                http_code=response.status_code,
+            )
+
+        return response
+    except requests.exceptions.ConnectionError:
+        raise Exception("Request Timeout", http_code=408)
+
+
+def process_optional_string_field(
+    endpoint_data: Dict[str, Any],
+    field_name: str,
+    endpoint_resource_value: Dict[str, Any],
+) -> None:
+    field_value = chk_attribute(
+        field_name, endpoint_data, "endpoint_data", default=None
+    )
+    if field_value is None:
+        return
+    chk_string("endpoint_data.{:s}".format(field_name), field_value)
+    if len(field_value) > 0:
+        endpoint_resource_value[field_name] = field_value
+
+
+def compose_resource_endpoint(
+    endpoint_data: Dict[str, Any],
+) -> Optional[Tuple[str, Dict]]:
+    try:
+        # Check type of endpoint_data
+        chk_type("endpoint_data", endpoint_data, dict)
+
+        # Check endpoint UUID (mandatory)
+        endpoint_uuid = chk_attribute("uuid", endpoint_data, "endpoint_data")
+        chk_string("endpoint_data.uuid", endpoint_uuid, min_length=1)
+        endpoint_resource_path = SPECIAL_RESOURCE_MAPPINGS.get(RESOURCE_ENDPOINTS)
+        endpoint_resource_key = "{:s}/endpoint[{:s}]".format(
+            endpoint_resource_path, endpoint_uuid
+        )
+        endpoint_resource_value = {"uuid": endpoint_uuid}
+
+        # Check endpoint optional string fields
+        process_optional_string_field(endpoint_data, "name", endpoint_resource_value)
+        process_optional_string_field(
+            endpoint_data, "site_location", endpoint_resource_value
+        )
+        process_optional_string_field(endpoint_data, "ce-ip", endpoint_resource_value)
+        process_optional_string_field(
+            endpoint_data, "address_ip", endpoint_resource_value
+        )
+        process_optional_string_field(
+            endpoint_data, "address_prefix", endpoint_resource_value
+        )
+        process_optional_string_field(endpoint_data, "mtu", endpoint_resource_value)
+        process_optional_string_field(
+            endpoint_data, "ipv4_lan_prefixes", endpoint_resource_value
+        )
+        process_optional_string_field(endpoint_data, "type", endpoint_resource_value)
+        process_optional_string_field(
+            endpoint_data, "context_uuid", endpoint_resource_value
+        )
+        process_optional_string_field(
+            endpoint_data, "topology_uuid", endpoint_resource_value
+        )
+
+        # Check endpoint sample types (optional)
+        endpoint_sample_types = chk_attribute(
+            "sample_types", endpoint_data, "endpoint_data", default=[]
+        )
+        chk_type("endpoint_data.sample_types", endpoint_sample_types, list)
+        sample_types = {}
+        sample_type_errors = []
+        for i, endpoint_sample_type in enumerate(endpoint_sample_types):
+            field_name = "endpoint_data.sample_types[{:d}]".format(i)
+            try:
+                chk_type(field_name, endpoint_sample_type, (int, str))
+                if isinstance(endpoint_sample_type, int):
+                    metric_name = KpiSampleType.Name(endpoint_sample_type)
+                    metric_id = endpoint_sample_type
+                elif isinstance(endpoint_sample_type, str):
+                    metric_id = KpiSampleType.Value(endpoint_sample_type)
+                    metric_name = endpoint_sample_type
+                else:
+                    str_type = str(type(endpoint_sample_type))
+                    raise Exception("Bad format: {:s}".format(str_type))  # pylint: disable=broad-exception-raised
+            except Exception as e:  # pylint: disable=broad-exception-caught
+                MSG = "Unsupported {:s}({:s}) : {:s}"
+                sample_type_errors.append(
+                    MSG.format(field_name, str(endpoint_sample_type), str(e))
+                )
+
+            metric_name = metric_name.lower().replace("kpisampletype_", "")
+            monitoring_resource_key = "{:s}/state/{:s}".format(
+                endpoint_resource_key, metric_name
+            )
+            sample_types[metric_id] = monitoring_resource_key
+
+        if len(sample_type_errors) > 0:
+            # pylint: disable=broad-exception-raised
+            raise Exception(
+                "Malformed Sample Types:\n{:s}".format("\n".join(sample_type_errors))
+            )
+
+        if len(sample_types) > 0:
+            endpoint_resource_value["sample_types"] = sample_types
+
+        if "site_location" in endpoint_data:
+            endpoint_resource_value["site_location"] = endpoint_data["site_location"]
+
+        if "ce-ip" in endpoint_data:
+            endpoint_resource_value["ce-ip"] = endpoint_data["ce-ip"]
+
+        if "address_ip" in endpoint_data:
+            endpoint_resource_value["address_ip"] = endpoint_data["address_ip"]
+
+        if "address_prefix" in endpoint_data:
+            endpoint_resource_value["address_prefix"] = endpoint_data["address_prefix"]
+
+        if "mtu" in endpoint_data:
+            endpoint_resource_value["mtu"] = endpoint_data["mtu"]
+
+        if "ipv4_lan_prefixes" in endpoint_data:
+            endpoint_resource_value["ipv4_lan_prefixes"] = endpoint_data[
+                "ipv4_lan_prefixes"
+            ]
+
+        return endpoint_resource_key, endpoint_resource_value
+    except:  # pylint: disable=bare-except
+        LOGGER.exception("Problem composing endpoint({:s})".format(str(endpoint_data)))
+        return None
diff --git a/src/device/service/drivers/ietf_l3vpn/__init__.py b/src/device/service/drivers/ietf_l3vpn/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..bbfc943b68af13a11e562abbc8680ade71db8f02
--- /dev/null
+++ b/src/device/service/drivers/ietf_l3vpn/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/src/device/service/drivers/ietf_l3vpn/driver.py b/src/device/service/drivers/ietf_l3vpn/driver.py
new file mode 100644
index 0000000000000000000000000000000000000000..2aca83b6a645bf2e793b08841949813f0413a531
--- /dev/null
+++ b/src/device/service/drivers/ietf_l3vpn/driver.py
@@ -0,0 +1,309 @@
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+import logging
+import re
+import threading
+from typing import Any, Iterator, List, Optional, Tuple, Union
+
+import anytree
+import requests
+from requests.auth import HTTPBasicAuth
+
+from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method
+from common.type_checkers.Checkers import chk_length, chk_string, chk_type
+from device.service.driver_api._Driver import (
+    RESOURCE_ENDPOINTS,
+    RESOURCE_SERVICES,
+    _Driver,
+)
+from device.service.driver_api.AnyTreeTools import (
+    TreeNode,
+    dump_subtree,
+    get_subnode,
+    set_subnode_value,
+)
+from device.service.driver_api.ImportTopologyEnum import (
+    ImportTopologyEnum,
+    get_import_topology,
+)
+
+from .Constants import SPECIAL_RESOURCE_MAPPINGS
+from .TfsApiClient import TfsApiClient
+from .Tools import compose_resource_endpoint
+
+LOGGER = logging.getLogger(__name__)
+
+
+ALL_RESOURCE_KEYS = [
+    RESOURCE_ENDPOINTS,
+    RESOURCE_SERVICES,
+]
+
+RE_GET_ENDPOINT_FROM_INTERFACE = re.compile(r"^\/interface\[([^\]]+)\].*")
+
+RE_IETF_L3VPN_DATA = re.compile(r"^\/service\[[^\]]+\]\/IETFL3VPN$")
+RE_IETF_L3VPN_OPERATION = re.compile(r"^\/service\[[^\]]+\]\/IETFL3VPN\/operation$")
+
+DRIVER_NAME = "ietf_l3vpn"
+METRICS_POOL = MetricsPool("Device", "Driver", labels={"driver": DRIVER_NAME})
+
+
+class IetfL3VpnDriver(_Driver):
+    def __init__(self, address: str, port: str, **settings) -> None:
+        super().__init__(DRIVER_NAME, address, int(port), **settings)
+        self.__lock = threading.Lock()
+        self.__started = threading.Event()
+        self.__terminate = threading.Event()
+        self.__running = TreeNode(".")
+        scheme = self.settings.get("scheme", "http")
+        username = self.settings.get("username")
+        password = self.settings.get("password")
+        self.tac = TfsApiClient(
+            self.address,
+            self.port,
+            scheme=scheme,
+            username=username,
+            password=password,
+        )
+        self.__auth = None
+        # (
+        #     HTTPBasicAuth(username, password)
+        #     if username is not None and password is not None
+        #     else None
+        # )
+        self.__tfs_nbi_root = "{:s}://{:s}:{:d}".format(
+            scheme, self.address, int(self.port)
+        )
+        self.__timeout = int(self.settings.get("timeout", 120))
+        self.__import_topology = get_import_topology(
+            self.settings, default=ImportTopologyEnum.DEVICES
+        )
+        endpoints = self.settings.get("endpoints", [])
+        endpoint_resources = []
+        for endpoint in endpoints:
+            endpoint_resource = compose_resource_endpoint(endpoint)
+            if endpoint_resource is None:
+                continue
+            endpoint_resources.append(endpoint_resource)
+        self._set_initial_config(endpoint_resources)
+
+    def _set_initial_config(
+        self, resources: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        chk_type("resources", resources, list)
+        if len(resources) == 0:
+            return []
+        results = []
+        resolver = anytree.Resolver(pathattr="name")
+        with self.__lock:
+            for i, resource in enumerate(resources):
+                str_resource_name = "resources[#{:d}]".format(i)
+                try:
+                    chk_type(str_resource_name, resource, (list, tuple))
+                    chk_length(str_resource_name, resource, min_length=2, max_length=2)
+                    resource_key, resource_value = resource
+                    chk_string(str_resource_name, resource_key, allow_empty=False)
+                    resource_path = resource_key.split("/")
+                except Exception as e:  # pylint: disable=broad-except
+                    LOGGER.exception(
+                        "Exception validating {:s}: {:s}".format(
+                            str_resource_name, str(resource_key)
+                        )
+                    )
+                    results.append(e)  # if validation fails, store the exception
+                    continue
+
+                try:
+                    resource_value = json.loads(resource_value)
+                except:  # pylint: disable=bare-except
+                    pass
+
+                set_subnode_value(
+                    resolver, self.__running, resource_path, resource_value
+                )
+
+                results.append(True)
+        return results
+
+    def Connect(self) -> bool:
+        url = (
+            self.__tfs_nbi_root + "/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services"
+        )
+        with self.__lock:
+            if self.__started.is_set():
+                return True
+            try:
+                # requests.get(url, timeout=self.__timeout, auth=self.__auth)
+                ...
+            except requests.exceptions.Timeout:
+                LOGGER.exception("Timeout connecting {:s}".format(url))
+                return False
+            except Exception:  # pylint: disable=broad-except
+                LOGGER.exception("Exception connecting {:s}".format(url))
+                return False
+            else:
+                self.__started.set()
+                return True
+
+    def Disconnect(self) -> bool:
+        with self.__lock:
+            self.__terminate.set()
+            return True
+
+    @metered_subclass_method(METRICS_POOL)
+    def GetInitialConfig(self) -> List[Tuple[str, Any]]:
+        with self.__lock:
+            return []
+
+    @metered_subclass_method(METRICS_POOL)
+    def GetConfig(
+        self, resource_keys: List[str] = []
+    ) -> List[Tuple[str, Union[Any, None, Exception]]]:
+        chk_type("resources", resource_keys, list)
+        with self.__lock:
+            if len(resource_keys) == 0:
+                return dump_subtree(self.__running)
+            results = []
+            resolver = anytree.Resolver(pathattr="name")
+            for i, resource_key in enumerate(resource_keys):
+                str_resource_name = "resource_key[#{:d}]".format(i)
+                try:
+                    chk_string(str_resource_name, resource_key, allow_empty=False)
+                    resource_key = SPECIAL_RESOURCE_MAPPINGS.get(
+                        resource_key, resource_key
+                    )
+                    resource_path = resource_key.split("/")
+                except Exception as e:  # pylint: disable=broad-except
+                    LOGGER.exception(
+                        "Exception validating {:s}: {:s}".format(
+                            str_resource_name, str(resource_key)
+                        )
+                    )
+                    results.append(
+                        (resource_key, e)
+                    )  # if validation fails, store the exception
+                    continue
+
+                resource_node = get_subnode(
+                    resolver, self.__running, resource_path, default=None
+                )
+                # if not found, resource_node is None
+                if resource_node is None:
+                    continue
+                results.extend(dump_subtree(resource_node))
+            return results
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetConfig(
+        self, resources: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        results = []
+        if len(resources) == 0:
+            return results
+        with self.__lock:
+            for resource in resources:
+                resource_key, resource_value = resource
+                if RE_IETF_L3VPN_OPERATION.match(resource_key):
+                    operation_type = json.loads(resource_value)["type"]
+                    results.append((resource_key, True))
+                    break
+            else:
+                raise Exception("operation type not found in resources")
+            for resource in resources:
+                LOGGER.info("resource = {:s}".format(str(resource)))
+                resource_key, resource_value = resource
+                if not RE_IETF_L3VPN_DATA.match(resource_key):
+                    continue
+                try:
+                    resource_value = json.loads(resource_value)
+
+                    # if service_exists(self.__tfs_nbi_root, self.__auth, service_uuid):
+                    #     exc = NotImplementedError(
+                    #         "IETF L3VPN Service Update is still not supported"
+                    #     )
+                    #     results.append((resource[0], exc))
+                    #     continue
+                    if operation_type == "create":
+                        service_id = resource_value["ietf-l3vpn-svc:l3vpn-svc"][
+                            "vpn-services"
+                        ]["vpn-service"][0]["vpn-id"]
+                        self.tac.create_connectivity_service(resource_value)
+                    elif operation_type == "update":
+                        service_id = resource_value["ietf-l3vpn-svc:l3vpn-svc"][
+                            "vpn-services"
+                        ]["vpn-service"][0]["vpn-id"]
+                        self.tac.update_connectivity_service(resource_value)
+                    else:
+                        raise Exception("operation type not supported")
+                    results.append((resource_key, True))
+                except Exception as e:  # pylint: disable=broad-except
+                    LOGGER.exception(
+                        "Unhandled error processing resource_key({:s})".format(
+                            str(resource_key)
+                        )
+                    )
+                    results.append((resource_key, e))
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def DeleteConfig(
+        self, resources: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        results = []
+        if len(resources) == 0:
+            return results
+        with self.__lock:
+            for resource in resources:
+                LOGGER.info("resource = {:s}".format(str(resource)))
+                resource_key, resource_value = resource
+                if not RE_IETF_L3VPN_DATA.match(resource_key):
+                    continue
+                try:
+                    resource_value = json.loads(resource_value)
+                    service_id = resource_value["id"]
+
+                    # if service_exists(self.__tfs_nbi_root, self.__auth, service_uuid):
+                    self.tac.delete_connectivity_service(service_id)
+                    results.append((resource_key, True))
+                except Exception as e:  # pylint: disable=broad-except
+                    LOGGER.exception(
+                        "Unhandled error processing resource_key({:s})".format(
+                            str(resource_key)
+                        )
+                    )
+                    results.append((resource_key, e))
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def SubscribeState(
+        self, subscriptions: List[Tuple[str, float, float]]
+    ) -> List[Union[bool, Exception]]:
+        # TODO: IETF L3VPN does not support monitoring by now
+        return [False for _ in subscriptions]
+
+    @metered_subclass_method(METRICS_POOL)
+    def UnsubscribeState(
+        self, subscriptions: List[Tuple[str, float, float]]
+    ) -> List[Union[bool, Exception]]:
+        # TODO: IETF L3VPN does not support monitoring by now
+        return [False for _ in subscriptions]
+
+    def GetState(
+        self, blocking=False, terminate: Optional[threading.Event] = None
+    ) -> Iterator[Tuple[float, str, Any]]:
+        # TODO: IETF L3VPN does not support monitoring by now
+        return []
diff --git a/src/device/service/drivers/ietf_slice/Constants.py b/src/device/service/drivers/ietf_slice/Constants.py
new file mode 100644
index 0000000000000000000000000000000000000000..172c328aeaa5a2beafe4ced1b273cb3e7577e241
--- /dev/null
+++ b/src/device/service/drivers/ietf_slice/Constants.py
@@ -0,0 +1,25 @@
+# Copyright 2022-2025 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from device.service.driver_api._Driver import (
+    RESOURCE_ENDPOINTS,
+    RESOURCE_INTERFACES,
+    RESOURCE_NETWORK_INSTANCES,
+)
+
+SPECIAL_RESOURCE_MAPPINGS = {
+    RESOURCE_ENDPOINTS: "/endpoints",
+    RESOURCE_INTERFACES: "/interfaces",
+    RESOURCE_NETWORK_INSTANCES: "/net-instances",
+}
diff --git a/src/device/service/drivers/ietf_slice/Tools.py b/src/device/service/drivers/ietf_slice/Tools.py
new file mode 100644
index 0000000000000000000000000000000000000000..bd976927e4b17c74264b3372ed1caeeb1bc96c61
--- /dev/null
+++ b/src/device/service/drivers/ietf_slice/Tools.py
@@ -0,0 +1,147 @@
+# Copyright 2022-2025 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import logging
+from typing import Any, Dict, Optional, Tuple
+
+import requests
+
+from common.proto.kpi_sample_types_pb2 import KpiSampleType
+from common.type_checkers.Checkers import chk_attribute, chk_string, chk_type
+from device.service.driver_api._Driver import RESOURCE_ENDPOINTS
+
+from .Constants import SPECIAL_RESOURCE_MAPPINGS
+
+LOGGER = logging.getLogger(__name__)
+
+
+def process_optional_string_field(
+    endpoint_data: Dict[str, Any],
+    field_name: str,
+    endpoint_resource_value: Dict[str, Any],
+) -> None:
+    field_value = chk_attribute(
+        field_name, endpoint_data, "endpoint_data", default=None
+    )
+    if field_value is None:
+        return
+    chk_string("endpoint_data.{:s}".format(field_name), field_value)
+    if len(field_value) > 0:
+        endpoint_resource_value[field_name] = field_value
+
+
+def compose_resource_endpoint(
+    endpoint_data: Dict[str, Any],
+) -> Optional[Tuple[str, Dict]]:
+    try:
+        # Check type of endpoint_data
+        chk_type("endpoint_data", endpoint_data, dict)
+
+        # Check endpoint UUID (mandatory)
+        endpoint_uuid = chk_attribute("uuid", endpoint_data, "endpoint_data")
+        chk_string("endpoint_data.uuid", endpoint_uuid, min_length=1)
+        endpoint_resource_path = SPECIAL_RESOURCE_MAPPINGS.get(RESOURCE_ENDPOINTS)
+        endpoint_resource_key = "{:s}/endpoint[{:s}]".format(
+            endpoint_resource_path, endpoint_uuid
+        )
+        endpoint_resource_value = {"uuid": endpoint_uuid}
+
+        # Check endpoint optional string fields
+        process_optional_string_field(endpoint_data, "name", endpoint_resource_value)
+        process_optional_string_field(
+            endpoint_data, "site_location", endpoint_resource_value
+        )
+        process_optional_string_field(endpoint_data, "ce-ip", endpoint_resource_value)
+        process_optional_string_field(
+            endpoint_data, "address_ip", endpoint_resource_value
+        )
+        process_optional_string_field(
+            endpoint_data, "address_prefix", endpoint_resource_value
+        )
+        process_optional_string_field(endpoint_data, "mtu", endpoint_resource_value)
+        process_optional_string_field(
+            endpoint_data, "ipv4_lan_prefixes", endpoint_resource_value
+        )
+        process_optional_string_field(endpoint_data, "type", endpoint_resource_value)
+        process_optional_string_field(
+            endpoint_data, "context_uuid", endpoint_resource_value
+        )
+        process_optional_string_field(
+            endpoint_data, "topology_uuid", endpoint_resource_value
+        )
+
+        # Check endpoint sample types (optional)
+        endpoint_sample_types = chk_attribute(
+            "sample_types", endpoint_data, "endpoint_data", default=[]
+        )
+        chk_type("endpoint_data.sample_types", endpoint_sample_types, list)
+        sample_types = {}
+        sample_type_errors = []
+        for i, endpoint_sample_type in enumerate(endpoint_sample_types):
+            field_name = "endpoint_data.sample_types[{:d}]".format(i)
+            try:
+                chk_type(field_name, endpoint_sample_type, (int, str))
+                if isinstance(endpoint_sample_type, int):
+                    metric_name = KpiSampleType.Name(endpoint_sample_type)
+                    metric_id = endpoint_sample_type
+                elif isinstance(endpoint_sample_type, str):
+                    metric_id = KpiSampleType.Value(endpoint_sample_type)
+                    metric_name = endpoint_sample_type
+                else:
+                    str_type = str(type(endpoint_sample_type))
+                    raise Exception("Bad format: {:s}".format(str_type))  # pylint: disable=broad-exception-raised
+            except Exception as e:  # pylint: disable=broad-exception-caught
+                MSG = "Unsupported {:s}({:s}) : {:s}"
+                sample_type_errors.append(
+                    MSG.format(field_name, str(endpoint_sample_type), str(e))
+                )
+
+            metric_name = metric_name.lower().replace("kpisampletype_", "")
+            monitoring_resource_key = "{:s}/state/{:s}".format(
+                endpoint_resource_key, metric_name
+            )
+            sample_types[metric_id] = monitoring_resource_key
+
+        if len(sample_type_errors) > 0:
+            # pylint: disable=broad-exception-raised
+            raise Exception(
+                "Malformed Sample Types:\n{:s}".format("\n".join(sample_type_errors))
+            )
+
+        if len(sample_types) > 0:
+            endpoint_resource_value["sample_types"] = sample_types
+
+        if "site_location" in endpoint_data:
+            endpoint_resource_value["site_location"] = endpoint_data["site_location"]
+
+        if "ce-ip" in endpoint_data:
+            endpoint_resource_value["ce-ip"] = endpoint_data["ce-ip"]
+
+        if "address_ip" in endpoint_data:
+            endpoint_resource_value["address_ip"] = endpoint_data["address_ip"]
+
+        if "address_prefix" in endpoint_data:
+            endpoint_resource_value["address_prefix"] = endpoint_data["address_prefix"]
+
+        if "mtu" in endpoint_data:
+            endpoint_resource_value["mtu"] = endpoint_data["mtu"]
+
+        if "ipv4_lan_prefixes" in endpoint_data:
+            endpoint_resource_value["ipv4_lan_prefixes"] = endpoint_data[
+                "ipv4_lan_prefixes"
+            ]
+
+        return endpoint_resource_key, endpoint_resource_value
+    except:  # pylint: disable=bare-except
+        LOGGER.exception("Problem composing endpoint({:s})".format(str(endpoint_data)))
+        return None
diff --git a/src/device/service/drivers/ietf_slice/__init__.py b/src/device/service/drivers/ietf_slice/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..6242c89c7fa17bc5b6cc44328d8ce58438721d45
--- /dev/null
+++ b/src/device/service/drivers/ietf_slice/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2022-2025 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/src/device/service/drivers/ietf_slice/driver.py b/src/device/service/drivers/ietf_slice/driver.py
new file mode 100644
index 0000000000000000000000000000000000000000..e8b6e7d0effac1f7a3eb05c7aabd2d0a39125b65
--- /dev/null
+++ b/src/device/service/drivers/ietf_slice/driver.py
@@ -0,0 +1,306 @@
+# Copyright 2022-2025 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+import logging
+import re
+import threading
+from typing import Any, Iterator, List, Optional, Tuple, Union
+
+import anytree
+import requests
+from requests.auth import HTTPBasicAuth
+
+from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method
+from common.type_checkers.Checkers import chk_length, chk_string, chk_type
+from device.service.driver_api._Driver import (
+    RESOURCE_ENDPOINTS,
+    RESOURCE_SERVICES,
+    _Driver,
+)
+from device.service.driver_api.AnyTreeTools import (
+    TreeNode,
+    dump_subtree,
+    get_subnode,
+    set_subnode_value,
+)
+from device.service.driver_api.ImportTopologyEnum import (
+    ImportTopologyEnum,
+    get_import_topology,
+)
+
+from .Constants import SPECIAL_RESOURCE_MAPPINGS
+from .tfs_slice_nbi_client import TfsApiClient
+from .Tools import compose_resource_endpoint
+
+LOGGER = logging.getLogger(__name__)
+
+
+ALL_RESOURCE_KEYS = [
+    RESOURCE_ENDPOINTS,
+    RESOURCE_SERVICES,
+]
+
+RE_IETF_SLICE_DATA = re.compile(r"^\/service\[[^\]]+\]\/IETFSlice$")
+RE_IETF_SLICE_OPERATION = re.compile(r"^\/service\[[^\]]+\]\/IETFSlice\/operation$")
+
+DRIVER_NAME = "ietf_slice"
+METRICS_POOL = MetricsPool("Device", "Driver", labels={"driver": DRIVER_NAME})
+
+
+class IetfSliceDriver(_Driver):
+    def __init__(self, address: str, port: str, **settings) -> None:
+        super().__init__(DRIVER_NAME, address, int(port), **settings)
+        self.__lock = threading.Lock()
+        self.__started = threading.Event()
+        self.__terminate = threading.Event()
+        self.__running = TreeNode(".")
+        scheme = self.settings.get("scheme", "http")
+        username = self.settings.get("username")
+        password = self.settings.get("password")
+        self.tac = TfsApiClient(
+            self.address,
+            self.port,
+            scheme=scheme,
+            username=username,
+            password=password,
+        )
+        self.__auth = None
+        # (
+        #     HTTPBasicAuth(username, password)
+        #     if username is not None and password is not None
+        #     else None
+        # )
+        self.__tfs_nbi_root = "{:s}://{:s}:{:d}".format(
+            scheme, self.address, int(self.port)
+        )
+        self.__timeout = int(self.settings.get("timeout", 120))
+        self.__import_topology = get_import_topology(
+            self.settings, default=ImportTopologyEnum.DEVICES
+        )
+        endpoints = self.settings.get("endpoints", [])
+        endpoint_resources = []
+        for endpoint in endpoints:
+            endpoint_resource = compose_resource_endpoint(endpoint)
+            if endpoint_resource is None:
+                continue
+            endpoint_resources.append(endpoint_resource)
+        self._set_initial_config(endpoint_resources)
+
+    def _set_initial_config(
+        self, resources: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        chk_type("resources", resources, list)
+        if len(resources) == 0:
+            return []
+        results = []
+        resolver = anytree.Resolver(pathattr="name")
+        with self.__lock:
+            for i, resource in enumerate(resources):
+                str_resource_name = "resources[#{:d}]".format(i)
+                try:
+                    chk_type(str_resource_name, resource, (list, tuple))
+                    chk_length(str_resource_name, resource, min_length=2, max_length=2)
+                    resource_key, resource_value = resource
+                    chk_string(str_resource_name, resource_key, allow_empty=False)
+                    resource_path = resource_key.split("/")
+                except Exception as e:  # pylint: disable=broad-except
+                    LOGGER.exception(
+                        "Exception validating {:s}: {:s}".format(
+                            str_resource_name, str(resource_key)
+                        )
+                    )
+                    results.append(e)  # if validation fails, store the exception
+                    continue
+
+                try:
+                    resource_value = json.loads(resource_value)
+                except:  # pylint: disable=bare-except
+                    pass
+
+                set_subnode_value(
+                    resolver, self.__running, resource_path, resource_value
+                )
+
+                results.append(True)
+        return results
+
+    def Connect(self) -> bool:
+        url = self.__tfs_nbi_root + "/restconf/data/ietf-network-slice-service:ietf-nss"
+        with self.__lock:
+            if self.__started.is_set():
+                return True
+            try:
+                # requests.get(url, timeout=self.__timeout)
+                ...
+            except requests.exceptions.Timeout:
+                LOGGER.exception("Timeout connecting {:s}".format(url))
+                return False
+            except Exception:  # pylint: disable=broad-except
+                LOGGER.exception("Exception connecting {:s}".format(url))
+                return False
+            else:
+                self.__started.set()
+                return True
+
+    def Disconnect(self) -> bool:
+        with self.__lock:
+            self.__terminate.set()
+            return True
+
+    @metered_subclass_method(METRICS_POOL)
+    def GetInitialConfig(self) -> List[Tuple[str, Any]]:
+        with self.__lock:
+            return []
+
+    @metered_subclass_method(METRICS_POOL)
+    def GetConfig(
+        self, resource_keys: List[str] = []
+    ) -> List[Tuple[str, Union[Any, None, Exception]]]:
+        chk_type("resources", resource_keys, list)
+        with self.__lock:
+            if len(resource_keys) == 0:
+                return dump_subtree(self.__running)
+            results = []
+            resolver = anytree.Resolver(pathattr="name")
+            for i, resource_key in enumerate(resource_keys):
+                str_resource_name = "resource_key[#{:d}]".format(i)
+                try:
+                    chk_string(str_resource_name, resource_key, allow_empty=False)
+                    resource_key = SPECIAL_RESOURCE_MAPPINGS.get(
+                        resource_key, resource_key
+                    )
+                    resource_path = resource_key.split("/")
+                except Exception as e:  # pylint: disable=broad-except
+                    LOGGER.exception(
+                        "Exception validating {:s}: {:s}".format(
+                            str_resource_name, str(resource_key)
+                        )
+                    )
+                    results.append(
+                        (resource_key, e)
+                    )  # if validation fails, store the exception
+                    continue
+                resource_node = get_subnode(
+                    resolver, self.__running, resource_path, default=None
+                )
+                # if not found, resource_node is None
+                if resource_node is None:
+                    continue
+                results.extend(dump_subtree(resource_node))
+            return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetConfig(
+        self, resources: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        results = []
+
+        if len(resources) == 0:
+            return results
+
+        with self.__lock:
+            for resource in resources:
+                resource_key, resource_value = resource
+                if RE_IETF_SLICE_OPERATION.match(resource_key):
+                    operation_type = json.loads(resource_value)["type"]
+                    results.append((resource_key, True))
+                    break
+            else:
+                raise Exception("operation type not found in resources")
+            for resource in resources:
+                LOGGER.info("resource = {:s}".format(str(resource)))
+                resource_key, resource_value = resource
+                if not RE_IETF_SLICE_DATA.match(resource_key):
+                    continue
+                try:
+                    resource_value = json.loads(resource_value)
+
+                    slice_name = resource_value["network-slice-services"][
+                        "slice-service"
+                    ][0]["id"]
+
+                    if operation_type == "create":
+                        self.tac.create_slice(resource_value)
+
+                    elif operation_type == "update":
+                        connection_groups = resource_value["network-slice-services"][
+                            "slice-service"
+                        ][0]["connection-groups"]["connection-group"]
+
+                        if len(connection_groups) != 1:
+                            raise Exception("only one connection group is supported")
+
+                        connection_group = connection_groups[0]
+
+                        self.tac.update_slice(
+                            slice_name, connection_group["id"], connection_group
+                        )
+
+                    elif operation_type == "delete":
+                        self.tac.delete_slice(slice_name)
+
+                    results.append((resource_key, True))
+                except Exception as e:  # pylint: disable=broad-except
+                    LOGGER.exception(
+                        "Unhandled error processing resource_key({:s})".format(
+                            str(resource_key)
+                        )
+                    )
+                    results.append((resource_key, e))
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def DeleteConfig(
+        self, resources: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        results = []
+
+        if len(resources) == 0:
+            return results
+
+        with self.__lock:
+            for resource in resources:
+                LOGGER.info("resource = {:s}".format(str(resource)))
+                resource_key, resource_value = resource
+                try:
+                    results.append((resource_key, True))
+                except Exception as e:  # pylint: disable=broad-except
+                    LOGGER.exception(
+                        "Unhandled error processing resource_key({:s})".format(
+                            str(resource_key)
+                        )
+                    )
+                    results.append((resource_key, e))
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def SubscribeState(
+        self, subscriptions: List[Tuple[str, float, float]]
+    ) -> List[Union[bool, Exception]]:
+        # TODO: IETF Slice does not support monitoring by now
+        return [False for _ in subscriptions]
+
+    @metered_subclass_method(METRICS_POOL)
+    def UnsubscribeState(
+        self, subscriptions: List[Tuple[str, float, float]]
+    ) -> List[Union[bool, Exception]]:
+        # TODO: IETF Slice does not support monitoring by now
+        return [False for _ in subscriptions]
+
+    def GetState(
+        self, blocking=False, terminate: Optional[threading.Event] = None
+    ) -> Iterator[Tuple[float, str, Any]]:
+        # TODO: IETF Slice does not support monitoring by now
+        return []
diff --git a/src/device/service/drivers/ietf_slice/tfs_slice_nbi_client.py b/src/device/service/drivers/ietf_slice/tfs_slice_nbi_client.py
new file mode 100644
index 0000000000000000000000000000000000000000..596e3d903d6e17dda96be42d776aae2f9068f7bd
--- /dev/null
+++ b/src/device/service/drivers/ietf_slice/tfs_slice_nbi_client.py
@@ -0,0 +1,76 @@
+# Copyright 2022-2025 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+from typing import Optional
+
+import requests
+from requests.auth import HTTPBasicAuth
+
+IETF_SLICE_URL = "{:s}://{:s}:{:d}/restconf/data/ietf-network-slice-service"
+TIMEOUT = 30
+
+LOGGER = logging.getLogger(__name__)
+
+HEADERS = {"Content-Type": "application/json"}
+
+
+class TfsApiClient:
+    def __init__(
+        self,
+        address: str,
+        port: int,
+        scheme: str = "http",
+        username: Optional[str] = None,
+        password: Optional[str] = None,
+    ) -> None:
+        self._slice_url = IETF_SLICE_URL.format(scheme, address, port)
+        self._auth = None
+        # (
+        #     HTTPBasicAuth(username, password)
+        #     if username is not None and password is not None
+        #     else None
+        # )
+
+    def create_slice(self, slice_data: dict) -> None:
+        url = self._slice_url + ":network-slice-services"
+        try:
+            requests.post(url, json=slice_data, headers=HEADERS)
+            LOGGER.info(f"IETF Slice Post to {url}: {slice_data}")
+        except requests.exceptions.ConnectionError:
+            raise Exception("faild to send post request to TFS IETF Slice NBI")
+
+    def update_slice(
+        self,
+        slice_name: str,
+        connection_group_id: str,
+        updated_connection_group_data: dict,
+    ) -> None:
+        url = (
+            self._slice_url
+            + f":network-slice-services/slice-service={slice_name}/connection-groups/connection-group={connection_group_id}"
+        )
+        try:
+            requests.put(url, json=updated_connection_group_data, headers=HEADERS)
+            LOGGER.info(f"IETF Slice Put to {url}: {updated_connection_group_data}")
+        except requests.exceptions.ConnectionError:
+            raise Exception("faild to send update request to TFS IETF Slice NBI")
+
+    def delete_slice(self, slice_name: str) -> None:
+        url = self._slice_url + f":network-slice-services/slice-service={slice_name}"
+        try:
+            requests.delete(url)
+            LOGGER.info(f"IETF Slice Delete to {url}")
+        except requests.exceptions.ConnectionError:
+            raise Exception("faild to send delete request to TFS IETF Slice NBI")
diff --git a/src/device/service/drivers/nce/Constants.py b/src/device/service/drivers/nce/Constants.py
new file mode 100644
index 0000000000000000000000000000000000000000..172c328aeaa5a2beafe4ced1b273cb3e7577e241
--- /dev/null
+++ b/src/device/service/drivers/nce/Constants.py
@@ -0,0 +1,25 @@
+# Copyright 2022-2025 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from device.service.driver_api._Driver import (
+    RESOURCE_ENDPOINTS,
+    RESOURCE_INTERFACES,
+    RESOURCE_NETWORK_INSTANCES,
+)
+
+SPECIAL_RESOURCE_MAPPINGS = {
+    RESOURCE_ENDPOINTS: "/endpoints",
+    RESOURCE_INTERFACES: "/interfaces",
+    RESOURCE_NETWORK_INSTANCES: "/net-instances",
+}
diff --git a/src/device/service/drivers/nce/Tools.py b/src/device/service/drivers/nce/Tools.py
new file mode 100644
index 0000000000000000000000000000000000000000..f9b2f24a8df494d04d749624ea6b2e5b986944fc
--- /dev/null
+++ b/src/device/service/drivers/nce/Tools.py
@@ -0,0 +1,145 @@
+# Copyright 2022-2025 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import logging
+from typing import Any, Dict, Optional, Tuple
+
+from common.proto.kpi_sample_types_pb2 import KpiSampleType
+from common.type_checkers.Checkers import chk_attribute, chk_string, chk_type
+from device.service.driver_api._Driver import RESOURCE_ENDPOINTS
+
+from .Constants import SPECIAL_RESOURCE_MAPPINGS
+
+LOGGER = logging.getLogger(__name__)
+
+
+def process_optional_string_field(
+    endpoint_data: Dict[str, Any],
+    field_name: str,
+    endpoint_resource_value: Dict[str, Any],
+) -> None:
+    field_value = chk_attribute(
+        field_name, endpoint_data, "endpoint_data", default=None
+    )
+    if field_value is None:
+        return
+    chk_string("endpoint_data.{:s}".format(field_name), field_value)
+    if len(field_value) > 0:
+        endpoint_resource_value[field_name] = field_value
+
+
+def compose_resource_endpoint(
+    endpoint_data: Dict[str, Any],
+) -> Optional[Tuple[str, Dict]]:
+    try:
+        # Check type of endpoint_data
+        chk_type("endpoint_data", endpoint_data, dict)
+
+        # Check endpoint UUID (mandatory)
+        endpoint_uuid = chk_attribute("uuid", endpoint_data, "endpoint_data")
+        chk_string("endpoint_data.uuid", endpoint_uuid, min_length=1)
+        endpoint_resource_path = SPECIAL_RESOURCE_MAPPINGS.get(RESOURCE_ENDPOINTS)
+        endpoint_resource_key = "{:s}/endpoint[{:s}]".format(
+            endpoint_resource_path, endpoint_uuid
+        )
+        endpoint_resource_value = {"uuid": endpoint_uuid}
+
+        # Check endpoint optional string fields
+        process_optional_string_field(endpoint_data, "name", endpoint_resource_value)
+        process_optional_string_field(
+            endpoint_data, "site_location", endpoint_resource_value
+        )
+        process_optional_string_field(endpoint_data, "ce-ip", endpoint_resource_value)
+        process_optional_string_field(
+            endpoint_data, "address_ip", endpoint_resource_value
+        )
+        process_optional_string_field(
+            endpoint_data, "address_prefix", endpoint_resource_value
+        )
+        process_optional_string_field(endpoint_data, "mtu", endpoint_resource_value)
+        process_optional_string_field(
+            endpoint_data, "ipv4_lan_prefixes", endpoint_resource_value
+        )
+        process_optional_string_field(endpoint_data, "type", endpoint_resource_value)
+        process_optional_string_field(
+            endpoint_data, "context_uuid", endpoint_resource_value
+        )
+        process_optional_string_field(
+            endpoint_data, "topology_uuid", endpoint_resource_value
+        )
+
+        # Check endpoint sample types (optional)
+        endpoint_sample_types = chk_attribute(
+            "sample_types", endpoint_data, "endpoint_data", default=[]
+        )
+        chk_type("endpoint_data.sample_types", endpoint_sample_types, list)
+        sample_types = {}
+        sample_type_errors = []
+        for i, endpoint_sample_type in enumerate(endpoint_sample_types):
+            field_name = "endpoint_data.sample_types[{:d}]".format(i)
+            try:
+                chk_type(field_name, endpoint_sample_type, (int, str))
+                if isinstance(endpoint_sample_type, int):
+                    metric_name = KpiSampleType.Name(endpoint_sample_type)
+                    metric_id = endpoint_sample_type
+                elif isinstance(endpoint_sample_type, str):
+                    metric_id = KpiSampleType.Value(endpoint_sample_type)
+                    metric_name = endpoint_sample_type
+                else:
+                    str_type = str(type(endpoint_sample_type))
+                    raise Exception("Bad format: {:s}".format(str_type))  # pylint: disable=broad-exception-raised
+            except Exception as e:  # pylint: disable=broad-exception-caught
+                MSG = "Unsupported {:s}({:s}) : {:s}"
+                sample_type_errors.append(
+                    MSG.format(field_name, str(endpoint_sample_type), str(e))
+                )
+
+            metric_name = metric_name.lower().replace("kpisampletype_", "")
+            monitoring_resource_key = "{:s}/state/{:s}".format(
+                endpoint_resource_key, metric_name
+            )
+            sample_types[metric_id] = monitoring_resource_key
+
+        if len(sample_type_errors) > 0:
+            # pylint: disable=broad-exception-raised
+            raise Exception(
+                "Malformed Sample Types:\n{:s}".format("\n".join(sample_type_errors))
+            )
+
+        if len(sample_types) > 0:
+            endpoint_resource_value["sample_types"] = sample_types
+
+        if "site_location" in endpoint_data:
+            endpoint_resource_value["site_location"] = endpoint_data["site_location"]
+
+        if "ce-ip" in endpoint_data:
+            endpoint_resource_value["ce-ip"] = endpoint_data["ce-ip"]
+
+        if "address_ip" in endpoint_data:
+            endpoint_resource_value["address_ip"] = endpoint_data["address_ip"]
+
+        if "address_prefix" in endpoint_data:
+            endpoint_resource_value["address_prefix"] = endpoint_data["address_prefix"]
+
+        if "mtu" in endpoint_data:
+            endpoint_resource_value["mtu"] = endpoint_data["mtu"]
+
+        if "ipv4_lan_prefixes" in endpoint_data:
+            endpoint_resource_value["ipv4_lan_prefixes"] = endpoint_data[
+                "ipv4_lan_prefixes"
+            ]
+
+        return endpoint_resource_key, endpoint_resource_value
+    except:  # pylint: disable=bare-except
+        LOGGER.exception("Problem composing endpoint({:s})".format(str(endpoint_data)))
+        return None
diff --git a/src/device/service/drivers/nce/__init__.py b/src/device/service/drivers/nce/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..6242c89c7fa17bc5b6cc44328d8ce58438721d45
--- /dev/null
+++ b/src/device/service/drivers/nce/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2022-2025 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/src/device/service/drivers/nce/driver.py b/src/device/service/drivers/nce/driver.py
new file mode 100644
index 0000000000000000000000000000000000000000..4ac1a2b1c604a6ebe5028688dc39f545e0e1cee6
--- /dev/null
+++ b/src/device/service/drivers/nce/driver.py
@@ -0,0 +1,278 @@
+# Copyright 2022-2025 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+import logging
+import re
+import threading
+from typing import Any, Iterator, List, Optional, Tuple, Union
+
+import anytree
+import requests
+from requests.auth import HTTPBasicAuth
+
+from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method
+from common.type_checkers.Checkers import chk_length, chk_string, chk_type
+from device.service.driver_api._Driver import _Driver
+from device.service.driver_api.AnyTreeTools import (
+    TreeNode,
+    dump_subtree,
+    get_subnode,
+    set_subnode_value,
+)
+from device.service.driver_api.ImportTopologyEnum import (
+    ImportTopologyEnum,
+    get_import_topology,
+)
+
+from .Constants import SPECIAL_RESOURCE_MAPPINGS
+from .nce_fan_client import NCEClient
+from .Tools import compose_resource_endpoint
+
+LOGGER = logging.getLogger(__name__)
+
+
+RE_NCE_APP_FLOW_DATA = re.compile(r"^\/service\[[^\]]+\]\/AppFlow$")
+RE_NCE_APP_FLOW_OPERATION = re.compile(r"^\/service\[[^\]]+\]\/AppFlow\/operation$")
+
+DRIVER_NAME = "nce"
+METRICS_POOL = MetricsPool("Device", "Driver", labels={"driver": DRIVER_NAME})
+
+
+class NCEDriver(_Driver):
+    def __init__(self, address: str, port: str, **settings) -> None:
+        super().__init__(DRIVER_NAME, address, int(port), **settings)
+        self.__lock = threading.Lock()
+        self.__started = threading.Event()
+        self.__terminate = threading.Event()
+        self.__running = TreeNode(".")
+        scheme = self.settings.get("scheme", "http")
+        username = self.settings.get("username")
+        password = self.settings.get("password")
+        self.nce = NCEClient(
+            self.address,
+            self.port,
+            scheme=scheme,
+            username=username,
+            password=password,
+        )
+        self.__auth = None
+        # (
+        #     HTTPBasicAuth(username, password)
+        #     if username is not None and password is not None
+        #     else None
+        # )
+        self.__tfs_nbi_root = "{:s}://{:s}:{:d}".format(
+            scheme, self.address, int(self.port)
+        )
+        self.__timeout = int(self.settings.get("timeout", 120))
+        self.__import_topology = get_import_topology(
+            self.settings, default=ImportTopologyEnum.DEVICES
+        )
+        endpoints = self.settings.get("endpoints", [])
+        endpoint_resources = []
+        for endpoint in endpoints:
+            endpoint_resource = compose_resource_endpoint(endpoint)
+            if endpoint_resource is None:
+                continue
+            endpoint_resources.append(endpoint_resource)
+        self._set_initial_config(endpoint_resources)
+
+    def _set_initial_config(
+        self, resources: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        chk_type("resources", resources, list)
+        if len(resources) == 0:
+            return []
+        results = []
+        resolver = anytree.Resolver(pathattr="name")
+        with self.__lock:
+            for i, resource in enumerate(resources):
+                str_resource_name = "resources[#{:d}]".format(i)
+                try:
+                    chk_type(str_resource_name, resource, (list, tuple))
+                    chk_length(str_resource_name, resource, min_length=2, max_length=2)
+                    resource_key, resource_value = resource
+                    chk_string(str_resource_name, resource_key, allow_empty=False)
+                    resource_path = resource_key.split("/")
+                except Exception as e:  # pylint: disable=broad-except
+                    LOGGER.exception(
+                        "Exception validating {:s}: {:s}".format(
+                            str_resource_name, str(resource_key)
+                        )
+                    )
+                    results.append(e)  # if validation fails, store the exception
+                    continue
+
+                try:
+                    resource_value = json.loads(resource_value)
+                except:  # pylint: disable=bare-except
+                    pass
+
+                set_subnode_value(
+                    resolver, self.__running, resource_path, resource_value
+                )
+
+                results.append(True)
+        return results
+
+    def Connect(self) -> bool:
+        with self.__lock:
+            if self.__started.is_set():
+                return True
+            try:
+                ...
+            except requests.exceptions.Timeout:
+                return False
+            except Exception:  # pylint: disable=broad-except
+                return False
+            else:
+                self.__started.set()
+                return True
+
+    def Disconnect(self) -> bool:
+        with self.__lock:
+            self.__terminate.set()
+            return True
+
+    @metered_subclass_method(METRICS_POOL)
+    def GetInitialConfig(self) -> List[Tuple[str, Any]]:
+        with self.__lock:
+            return []
+
+    @metered_subclass_method(METRICS_POOL)
+    def GetConfig(
+        self, resource_keys: List[str] = []
+    ) -> List[Tuple[str, Union[Any, None, Exception]]]:
+        chk_type("resources", resource_keys, list)
+        with self.__lock:
+            if len(resource_keys) == 0:
+                return dump_subtree(self.__running)
+            results = []
+            resolver = anytree.Resolver(pathattr="name")
+            for i, resource_key in enumerate(resource_keys):
+                str_resource_name = "resource_key[#{:d}]".format(i)
+                try:
+                    chk_string(str_resource_name, resource_key, allow_empty=False)
+                    resource_key = SPECIAL_RESOURCE_MAPPINGS.get(
+                        resource_key, resource_key
+                    )
+                    resource_path = resource_key.split("/")
+                except Exception as e:  # pylint: disable=broad-except
+                    LOGGER.exception(
+                        "Exception validating {:s}: {:s}".format(
+                            str_resource_name, str(resource_key)
+                        )
+                    )
+                    results.append(
+                        (resource_key, e)
+                    )  # if validation fails, store the exception
+                    continue
+
+                resource_node = get_subnode(
+                    resolver, self.__running, resource_path, default=None
+                )
+                # if not found, resource_node is None
+                if resource_node is None:
+                    continue
+                results.extend(dump_subtree(resource_node))
+            return results
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetConfig(
+        self, resources: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        results = []
+
+        if len(resources) == 0:
+            return results
+
+        with self.__lock:
+            for resource in resources:
+                resource_key, resource_value = resource
+                LOGGER.debug("resource = {:s}".format(str(resource)))
+                if RE_NCE_APP_FLOW_OPERATION.match(resource_key):
+                    operation_type = json.loads(resource_value)["type"]
+                    results.append((resource_key, True))
+                    break
+            else:
+                raise Exception("operation type not found in resources")
+            for resource in resources:
+                LOGGER.info("resource = {:s}".format(str(resource)))
+                resource_key, resource_value = resource
+                if not RE_NCE_APP_FLOW_DATA.match(resource_key):
+                    continue
+                try:
+                    resource_value = json.loads(resource_value)
+                    if operation_type == "create":
+
+                        self.nce.create_app_flow(resource_value)
+                    elif operation_type == "delete":
+
+                        app_flow_name = resource_value["huawei-nce-app-flow:app-flows"][
+                            "app-flow"
+                        ][0]["app-name"]
+                        self.nce.delete_app_flow(app_flow_name)
+                    results.append((resource_key, True))
+                except Exception as e:  # pylint: disable=broad-except
+                    LOGGER.exception(
+                        "Unhandled error processing resource_key({:s})".format(
+                            str(resource_key)
+                        )
+                    )
+                    results.append((resource_key, e))
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def DeleteConfig(
+        self, resources: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        results = []
+        if len(resources) == 0:
+            return results
+        with self.__lock:
+            for resource in resources:
+                LOGGER.info("resource = {:s}".format(str(resource)))
+                resource_key, resource_value = resource
+                try:
+                    results.append((resource_key, True))
+                except Exception as e:  # pylint: disable=broad-except
+                    LOGGER.exception(
+                        "Unhandled error processing resource_key({:s})".format(
+                            str(resource_key)
+                        )
+                    )
+                    results.append((resource_key, e))
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def SubscribeState(
+        self, subscriptions: List[Tuple[str, float, float]]
+    ) -> List[Union[bool, Exception]]:
+        # TODO: IETF L3VPN does not support monitoring by now
+        return [False for _ in subscriptions]
+
+    @metered_subclass_method(METRICS_POOL)
+    def UnsubscribeState(
+        self, subscriptions: List[Tuple[str, float, float]]
+    ) -> List[Union[bool, Exception]]:
+        # TODO: IETF L3VPN does not support monitoring by now
+        return [False for _ in subscriptions]
+
+    def GetState(
+        self, blocking=False, terminate: Optional[threading.Event] = None
+    ) -> Iterator[Tuple[float, str, Any]]:
+        # TODO: IETF L3VPN does not support monitoring by now
+        return []
diff --git a/src/device/service/drivers/nce/nce_fan_client.py b/src/device/service/drivers/nce/nce_fan_client.py
new file mode 100644
index 0000000000000000000000000000000000000000..1c3523427ab5818b650a5eeecafc098b1c55662e
--- /dev/null
+++ b/src/device/service/drivers/nce/nce_fan_client.py
@@ -0,0 +1,94 @@
+# Copyright 2022-2025 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+from typing import Optional
+
+import requests
+from requests.auth import HTTPBasicAuth
+
+LOGGER = logging.getLogger(__name__)
+
+NCE_FAN_URL = "{:s}://{:s}:{:d}/restconf/v1/data"
+TIMEOUT = 30
+
+HTTP_OK_CODES = {
+    200,  # OK
+    201,  # Created
+    202,  # Accepted
+    204,  # No Content
+}
+
+MAPPING_STATUS = {
+    "DEVICEOPERATIONALSTATUS_UNDEFINED": 0,
+    "DEVICEOPERATIONALSTATUS_DISABLED": 1,
+    "DEVICEOPERATIONALSTATUS_ENABLED": 2,
+}
+
+MAPPING_DRIVER = {
+    "DEVICEDRIVER_UNDEFINED": 0,
+    "DEVICEDRIVER_OPENCONFIG": 1,
+    "DEVICEDRIVER_TRANSPORT_API": 2,
+    "DEVICEDRIVER_P4": 3,
+    "DEVICEDRIVER_IETF_NETWORK_TOPOLOGY": 4,
+    "DEVICEDRIVER_ONF_TR_532": 5,
+    "DEVICEDRIVER_XR": 6,
+    "DEVICEDRIVER_IETF_L2VPN": 7,
+    "DEVICEDRIVER_GNMI_OPENCONFIG": 8,
+    "DEVICEDRIVER_OPTICAL_TFS": 9,
+    "DEVICEDRIVER_IETF_ACTN": 10,
+    "DEVICEDRIVER_OC": 11,
+}
+
+HEADERS = {'Content-Type': 'application/json'}
+
+class NCEClient:
+    def __init__(
+        self,
+        address: str,
+        port: int,
+        scheme: str = "http",
+        username: Optional[str] = None,
+        password: Optional[str] = None,
+    ) -> None:
+        self._nce_fan_url = NCE_FAN_URL.format(scheme, address, port)
+        self._auth = None
+
+    def create_app_flow(self, app_flow_data: dict) -> None:
+        try:
+            app_data = app_flow_data["huawei-nce-app-flow:app-flows"]["applications"]
+            app_url = self._nce_fan_url + "/app-flows/apps"
+            LOGGER.info(f'Creating app: {app_data} URL: {app_url}')
+            requests.post(app_url, json=app_data, headers=HEADERS)
+
+            app_flow_data = {
+                "app-flow": app_flow_data["huawei-nce-app-flow:app-flows"]["app-flow"]
+            }
+            app_flow_url = self._nce_fan_url + "/app-flows"
+            LOGGER.info(f'Creating app flow: {app_flow_data} URL: {app_flow_url}')
+            requests.post(app_flow_url, json=app_flow_data, headers=HEADERS)
+        except requests.exceptions.ConnectionError:
+            raise Exception("faild to send post requests to NCE FAN")
+
+    def delete_app_flow(self, app_flow_name: str) -> None:
+        try:
+            app_url = self._nce_fan_url + f"/app-flows/apps/application={app_flow_name}"
+            LOGGER.info(f'Deleting app: {app_flow_name} URL: {app_url}')
+            requests.delete(app_url)
+
+            app_flow_url = self._nce_fan_url + f"/app-flows/app-flow={app_flow_name}"
+            LOGGER.info(f'Deleting app flow: {app_flow_name} URL: {app_flow_url}')
+            requests.delete(app_flow_url)
+        except requests.exceptions.ConnectionError:
+            raise Exception("faild to send delete request to NCE FAN")
diff --git a/src/device/tests/test_unitary_ietf_l3vpn.py b/src/device/tests/test_unitary_ietf_l3vpn.py
new file mode 100644
index 0000000000000000000000000000000000000000..728ca691332c8abee7b5d6f5ad6c151240e540ed
--- /dev/null
+++ b/src/device/tests/test_unitary_ietf_l3vpn.py
@@ -0,0 +1,345 @@
+import json
+from json import dumps
+
+import requests
+
+from device.service.drivers.ietf_l3vpn.driver import IetfL3VpnDriver
+from device.service.Tools import RESOURCE_ENDPOINTS
+
+settings = {
+    "endpoints": [
+        {
+            "uuid": "access-pe",
+            "name": "access-pe",
+            "type": "copper",
+            "ce-ip": "1.1.1.1",
+            "address_ip": "3.3.2.1",
+            "address_prefix": 24,
+            "location": "access",
+            "mtu": 1500,
+            "ipv4_lan_prefixes": [
+                {"lan": "128.32.10.0/24", "lan_tag": 10},
+                {"lan": "128.32.20.0/24", "lan_tag": 20},
+            ],
+        },
+        {
+            "uuid": "cloud-pe",
+            "name": "cloud-pe",
+            "type": "copper",
+            "ce-ip": "1.1.1.1",
+            "address_ip": "3.3.2.1",
+            "address_prefix": 24,
+            "location": "cloud",
+            "mtu": 1500,
+            "ipv4_lan_prefixes": [{"lan": "172.1.101.0/24", "lan_tag": 101}],
+        },
+    ],
+    "scheme": "http",
+    "username": "admin",
+    "password": "admin",
+    "base_url": "/restconf/v2/data",
+    "timeout": 120,
+    "verify": False,
+}
+
+post_request_data = []
+get_request_data = []
+
+
+def mock_post(*args, **kwargs):
+    post_request_data.append((args, kwargs))
+
+
+def mock_get(*args, **kwargs):
+    get_request_data.append((args, kwargs))
+
+
+driver = IetfL3VpnDriver(address="1.2.3.4", port=0, **settings)
+
+
+def test_connect(monkeypatch):
+    global post_request_data
+    global get_request_data
+    post_request_data = []
+    get_request_data = []
+    monkeypatch.setattr(requests, "post", mock_post)
+    monkeypatch.setattr(requests, "get", mock_get)
+
+    driver.Connect()
+    assert not post_request_data
+    assert len(get_request_data) == 1
+    assert get_request_data[0][0] == (
+        "http://1.2.3.4:0/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services",
+    )
+    assert list(get_request_data[0][1].keys()) == ["timeout", "verify", "auth"]
+
+
+def test_GetConfig(monkeypatch):
+    global post_request_data
+    global get_request_data
+    post_request_data = []
+    get_request_data = []
+    monkeypatch.setattr(requests, "post", mock_post)
+    monkeypatch.setattr(requests, "get", mock_get)
+
+    resources_to_get = [RESOURCE_ENDPOINTS]
+    result_GetConfig = driver.GetConfig(resources_to_get)
+    assert result_GetConfig == [
+        (
+            "/endpoints/endpoint[access-pe]",
+            {
+                "uuid": "access-pe",
+                "name": "access-pe",
+                "type": "copper",
+                "location": "access",
+                "ce-ip": "1.1.1.1",
+                "address_ip": "3.3.2.1",
+                "address_prefix": 24,
+                "mtu": 1500,
+                "ipv4_lan_prefixes": [
+                    {"lan": "128.32.10.0/24", "lan_tag": 10},
+                    {"lan": "128.32.20.0/24", "lan_tag": 20},
+                ],
+            },
+        ),
+        (
+            "/endpoints/endpoint[cloud-pe]",
+            {
+                "uuid": "cloud-pe",
+                "name": "cloud-pe",
+                "type": "copper",
+                "location": "cloud",
+                "ce-ip": "1.1.1.1",
+                "address_ip": "3.3.2.1",
+                "address_prefix": 24,
+                "mtu": 1500,
+                "ipv4_lan_prefixes": [{"lan": "172.1.101.0/24", "lan_tag": 101}],
+            },
+        ),
+    ]
+
+
+def test_SetConfig(monkeypatch):
+    global post_request_data
+    global get_request_data
+    post_request_data = []
+    get_request_data = []
+    monkeypatch.setattr(requests, "post", mock_post)
+    monkeypatch.setattr(requests, "get", mock_get)
+
+    resources = [
+        (
+            "/services/service[vpn_A]",
+            json.dumps(
+                {
+                    "uuid": "vpn_A",
+                    "src_device_name": "ip-net-controller",
+                    "src_endpoint_name": settings["endpoints"][0]["name"],
+                    "src_site_location": settings["endpoints"][0]["location"],
+                    "src_ipv4_lan_prefixes": settings["endpoints"][0][
+                        "ipv4_lan_prefixes"
+                    ],
+                    "src_ce_address": settings["endpoints"][0]["ce-ip"],
+                    "src_pe_address": settings["endpoints"][0]["address_ip"],
+                    "src_ce_pe_network_prefix": settings["endpoints"][0][
+                        "address_prefix"
+                    ],
+                    "src_mtu": settings["endpoints"][0]["mtu"],
+                    "dst_device_name": "ip-net-controller",
+                    "dst_endpoint_name": settings["endpoints"][1]["name"],
+                    "dst_site_location": settings["endpoints"][1]["location"],
+                    "dst_ipv4_lan_prefixes": settings["endpoints"][1][
+                        "ipv4_lan_prefixes"
+                    ],
+                    "dst_ce_address": settings["endpoints"][1]["ce-ip"],
+                    "dst_pe_address": settings["endpoints"][1]["address_ip"],
+                    "dst_ce_pe_network_prefix": settings["endpoints"][1][
+                        "address_prefix"
+                    ],
+                    "dst_mtu": settings["endpoints"][1]["mtu"],
+                }
+            ),
+        )
+    ]
+    result_SetConfig = driver.SetConfig(resources)
+    assert result_SetConfig == [("/services/service[vpn_A]", True)]
+    assert len(get_request_data) == 1
+    assert get_request_data[0][0] == (
+        "http://1.2.3.4:0/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services/vpn-service=vpn_A",
+    )
+    assert len(post_request_data) == 1
+    assert post_request_data[0][0] == (
+        "http://1.2.3.4:0/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services/vpn-services",
+    )
+    assert post_request_data[0][1]["json"] == {
+        "ietf-l3vpn-svc:l3vpn-svc": {
+            "vpn-services": {"vpn-service": [{"vpn-id": "vpn_A"}]},
+            "sites": {
+                "site": [
+                    {
+                        "site-id": "site_access",
+                        "management": {"type": "ietf-l3vpn-svc:customer-managed"},
+                        "locations": {"location": [{"location-id": "access"}]},
+                        "devices": {
+                            "device": [
+                                {
+                                    "device-id": "ip-net-controller",
+                                    "location": "access",
+                                }
+                            ]
+                        },
+                        "routing-protocols": {
+                            "routing-protocol": [
+                                {
+                                    "type": "ietf-l3vpn-svc:static",
+                                    "static": {
+                                        "cascaded-lan-prefixes": {
+                                            "ipv4-lan-prefixes": [
+                                                {
+                                                    "lan": "128.32.10.0/24",
+                                                    "lan-tag": 10,
+                                                    "next-hop": "3.3.2.1",
+                                                },
+                                                {
+                                                    "lan": "128.32.20.0/24",
+                                                    "lan-tag": 20,
+                                                    "next-hop": "3.3.2.1",
+                                                },
+                                            ]
+                                        }
+                                    },
+                                }
+                            ]
+                        },
+                        "site-network-accesses": {
+                            "site-network-access": [
+                                {
+                                    "site-network-access-id": "access-pe",
+                                    "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                                    "device-reference": "ip-net-controller",
+                                    "vpn-attachment": {
+                                        "vpn-id": "vpn_A",
+                                        "site-role": "ietf-l3vpn-svc:hub-role",
+                                    },
+                                    "ip-connection": {
+                                        "ipv4": {
+                                            "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                                            "addresses": {
+                                                "provider-address": "3.3.2.1",
+                                                "customer-address": "1.1.1.1",
+                                                "prefix-length": 24,
+                                            },
+                                        }
+                                    },
+                                    "service": {
+                                        "svc-mtu": 1500,
+                                        "svc-input-bandwidth": 1000000000,
+                                        "svc-output-bandwidth": 1000000000,
+                                        "qos": {
+                                            "qos-profile": {
+                                                "classes": {
+                                                    "class": [
+                                                        {
+                                                            "class-id": "src_qos_profile",
+                                                            "direction": (
+                                                                "ietf-l3vpn-svc:both",
+                                                            ),
+                                                            "latency": {
+                                                                "latency-boundary": 10
+                                                            },
+                                                            "bandwidth": {
+                                                                "guaranteed-bw-percent": 100
+                                                            },
+                                                        }
+                                                    ]
+                                                }
+                                            }
+                                        },
+                                    },
+                                }
+                            ]
+                        },
+                    },
+                    {
+                        "site-id": "site_cloud",
+                        "management": {"type": "ietf-l3vpn-svc:customer-managed"},
+                        "locations": {"location": [{"location-id": "cloud"}]},
+                        "devices": {
+                            "device": [
+                                {
+                                    "device-id": "ip-net-controller",
+                                    "location": "cloud",
+                                }
+                            ]
+                        },
+                        "routing-protocols": {
+                            "routing-protocol": [
+                                {
+                                    "type": "ietf-l3vpn-svc:static",
+                                    "static": {
+                                        "cascaded-lan-prefixes": {
+                                            "ipv4-lan-prefixes": [
+                                                {
+                                                    "lan": "172.1.101.0/24",
+                                                    "lan-tag": 101,
+                                                    "next-hop": "3.3.2.1",
+                                                }
+                                            ]
+                                        }
+                                    },
+                                }
+                            ]
+                        },
+                        "site-network-accesses": {
+                            "site-network-access": [
+                                {
+                                    "site-network-access-id": "cloud-pe",
+                                    "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                                    "device-reference": "ip-net-controller",
+                                    "vpn-attachment": {
+                                        "vpn-id": "vpn_A",
+                                        "site-role": "ietf-l3vpn-svc:spoke-role",
+                                    },
+                                    "ip-connection": {
+                                        "ipv4": {
+                                            "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                                            "addresses": {
+                                                "provider-address": "3.3.2.1",
+                                                "customer-address": "1.1.1.1",
+                                                "prefix-length": 24,
+                                            },
+                                        }
+                                    },
+                                    "service": {
+                                        "svc-mtu": 1500,
+                                        "svc-input-bandwidth": 1000000000,
+                                        "svc-output-bandwidth": 1000000000,
+                                        "qos": {
+                                            "qos-profile": {
+                                                "classes": {
+                                                    "class": [
+                                                        {
+                                                            "class-id": "dst_qos_profile",
+                                                            "direction": (
+                                                                "ietf-l3vpn-svc:both",
+                                                            ),
+                                                            "latency": {
+                                                                "latency-boundary": 10
+                                                            },
+                                                            "bandwidth": {
+                                                                "guaranteed-bw-percent": 100
+                                                            },
+                                                        }
+                                                    ]
+                                                }
+                                            }
+                                        },
+                                    },
+                                }
+                            ]
+                        },
+                    },
+                ]
+            },
+        }
+    }
diff --git a/src/nbi/service/__main__.py b/src/nbi/service/__main__.py
index 71df0517aa688c106d8d0fe544f5f6b1af5a58f3..1d470f4eac30795e2272c9145baf947f3c982ba5 100644
--- a/src/nbi/service/__main__.py
+++ b/src/nbi/service/__main__.py
@@ -31,6 +31,7 @@ from .rest_server.nbi_plugins.ietf_network_slice import register_ietf_nss
 from .rest_server.nbi_plugins.ietf_acl import register_ietf_acl
 from .rest_server.nbi_plugins.qkd_app import register_qkd_app
 from .rest_server.nbi_plugins.tfs_api import register_tfs_api
+from .rest_server.nbi_plugins import register_restconf
 from .context_subscription import register_context_subscription
 
 terminate = threading.Event()
@@ -79,6 +80,7 @@ def main():
     register_ietf_acl(rest_server)
     register_qkd_app(rest_server)
     register_tfs_api(rest_server)
+    register_restconf(rest_server)
     rest_server.start()
 
     register_context_subscription()
diff --git a/src/nbi/service/rest_server/nbi_plugins/__init__.py b/src/nbi/service/rest_server/nbi_plugins/__init__.py
index 53d5157f750bfb085125cbd33faff1cec5924e14..9b5d7920db49bab6d456aba186e6500142aad5b2 100644
--- a/src/nbi/service/rest_server/nbi_plugins/__init__.py
+++ b/src/nbi/service/rest_server/nbi_plugins/__init__.py
@@ -12,3 +12,27 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from flask.json import jsonify
+from flask_restful import Resource
+
+from nbi.service.rest_server.RestServer import RestServer
+
+from .tools.HttpStatusCodes import HTTP_CREATED
+
+URL_PREFIX = "/restconf/data"
+
+
+class BaseServer(Resource):
+    def post(self):
+        response = jsonify({})
+        response.status_code = HTTP_CREATED
+        return response
+
+
+def _add_resource(rest_server: RestServer, resource: Resource, *urls, **kwargs):
+    urls = [(URL_PREFIX + url) for url in urls]
+    rest_server.add_resource(resource, *urls, **kwargs)
+
+
+def register_restconf(rest_server: RestServer):
+    _add_resource(rest_server, BaseServer, "")
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_Service.py b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_Service.py
index 97364dff8606f1af48bab362b94b968561792411..bf3f8aabca1c04260d32a4163ec2686931f520fc 100644
--- a/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_Service.py
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_Service.py
@@ -26,7 +26,7 @@ from ..tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK
 LOGGER = logging.getLogger(__name__)
 
 class L3VPN_Service(Resource):
-    @HTTP_AUTH.login_required
+    # @HTTP_AUTH.login_required
     def get(self, vpn_id : str):
         LOGGER.debug('VPN_Id: {:s}'.format(str(vpn_id)))
         LOGGER.debug('Request: {:s}'.format(str(request)))
@@ -52,7 +52,7 @@ class L3VPN_Service(Resource):
             response.status_code = HTTP_SERVERERROR
         return response
 
-    @HTTP_AUTH.login_required
+    # @HTTP_AUTH.login_required
     def delete(self, vpn_id : str):
         LOGGER.debug('VPN_Id: {:s}'.format(str(vpn_id)))
         LOGGER.debug('Request: {:s}'.format(str(request)))
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_Services.py b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_Services.py
index 98d950952702d5cf1df8aa29edc50683e56a296e..47f6d5726225350976a67eeaacda64ceb32f0d7f 100644
--- a/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_Services.py
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_Services.py
@@ -26,11 +26,11 @@ from .YangValidator import YangValidator
 LOGGER = logging.getLogger(__name__)
 
 class L3VPN_Services(Resource):
-    @HTTP_AUTH.login_required
+    # @HTTP_AUTH.login_required
     def get(self):
         return {}
 
-    @HTTP_AUTH.login_required
+    # @HTTP_AUTH.login_required
     def post(self):
         if not request.is_json: raise UnsupportedMediaType('JSON payload is required')
         request_data : Dict = request.json
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Service.py b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Service.py
index e25270d3601ffa1cfdffa68a98305e3646602001..8f6dc86609f8c0e4d51fa02c64ab7c59a377395a 100644
--- a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Service.py
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Service.py
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -13,47 +13,61 @@
 # limitations under the License.
 
 import logging
+
 from flask.json import jsonify
 from flask_restful import Resource
+
 from common.proto.context_pb2 import SliceStatusEnum
 from common.tools.context_queries.Slice import get_slice_by_uuid
 from common.tools.grpc.Tools import grpc_message_to_json
 from context.client.ContextClient import ContextClient
 from slice.client.SliceClient import SliceClient
+
 from ..tools.Authentication import HTTP_AUTH
-from ..tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK, HTTP_SERVERERROR
+from ..tools.HttpStatusCodes import (
+    HTTP_GATEWAYTIMEOUT,
+    HTTP_NOCONTENT,
+    HTTP_OK,
+    HTTP_SERVERERROR,
+)
 
 LOGGER = logging.getLogger(__name__)
 
+
 class NSS_Service(Resource):
-    @HTTP_AUTH.login_required
-    def get(self, slice_id : str):
-        LOGGER.debug('GET Slice ID: {:s}'.format(str(slice_id)))
+    # @HTTP_AUTH.login_required
+    def get(self, slice_id: str):
+        LOGGER.debug("GET Slice ID: {:s}".format(str(slice_id)))
         try:
             context_client = ContextClient()
 
             target = get_slice_by_uuid(context_client, slice_id, rw_copy=True)
             if target is None:
-                raise Exception('Slice({:s}) not found in database'.format(str(slice_id)))
+                raise Exception(
+                    "Slice({:s}) not found in database".format(str(slice_id))
+                )
 
-            if target.slice_id.slice_uuid.uuid != slice_id: # pylint: disable=no-member
-                raise Exception('Slice retrieval failed. Wrong Slice Id was returned')
+            if target.slice_id.slice_uuid.uuid != slice_id:  # pylint: disable=no-member
+                raise Exception("Slice retrieval failed. Wrong Slice Id was returned")
 
             slice_ready_status = SliceStatusEnum.SLICESTATUS_ACTIVE
-            slice_status = target.slice_status.slice_status # pylint: disable=no-member
+            slice_status = target.slice_status.slice_status  # pylint: disable=no-member
             response = jsonify(grpc_message_to_json(target))
-            response.status_code = HTTP_OK if slice_status == slice_ready_status else HTTP_GATEWAYTIMEOUT
+            response.status_code = (
+                HTTP_OK if slice_status == slice_ready_status else HTTP_GATEWAYTIMEOUT
+            )
 
-        except Exception as e: # pylint: disable=broad-except
-            LOGGER.exception('Something went wrong Retrieving Slice({:s})'.format(str(slice_id)))
-            response = jsonify({'error': str(e)})
+        except Exception as e:  # pylint: disable=broad-except
+            LOGGER.exception(
+                "Something went wrong Retrieving Slice({:s})".format(str(slice_id))
+            )
+            response = jsonify({"error": str(e)})
             response.status_code = HTTP_SERVERERROR
         return response
 
-
-    @HTTP_AUTH.login_required
-    def delete(self, slice_id : str):
-        LOGGER.debug('DELETE Slice ID: {:s}'.format(str(slice_id)))
+    # @HTTP_AUTH.login_required
+    def delete(self, slice_id: str):
+        LOGGER.debug("DELETE Slice ID: {:s}".format(str(slice_id)))
         try:
             context_client = ContextClient()
             target = get_slice_by_uuid(context_client, slice_id)
@@ -62,17 +76,25 @@ class NSS_Service(Resource):
             response.status_code = HTTP_OK
 
             if target is None:
-                LOGGER.warning('Slice({:s}) not found in database. Nothing done.'.format(str(slice_id)))
+                LOGGER.warning(
+                    "Slice({:s}) not found in database. Nothing done.".format(
+                        str(slice_id)
+                    )
+                )
                 response.status_code = HTTP_NOCONTENT
             else:
-                if target.slice_id.slice_uuid.uuid != slice_id:  # pylint: disable=no-member
-                    raise Exception('Slice retrieval failed. Wrong Slice Id was returned')
+                if target.slice_id.slice_uuid.uuid != slice_id and target.name != slice_id:  # pylint: disable=no-member
+                    raise Exception(
+                        "Slice retrieval failed. Wrong Slice Id was returned"
+                    )
                 slice_client = SliceClient()
                 slice_client.DeleteSlice(target.slice_id)
                 LOGGER.debug(f"Slice({slice_id}) successfully deleted")
 
         except Exception as e:  # pylint: disable=broad-except
-            LOGGER.exception('Something went wrong Deleting Slice({:s})'.format(str(slice_id)))
-            response = jsonify({'error': str(e)})
+            LOGGER.exception(
+                "Something went wrong Deleting Slice({:s})".format(str(slice_id))
+            )
+            response = jsonify({"error": str(e)})
             response.status_code = HTTP_SERVERERROR
-        return response
\ No newline at end of file
+        return response
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Service_Match_Criteria.py b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Service_Match_Criteria.py
new file mode 100644
index 0000000000000000000000000000000000000000..3e1c9f73f97f0df8a2b271cb34a4852e983e77a1
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Service_Match_Criteria.py
@@ -0,0 +1,59 @@
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import logging
+from typing import Dict
+
+from flask import request
+from flask.json import jsonify
+from flask_restful import Resource
+from werkzeug.exceptions import UnsupportedMediaType
+
+from context.client.ContextClient import ContextClient
+from slice.client.SliceClient import SliceClient
+
+from ..tools.Authentication import HTTP_AUTH
+from ..tools.HttpStatusCodes import (
+    HTTP_CREATED,
+)
+from .ietf_slice_handler import IETFSliceHandler
+
+LOGGER = logging.getLogger(__name__)
+
+
+class NSS_Service_Match_Criteria(Resource):
+    # @HTTP_AUTH.login_required
+    def get(self):
+        response = jsonify({"message": "All went well!"})
+        # TODO Return list of current network-slice-services
+        return response
+
+    # @HTTP_AUTH.login_required
+    def post(self, slice_id: str, sdp_id: str):
+        if not request.is_json:
+            raise UnsupportedMediaType("JSON payload is required")
+        request_data: Dict = request.json
+        context_client = ContextClient()
+        slice_request = IETFSliceHandler.create_match_criteria(
+            request_data, slice_id, sdp_id, context_client
+        )
+        slice_client = SliceClient()
+        slice_client.UpdateSlice(slice_request)
+        slice_request = IETFSliceHandler.copy_candidate_ietf_slice_data_to_running(
+            slice_id, context_client
+        )
+        _ = context_client.SetSlice(slice_request)
+
+        response = jsonify({})
+        response.status_code = HTTP_CREATED
+        return response
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Service_Match_Criterion.py b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Service_Match_Criterion.py
new file mode 100644
index 0000000000000000000000000000000000000000..8fb8adfd98e461a43f2dc24121b84a59aaabbd6b
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Service_Match_Criterion.py
@@ -0,0 +1,48 @@
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import logging
+
+from flask.json import jsonify
+from flask_restful import Resource
+
+from context.client.ContextClient import ContextClient
+
+from ..tools.Authentication import HTTP_AUTH
+from ..tools.HttpStatusCodes import (
+    HTTP_CREATED,
+)
+from .ietf_slice_handler import IETFSliceHandler
+
+LOGGER = logging.getLogger(__name__)
+
+
+class NSS_Service_Match_Criterion(Resource):
+    # @HTTP_AUTH.login_required
+    def get(self):
+        response = jsonify({"message": "All went well!"})
+        # TODO Return list of current network-slice-services
+        return response
+
+    # @HTTP_AUTH.login_required
+    def delete(self, slice_id: str, sdp_id: str, match_criterion_id: str):
+        context_client = ContextClient()
+        slice_request = IETFSliceHandler.delete_match_criteria(
+            slice_id, sdp_id, int(match_criterion_id), context_client
+        )
+        context_client = ContextClient()
+        _ = context_client.SetSlice(slice_request)
+
+        response = jsonify({})
+        response.status_code = HTTP_CREATED
+        return response
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services.py b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services.py
index 11a73141d6bd05db851d3019903e5a6db2f5c2d6..8398917a2c5d8c553efe59551962271d91759e9e 100644
--- a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services.py
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services.py
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -11,112 +11,44 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-import json
 import logging
-import ssl
-import uuid
 from typing import Dict
+
+from flask import request
 from flask.json import jsonify
 from flask_restful import Resource
-from flask import request
-
-from common.Constants import DEFAULT_CONTEXT_NAME
-from common.proto.context_pb2 import Slice, SliceStatusEnum, EndPointId, Constraint
-from common.tools.grpc.Tools import grpc_message_to_json
-from ..tools.Authentication import HTTP_AUTH
-from ..tools.HttpStatusCodes import HTTP_BADREQUEST, HTTP_OK, HTTP_CREATED, HTTP_SERVERERROR
 from werkzeug.exceptions import UnsupportedMediaType
 
+from context.client.ContextClient import ContextClient
 from slice.client.SliceClient import SliceClient
-from .bindings import load_json_data
-from .bindings.network_slice_services import NetworkSliceServices
+
+from ..tools.HttpStatusCodes import HTTP_CREATED, HTTP_OK
+from .ietf_slice_handler import IETFSliceHandler
 
 LOGGER = logging.getLogger(__name__)
 
+
 class NSS_Services(Resource):
-    @HTTP_AUTH.login_required
-    def get(self):    
-        response = jsonify({"message": "All went well!"})
-        # TODO Return list of current network-slice-services
+    # @HTTP_AUTH.login_required
+    def get(self):
+        context_client = ContextClient()
+        ietf_slices = IETFSliceHandler.get_all_ietf_slices(context_client)
+        response = jsonify(ietf_slices)
+        response.status_code = HTTP_OK
         return response
 
-    @HTTP_AUTH.login_required
+    # @HTTP_AUTH.login_required
     def post(self):
         if not request.is_json:
-            raise UnsupportedMediaType('JSON payload is required')
-        request_data = json.dumps(request.json)
+            raise UnsupportedMediaType("JSON payload is required")
+        request_data: Dict = request.json
+        context_client = ContextClient()
+        slice_request = IETFSliceHandler.create_slice_service(
+            request_data, context_client
+        )
+        slice_client = SliceClient()
+        slice_client.CreateSlice(slice_request)
+
         response = jsonify({})
         response.status_code = HTTP_CREATED
-
-        slices: NetworkSliceServices = load_json_data(request_data, NetworkSliceServices)[0]
-        for ietf_slice in slices.slice_service:
-            slice_request: Slice = Slice()
-            # Meta information
-            # TODO implement name and owner based on "tags"
-            slice_request.slice_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME
-            slice_request.slice_id.slice_uuid.uuid = ietf_slice.service_id()
-            # TODO map with admin status of IETF Slice
-            slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED
-
-            list_endpoints = []
-            for sdp in ietf_slice.sdps().sdp:
-                endpoint = EndPointId()
-                endpoint.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME
-                endpoint.device_id.device_uuid.uuid = sdp.node_id()
-                endpoint.endpoint_uuid.uuid = sdp.sdp_id()
-                list_endpoints.append(endpoint)
-            slice_request.slice_endpoint_ids.extend(list_endpoints)
-
-            # TODO Map connectivity_groups and connectivity constructs to real connections
-            LOGGER.debug(f"Connection groups detected: {len(ietf_slice.connection_groups().connection_group())}")
-            list_constraints = []
-            for cg in ietf_slice.connection_groups().connection_group:
-                for cc in cg.connectivity_construct:
-                    if cc.slo_sle_policy.custom:
-                        with cc.slo_sle_policy.custom as slo:
-                            for metric_bound in slo.service_slo_sle_policy().metric_bounds().metric_bound:
-                                metric_type = str(metric_bound.metric_type()).casefold()
-                                if metric_type == "service-slo-two-way-bandwidth":  # TODO fix to two way!
-                                    constraint = Constraint()
-                                    metric_unit = metric_bound.metric_unit().casefold()
-                                    capacity = float(metric_bound.bound())  # Assuming capacity already in Gbps
-                                    if metric_unit == "mbps":
-                                        capacity /= 1E3
-                                    elif metric_unit != "gbps":
-                                        LOGGER.warning(f"Invalided metric unit ({metric_bound.metric_unit()}), must be Mbps or Gbps")
-                                        response.status_code = HTTP_SERVERERROR
-                                        return response
-                                    constraint.sla_capacity.capacity_gbps = capacity
-                                    list_constraints.append(constraint)
-
-                                elif metric_type == "service-slo-one-way-delay":
-                                    if metric_bound.metric_unit().casefold() == "ms":
-                                        latency = int(metric_bound.bound())
-                                    else:
-                                        LOGGER.warning(f"Invalided metric unit ({metric_bound.metric_unit()}), must be \"ms\" ")
-                                        response.status_code = HTTP_SERVERERROR
-                                        return response
-                                    constraint = Constraint()
-                                    constraint.sla_latency.e2e_latency_ms = latency
-                                    list_constraints.append(constraint)
-
-                                elif metric_type == "service-slo-availability":
-                                    availability = float(metric_bound.bound())
-                                    if availability > 100.0 or availability < 0.0:
-                                        raise Exception(f'Slice SLO availability ({availability}) must be constrained [0,100]')
-                                    constraint = Constraint()
-                                    constraint.sla_availability.availability = availability
-                                    # TODO not really necessary, remove after OFC2023
-                                    constraint.sla_availability.num_disjoint_paths = 0
-                                    constraint.sla_availability.all_active = False
-                                    list_constraints.append(constraint)
-
-            slice_request.slice_constraints.extend(list_constraints)
-            LOGGER.debug(grpc_message_to_json(slice_request))  # TODO remove
-            # TODO adding owner, needs to be recoded after updating the bindings
-            owner = request.json["data"]["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["service-tags"][0]["value"]
-            slice_request.slice_owner.owner_string = owner
-            slice_request.slice_owner.owner_uuid.uuid = str(uuid.uuid5(uuid.NAMESPACE_DNS, owner))
-            slice_client = SliceClient()
-            slice_client.CreateSlice(slice_request)
         return response
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services_Connection_Group.py b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services_Connection_Group.py
new file mode 100644
index 0000000000000000000000000000000000000000..0309c6ac475dec59d3219be79792fdef81e3d330
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services_Connection_Group.py
@@ -0,0 +1,75 @@
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import logging
+from typing import Dict
+
+from flask import request
+from flask.json import jsonify
+from flask_restful import Resource
+from werkzeug.exceptions import UnsupportedMediaType
+
+from context.client.ContextClient import ContextClient
+from slice.client.SliceClient import SliceClient
+
+from ..tools.Authentication import HTTP_AUTH
+from ..tools.HttpStatusCodes import HTTP_CREATED
+from .ietf_slice_handler import IETFSliceHandler
+
+LOGGER = logging.getLogger(__name__)
+
+
+class NSS_Service_Connection_Group(Resource):
+    # @HTTP_AUTH.login_required
+    def get(self):
+        response = jsonify({"message": "All went well!"})
+        # TODO Return list of current network-slice-services
+        return response
+
+    # @HTTP_AUTH.login_required
+    def put(self, slice_id: str, connection_group_id: str):
+        if not request.is_json:
+            raise UnsupportedMediaType("JSON payload is required")
+        request_data: Dict = request.json
+
+        context_client = ContextClient()
+        slice_request = IETFSliceHandler.update_connection_group(
+            slice_id, request_data, context_client
+        )
+        slice_client = SliceClient()
+        slice_client.UpdateSlice(slice_request)
+        slice_request = IETFSliceHandler.copy_candidate_ietf_slice_data_to_running(
+            slice_id, context_client
+        )
+        _ = context_client.SetSlice(slice_request)
+
+        response = jsonify({})
+        response.status_code = HTTP_CREATED
+        return response
+
+    # @HTTP_AUTH.login_required
+    def delete(self, slice_id: str, connection_group_id: str):
+        context_client = ContextClient()
+        slice_request = IETFSliceHandler.delete_connection_group(
+            slice_id, connection_group_id, context_client
+        )
+        slice_client = SliceClient()
+        slice_client.UpdateSlice(slice_request)
+        slice_request = IETFSliceHandler.copy_candidate_ietf_slice_data_to_running(
+            slice_id, context_client
+        )
+        _ = context_client.SetSlice(slice_request)
+
+        response = jsonify({})
+        response.status_code = HTTP_CREATED
+        return response
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services_Connection_Groups.py b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services_Connection_Groups.py
new file mode 100644
index 0000000000000000000000000000000000000000..bee8349ef1949f0eb7f633ca4cbe6de6de1abbd6
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services_Connection_Groups.py
@@ -0,0 +1,52 @@
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import logging
+from typing import Dict
+
+from flask import request
+from flask.json import jsonify
+from flask_restful import Resource
+from werkzeug.exceptions import UnsupportedMediaType
+
+from context.client.ContextClient import ContextClient
+
+from ..tools.Authentication import HTTP_AUTH
+from ..tools.HttpStatusCodes import HTTP_CREATED
+from .ietf_slice_handler import IETFSliceHandler
+
+LOGGER = logging.getLogger(__name__)
+
+
+class NSS_Service_Connection_Groups(Resource):
+    # @HTTP_AUTH.login_required
+    def get(self):
+        response = jsonify({"message": "All went well!"})
+        # TODO Return list of current network-slice-services
+        return response
+
+    # @HTTP_AUTH.login_required
+    def post(self, slice_id: str):
+        if not request.is_json:
+            raise UnsupportedMediaType("JSON payload is required")
+        request_data: Dict = request.json
+
+        context_client = ContextClient()
+        slice_request = IETFSliceHandler.create_connection_group(
+            request_data, slice_id, context_client
+        )
+        _ = context_client.SetSlice(slice_request)
+
+        response = jsonify({})
+        response.status_code = HTTP_CREATED
+        return response
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services_SDP.py b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services_SDP.py
new file mode 100644
index 0000000000000000000000000000000000000000..f1d04a858907d016dc39a5a15a0d2771e25310af
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services_SDP.py
@@ -0,0 +1,45 @@
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import logging
+from typing import Dict
+
+from flask import request
+from flask.json import jsonify
+from flask_restful import Resource
+from werkzeug.exceptions import UnsupportedMediaType
+
+from context.client.ContextClient import ContextClient
+
+from ..tools.HttpStatusCodes import HTTP_OK
+from .ietf_slice_handler import IETFSliceHandler
+
+LOGGER = logging.getLogger(__name__)
+
+
+class NSS_Service_SDP(Resource):
+    # @HTTP_AUTH.login_required
+    def get(self):
+        response = jsonify({"message": "All went well!"})
+        # TODO Return list of current network-slice-services
+        return response
+
+    # @HTTP_AUTH.login_required
+    def delete(self, slice_id: str, sdp_id: str):
+        context_client = ContextClient()
+        slice_request = IETFSliceHandler.delete_sdp(slice_id, sdp_id, context_client)
+        _ = context_client.SetSlice(slice_request)
+
+        response = jsonify({})
+        response.status_code = HTTP_OK
+        return response
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services_SDPs.py b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services_SDPs.py
new file mode 100644
index 0000000000000000000000000000000000000000..8a3fb8c4210b790dd25f9c0f8467b79ef5a86bc9
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services_SDPs.py
@@ -0,0 +1,51 @@
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import logging
+from typing import Dict
+
+from flask import request
+from flask.json import jsonify
+from flask_restful import Resource
+from werkzeug.exceptions import UnsupportedMediaType
+
+from context.client.ContextClient import ContextClient
+
+from ..tools.HttpStatusCodes import HTTP_CREATED
+from .ietf_slice_handler import IETFSliceHandler
+
+LOGGER = logging.getLogger(__name__)
+
+
+class NSS_Service_SDPs(Resource):
+    # @HTTP_AUTH.login_required
+    def get(self):
+        response = jsonify({"message": "All went well!"})
+        # TODO Return list of current network-slice-services
+        return response
+
+    # @HTTP_AUTH.login_required
+    def post(self, slice_id: str):
+        if not request.is_json:
+            raise UnsupportedMediaType("JSON payload is required")
+        request_data: Dict = request.json
+
+        context_client = ContextClient()
+        slice_request = IETFSliceHandler.create_sdp(
+            request_data, slice_id, context_client
+        )
+        _ = context_client.SetSlice(slice_request)
+
+        response = jsonify({})
+        response.status_code = HTTP_CREATED
+        return response
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/YangValidator.py b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/YangValidator.py
new file mode 100644
index 0000000000000000000000000000000000000000..77071f7f7a72ad7d46e34f118a87dc2280a2a24c
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/YangValidator.py
@@ -0,0 +1,36 @@
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import libyang, os
+from typing import Dict, Optional
+
+YANG_DIR = os.path.join(os.path.dirname(__file__), 'yang')
+
+class YangValidator:
+    def __init__(self, module_name : str) -> None:
+        self._yang_context = libyang.Context(YANG_DIR)
+        self._yang_module  = self._yang_context.load_module(module_name)
+        self._yang_module.feature_enable_all()
+
+    def parse_to_dict(self, message : Dict) -> Dict:
+        dnode : Optional[libyang.DNode] = self._yang_module.parse_data_dict(
+            message, validate_present=True, validate=True, strict=True
+        )
+        if dnode is None: raise Exception('Unable to parse Message({:s})'.format(str(message)))
+        message = dnode.print_dict()
+        dnode.free()
+        return message
+
+    def destroy(self) -> None:
+        self._yang_context.destroy()
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/__init__.py b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/__init__.py
index e900c27e96aafc248e5db1bec303cb25b5a0f2d7..db76b3b911c971df8ab81b1710f4ac80e4ccb3ad 100644
--- a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/__init__.py
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -16,16 +16,60 @@
 # Ref: https://datatracker.ietf.org/doc/draft-ietf-teas-ietf-network-slice-nbi-yang/
 
 from flask_restful import Resource
+
 from nbi.service.rest_server.RestServer import RestServer
-from .NSS_Services import NSS_Services
+
 from .NSS_Service import NSS_Service
+from .NSS_Service_Match_Criteria import NSS_Service_Match_Criteria
+from .NSS_Service_Match_Criterion import NSS_Service_Match_Criterion
+from .NSS_Services import NSS_Services
+from .NSS_Services_Connection_Group import NSS_Service_Connection_Group
+from .NSS_Services_Connection_Groups import NSS_Service_Connection_Groups
+from .NSS_Services_SDP import NSS_Service_SDP
+from .NSS_Services_SDPs import NSS_Service_SDPs
+
+URL_PREFIX = "/restconf/data/ietf-network-slice-service"
 
-URL_PREFIX = '/restconf/data/ietf-network-slice-service:ietf-nss'
 
-def _add_resource(rest_server : RestServer, resource : Resource, *urls, **kwargs):
+def _add_resource(rest_server: RestServer, resource: Resource, *urls, **kwargs):
     urls = [(URL_PREFIX + url) for url in urls]
     rest_server.add_resource(resource, *urls, **kwargs)
 
-def register_ietf_nss(rest_server : RestServer):
-    _add_resource(rest_server, NSS_Services, '/network-slice-services')
-    _add_resource(rest_server, NSS_Service, '/network-slice-services/slice-service=<string:slice_id>')
+
+def register_ietf_nss(rest_server: RestServer):
+    _add_resource(rest_server, NSS_Services, ":network-slice-services")
+    _add_resource(
+        rest_server,
+        NSS_Service,
+        ":network-slice-services/slice-service=<string:slice_id>",
+    )
+    _add_resource(
+        rest_server,
+        NSS_Service_SDPs,
+        ":network-slice-services/slice-service=<string:slice_id>/sdps",
+    )
+    _add_resource(
+        rest_server,
+        NSS_Service_SDP,
+        ":network-slice-services/slice-service=<string:slice_id>/sdps/sdp=<string:sdp_id>",
+    )
+    _add_resource(
+        rest_server,
+        NSS_Service_Connection_Groups,
+        ":network-slice-services/slice-service=<string:slice_id>/connection-groups",
+    )
+    _add_resource(
+        rest_server,
+        NSS_Service_Connection_Group,
+        ":network-slice-services/slice-service=<string:slice_id>/connection-groups/connection-group=<string:connection_group_id>",
+    )
+    _add_resource(
+        rest_server,
+        NSS_Service_Match_Criteria,
+        ":network-slice-services/slice-service=<string:slice_id>/sdps/sdp=<string:sdp_id>/service-match-criteria",
+    )
+    _add_resource(
+        rest_server,
+        NSS_Service_Match_Criterion,
+        ":network-slice-services/slice-service=<string:slice_id>/sdps/sdp=<string:sdp_id>/service-match-criteria/match-criterion=<string:match_criterion_id>",
+    )
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/ietf_slice_handler.py b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/ietf_slice_handler.py
new file mode 100644
index 0000000000000000000000000000000000000000..80ce4c6b78d446ff1e08a750f236e0c143e1ba57
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/ietf_slice_handler.py
@@ -0,0 +1,640 @@
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+import logging
+import uuid
+from typing import Dict, List, Optional
+
+from common.Constants import DEFAULT_CONTEXT_NAME
+from common.proto.context_pb2 import (
+    ConfigRule,
+    Constraint,
+    DeviceId,
+    Device,
+    Empty,
+    EndPointId,
+    ServiceConfig,
+    Slice,
+    SliceStatusEnum,
+)
+from common.tools.context_queries.Slice import get_slice_by_defualt_name
+from common.tools.grpc.ConfigRules import update_config_rule_custom
+from common.tools.object_factory.Device import json_device_id
+from common.DeviceTypes import DeviceTypeEnum
+from context.client import ContextClient
+
+from .YangValidator import YangValidator
+
+LOGGER = logging.getLogger(__name__)
+
+
+RUNNING_RESOURCE_KEY = "running_ietf_slice"
+CANDIDATE_RESOURCE_KEY = "candidate_ietf_slice"
+ADDRESS_PREFIX = 24
+RAISE_IF_DIFFERS = False
+
+
+def validate_ietf_slice_data(request_data: Dict) -> None:
+    """
+    Validate the provided IETF slice data against the YANG model.
+    """
+    yang_validator = YangValidator("ietf-network-slice-service")
+    _ = yang_validator.parse_to_dict(request_data)
+    yang_validator.destroy()
+
+
+def get_custom_config_rule(
+    service_config: ServiceConfig, resource_key: str
+) -> Optional[ConfigRule]:
+    """
+    Retrieve the custom config rule with the given resource_key from a ServiceConfig.
+    """
+    for cr in service_config.config_rules:
+        if (
+            cr.WhichOneof("config_rule") == "custom"
+            and cr.custom.resource_key == resource_key
+        ):
+            return cr
+    return None
+
+
+def get_ietf_data_from_config(slice_request: Slice, resource_key: str) -> Dict:
+    """
+    Retrieve the IETF data (as a Python dict) from a slice's config rule for the specified resource_key.
+    Raises an exception if not found.
+    """
+    config_rule = get_custom_config_rule(slice_request.slice_config, resource_key)
+    if not config_rule:
+        raise Exception(f"IETF data not found for resource_key: {resource_key}")
+    return json.loads(config_rule.custom.resource_value)
+
+
+def update_ietf_data_in_config(
+    slice_request: Slice, resource_key: str, ietf_data: Dict
+) -> None:
+    """
+    Update the slice config rule (identified by resource_key) with the provided IETF data.
+    """
+    fields = {name: (value, RAISE_IF_DIFFERS) for name, value in ietf_data.items()}
+    update_config_rule_custom(
+        slice_request.slice_config.config_rules, resource_key, fields
+    )
+
+
+def build_constraints_from_connection_group(connection_group: dict) -> List[Constraint]:
+    """
+    Build a list of Constraints from the 'metric-bound' data in a connection group.
+    """
+    constraints = []
+    metric_bounds = connection_group["connectivity-construct"][0][
+        "service-slo-sle-policy"
+    ]["slo-policy"]["metric-bound"]
+
+    for metric in metric_bounds:
+        metric_type = metric["metric-type"]
+        if metric_type == "ietf-nss:one-way-delay-maximum":
+            bound_value = float(metric["bound"])
+            constraint = Constraint()
+            constraint.sla_latency.e2e_latency_ms = bound_value
+            constraints.append(constraint)
+        elif metric_type == "ietf-nss:one-way-bandwidth":
+            bound_value = float(metric["bound"])
+            constraint = Constraint()
+            # Convert from Mbps to Gbps if needed
+            constraint.sla_capacity.capacity_gbps = bound_value / 1.0e3
+            constraints.append(constraint)
+
+    return constraints
+
+
+def get_endpoint_controller_type(
+    endpoint: EndPointId, context_client: ContextClient
+) -> str:
+    """
+    Retrieve the device type of an endpoint's controller device, if any; otherwise returns an empty string.
+    """
+    endpoint_device: Device = context_client.GetDevice(endpoint.device_id)
+    if endpoint_device.controller_id == DeviceId():
+        return ""
+    controller = context_client.GetDevice(endpoint_device.controller_id)
+    if controller is None:
+        controller_uuid = endpoint_device.controller_id.device_uuid.uuid
+        raise Exception(f"Controller device {controller_uuid} not found")
+    return controller.device_type
+
+
+def sort_endpoints(
+    endpoints_list: List[EndPointId],
+    sdps: List,
+    connection_group: Dict,
+    context_client: ContextClient,
+) -> List[EndPointId]:
+    """
+    Sort the endpoints_list based on controller type:
+      - If the first endpoint is an NCE, keep order.
+      - If the last endpoint is an NCE, reverse order.
+      - Otherwise, use the 'p2p-sender-sdp' from the connection group to decide.
+    """
+    if not endpoints_list:
+        return endpoints_list
+
+    first_ep = endpoints_list[0]
+    last_ep = endpoints_list[-1]
+    first_controller_type = get_endpoint_controller_type(first_ep, context_client)
+    last_controller_type = get_endpoint_controller_type(last_ep, context_client)
+
+    if first_controller_type == DeviceTypeEnum.NCE.value:
+        return endpoints_list
+    elif last_controller_type == DeviceTypeEnum.NCE.value:
+        return endpoints_list[::-1]
+
+    src_sdp_id = connection_group["connectivity-construct"][0]["p2p-sender-sdp"]
+    sdp_id_name_mapping = {sdp["id"]: sdp["node-id"] for sdp in sdps}
+    if endpoints_list[0].device_id.device_uuid.uuid == sdp_id_name_mapping[src_sdp_id]:
+        return endpoints_list
+    return endpoints_list[::-1]
+
+
+def replace_ont_endpoint_with_emu_dc(
+    endpoint_list: List[EndPointId], context_client: ContextClient
+) -> List[EndPointId]:
+    """
+    Replace an ONT endpoint in endpoint_list with an 'emu-datacenter' endpoint if found.
+    One endpoint must be managed (controller_id != empty), the other must be unmanaged.
+    """
+    if len(endpoint_list) != 2:
+        raise Exception(
+            "Expecting exactly two endpoints to handle ONT -> emu-dc replacement"
+        )
+
+    link_list = context_client.ListLinks(Empty())
+    links = list(link_list.links)
+    devices_list = context_client.ListDevices(Empty())
+    devices = devices_list.devices
+
+    uuid_name_map = {d.device_id.device_uuid.uuid: d.name for d in devices}
+    uuid_device_map = {d.device_id.device_uuid.uuid: d for d in devices}
+    name_device_map = {d.name: d for d in devices}
+
+    endpoint_id_1, endpoint_id_2 = endpoint_list
+    device_uuid_1 = endpoint_id_1.device_id.device_uuid.uuid
+    device_uuid_2 = endpoint_id_2.device_id.device_uuid.uuid
+
+    device_1 = name_device_map.get(device_uuid_1)
+    device_2 = name_device_map.get(device_uuid_2)
+
+    if not device_1 or not device_2:
+        raise Exception("One or both devices not found in name_device_map")
+
+    # Check if the first endpoint is managed
+    if device_1.controller_id != DeviceId():
+        for link in links:
+            link_endpoints = list(link.link_endpoint_ids)
+            link_ep_1, link_ep_2 = link_endpoints
+            if (
+                device_uuid_1 == uuid_name_map.get(link_ep_1.device_id.device_uuid.uuid)
+                and uuid_device_map[link_ep_2.device_id.device_uuid.uuid].device_type
+                == "emu-datacenter"
+            ):
+                endpoint_list[0] = link_ep_2
+                break
+    # Otherwise, check if the second endpoint is managed
+    elif device_2.controller_id != DeviceId():
+        for link in links:
+            link_endpoints = list(link.link_endpoint_ids)
+            link_ep_1, link_ep_2 = link_endpoints
+            if (
+                device_uuid_2 == uuid_name_map.get(link_ep_1.device_id.device_uuid.uuid)
+                and uuid_device_map[link_ep_2.device_id.device_uuid.uuid].device_type
+                == "emu-datacenter"
+            ):
+                endpoint_list[1] = link_ep_2
+                break
+    else:
+        raise Exception(
+            "One endpoint should be managed by a controller and the other should not be"
+        )
+
+    return endpoint_list
+
+
+class IETFSliceHandler:
+    @staticmethod
+    def get_all_ietf_slices(context_client: ContextClient) -> Dict:
+        """
+        Retrieve all IETF slices from the (single) context. Expects exactly one context in the system.
+        """
+        existing_context_ids = context_client.ListContextIds(Empty())
+        context_ids = list(existing_context_ids.context_ids)
+        if len(context_ids) != 1:
+            raise Exception("Number of contexts should be exactly 1")
+
+        slices_list = context_client.ListSlices(context_ids[0])
+        slices = slices_list.slices
+
+        ietf_slices = {"network-slice-services": {"slice-service": []}}
+        for slc in slices:
+            candidate_cr = get_custom_config_rule(
+                slc.slice_config, CANDIDATE_RESOURCE_KEY
+            )
+            if not candidate_cr:
+                # Skip slices that don't have the candidate_ietf_slice data
+                continue
+            candidate_ietf_data = json.loads(candidate_cr.custom.resource_value)
+            ietf_slices["network-slice-services"]["slice-service"].append(
+                candidate_ietf_data["network-slice-services"]["slice-service"][0]
+            )
+        return ietf_slices
+
+    @staticmethod
+    def create_slice_service(
+        request_data: dict, context_client: ContextClient
+    ) -> Slice:
+        """
+        Create a new slice service from the provided IETF data, applying validations and constructing a Slice object.
+        """
+        # Ensure the top-level key is "network-slice-services"
+        if "network-slice-services" not in request_data:
+            request_data = {"network-slice-services": request_data}
+
+        validate_ietf_slice_data(request_data)
+        slice_service = request_data["network-slice-services"]["slice-service"][0]
+
+        slice_id = slice_service["id"]
+        sdps = slice_service["sdps"]["sdp"]
+        if len(sdps) != 2:
+            raise Exception("Number of SDPs should be exactly 2")
+
+        connection_groups = slice_service["connection-groups"]["connection-group"]
+        slice_request = Slice()
+        slice_request.slice_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME
+        slice_request.slice_id.slice_uuid.uuid = slice_id
+        slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED
+
+        list_endpoints = []
+        endpoint_config_rules = []
+        connection_group_ids = set()
+
+        # Build endpoints from SDPs
+        for sdp in sdps:
+            attachment_circuits = sdp["attachment-circuits"]["attachment-circuit"]
+            if len(attachment_circuits) != 1:
+                raise Exception("Each SDP must have exactly 1 attachment-circuit")
+
+            endpoint = EndPointId()
+            endpoint.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME
+            device_uuid = sdp["node-id"]
+            endpoint.device_id.device_uuid.uuid = device_uuid
+            endpoint_uuid = attachment_circuits[0]["ac-tp-id"]
+            endpoint.endpoint_uuid.uuid = endpoint_uuid
+            list_endpoints.append(endpoint)
+
+            # Keep track of connection-group-id from each SDP
+            connection_group_ids.add(
+                sdp["service-match-criteria"]["match-criterion"][0][
+                    "target-connection-group-id"
+                ]
+            )
+
+            # Endpoint-specific config rule fields
+            endpoint_config_rule_fields = {
+                "address_ip": (endpoint_uuid, RAISE_IF_DIFFERS),
+                "address_prefix": (ADDRESS_PREFIX, RAISE_IF_DIFFERS),
+            }
+            endpoint_config_rules.append(
+                (
+                    f"/device[{device_uuid}]/endpoint[{endpoint_uuid}]/settings",
+                    endpoint_config_rule_fields,
+                )
+            )
+
+        if len(connection_group_ids) != 1:
+            raise Exception("SDPs do not share a common connection-group-id")
+
+        # Build constraints from the matching connection group
+        unique_cg_id = connection_group_ids.pop()
+        found_cg = next(
+            (cg for cg in connection_groups if cg["id"] == unique_cg_id), None
+        )
+        if not found_cg:
+            raise Exception("The connection group referenced by the SDPs was not found")
+
+        list_constraints = build_constraints_from_connection_group(found_cg)
+
+        # Sort endpoints and optionally replace the ONT endpoint
+        list_endpoints = sort_endpoints(list_endpoints, sdps, found_cg, context_client)
+        list_endpoints = replace_ont_endpoint_with_emu_dc(
+            list_endpoints, context_client
+        )
+
+        slice_request.slice_endpoint_ids.extend(list_endpoints)
+        slice_request.slice_constraints.extend(list_constraints)
+
+        # Set slice owner
+        slice_request.slice_owner.owner_string = slice_id
+        slice_request.slice_owner.owner_uuid.uuid = str(
+            uuid.uuid5(uuid.NAMESPACE_DNS, slice_id)
+        )
+
+        # Update slice config with IETF data (both running and candidate)
+        ietf_slice_fields = {
+            name: (value, RAISE_IF_DIFFERS) for name, value in request_data.items()
+        }
+        update_config_rule_custom(
+            slice_request.slice_config.config_rules,
+            RUNNING_RESOURCE_KEY,
+            ietf_slice_fields,
+        )
+        update_config_rule_custom(
+            slice_request.slice_config.config_rules,
+            CANDIDATE_RESOURCE_KEY,
+            ietf_slice_fields,
+        )
+
+        # Update endpoint config rules
+        for ep_cr_key, ep_cr_fields in endpoint_config_rules:
+            update_config_rule_custom(
+                slice_request.slice_config.config_rules, ep_cr_key, ep_cr_fields
+            )
+
+        return slice_request
+
+    @staticmethod
+    def create_sdp(
+        request_data: dict, slice_uuid: str, context_client: ContextClient
+    ) -> Slice:
+        """
+        Add a new SDP to an existing slice, updating the candidate IETF data.
+        """
+        sdps = request_data["sdp"]
+        if len(sdps) != 1:
+            raise Exception("Number of SDPs to create must be exactly 1")
+
+        new_sdp = sdps[0]
+        slice_request = get_slice_by_defualt_name(
+            context_client, slice_uuid, rw_copy=False
+        )
+        ietf_data = get_ietf_data_from_config(slice_request, CANDIDATE_RESOURCE_KEY)
+
+        slice_service = ietf_data["network-slice-services"]["slice-service"][0]
+        slice_sdps = slice_service["sdps"]["sdp"]
+        slice_sdps.append(new_sdp)
+
+        # Save updated IETF data
+        update_ietf_data_in_config(slice_request, CANDIDATE_RESOURCE_KEY, ietf_data)
+        return slice_request
+
+    @staticmethod
+    def delete_sdp(
+        slice_uuid: str, sdp_id: str, context_client: ContextClient
+    ) -> Slice:
+        """
+        Delete the specified SDP from an existing slice's candidate IETF data.
+        """
+        slice_request = get_slice_by_defualt_name(
+            context_client, slice_uuid, rw_copy=False
+        )
+        ietf_data = get_ietf_data_from_config(slice_request, CANDIDATE_RESOURCE_KEY)
+
+        slice_service = ietf_data["network-slice-services"]["slice-service"][0]
+        slice_sdps = slice_service["sdps"]["sdp"]
+
+        # Find and remove the matching SDP
+        sdp_idx = next(
+            (i for i, sdp in enumerate(slice_sdps) if sdp["id"] == sdp_id), None
+        )
+        if sdp_idx is None:
+            raise Exception(f"SDP with id '{sdp_id}' not found in slice '{slice_uuid}'")
+        slice_sdps.pop(sdp_idx)
+
+        update_ietf_data_in_config(slice_request, CANDIDATE_RESOURCE_KEY, ietf_data)
+        return slice_request
+
+    @staticmethod
+    def create_connection_group(
+        request_data: dict, slice_id: str, context_client: ContextClient
+    ) -> Slice:
+        """
+        Add a new connection group to an existing slice's candidate IETF data.
+        """
+        connection_groups = request_data["connection-group"]
+        if len(connection_groups) != 1:
+            raise Exception("Number of connection groups to create must be exactly 1")
+
+        new_connection_group = connection_groups[0]
+        slice_request = get_slice_by_defualt_name(
+            context_client, slice_id, rw_copy=False
+        )
+        ietf_data = get_ietf_data_from_config(slice_request, CANDIDATE_RESOURCE_KEY)
+
+        slice_service = ietf_data["network-slice-services"]["slice-service"][0]
+        slice_connection_groups = slice_service["connection-groups"]["connection-group"]
+        slice_connection_groups.append(new_connection_group)
+
+        # Validate the updated data, then save
+        validate_ietf_slice_data(ietf_data)
+        update_ietf_data_in_config(slice_request, CANDIDATE_RESOURCE_KEY, ietf_data)
+        return slice_request
+
+    @staticmethod
+    def update_connection_group(
+        slice_name: str,
+        updated_connection_group: dict,
+        context_client: ContextClient,
+    ) -> Slice:
+        """
+        Update an existing connection group in the candidate IETF data.
+        """
+        slice_request = get_slice_by_defualt_name(
+            context_client, slice_name, rw_copy=False
+        )
+        candidate_ietf_data = get_ietf_data_from_config(
+            slice_request, CANDIDATE_RESOURCE_KEY
+        )
+
+        slice_service = candidate_ietf_data["network-slice-services"]["slice-service"][
+            0
+        ]
+        slice_connection_groups = slice_service["connection-groups"]["connection-group"]
+
+        cg_id = updated_connection_group["id"]
+        cg_idx = next(
+            (i for i, cg in enumerate(slice_connection_groups) if cg["id"] == cg_id),
+            None,
+        )
+        if cg_idx is None:
+            raise Exception(f"Connection group with id '{cg_id}' not found")
+
+        slice_connection_groups[cg_idx] = updated_connection_group
+        update_ietf_data_in_config(
+            slice_request, CANDIDATE_RESOURCE_KEY, candidate_ietf_data
+        )
+
+        slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED
+        return slice_request
+
+    @staticmethod
+    def delete_connection_group(
+        slice_uuid: str, connection_group_id: str, context_client: ContextClient
+    ) -> Slice:
+        """
+        Remove an existing connection group from the candidate IETF data of a slice.
+        """
+        slice_request = get_slice_by_defualt_name(
+            context_client, slice_uuid, rw_copy=False
+        )
+        candidate_ietf_data = get_ietf_data_from_config(
+            slice_request, CANDIDATE_RESOURCE_KEY
+        )
+
+        slice_service = candidate_ietf_data["network-slice-services"]["slice-service"][
+            0
+        ]
+        slice_connection_groups = slice_service["connection-groups"]["connection-group"]
+
+        cg_idx = next(
+            (
+                i
+                for i, cg in enumerate(slice_connection_groups)
+                if cg["id"] == connection_group_id
+            ),
+            None,
+        )
+        if cg_idx is None:
+            raise Exception(
+                f"Connection group with id '{connection_group_id}' not found"
+            )
+
+        slice_connection_groups.pop(cg_idx)
+        update_ietf_data_in_config(
+            slice_request, CANDIDATE_RESOURCE_KEY, candidate_ietf_data
+        )
+
+        slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED
+        return slice_request
+
+    @staticmethod
+    def create_match_criteria(
+        request_data: dict, slice_name: str, sdp_id: str, context_client: ContextClient
+    ) -> Slice:
+        """
+        Create a new match-criterion for the specified SDP in a slice's candidate IETF data.
+        """
+        match_criteria = request_data["match-criterion"]
+        if len(match_criteria) != 1:
+            raise Exception(
+                "Number of match-criterion entries to create must be exactly 1"
+            )
+
+        new_match_criterion = match_criteria[0]
+        target_connection_group_id = new_match_criterion["target-connection-group-id"]
+
+        slice_request = get_slice_by_defualt_name(
+            context_client, slice_name, rw_copy=False
+        )
+        ietf_data = get_ietf_data_from_config(slice_request, CANDIDATE_RESOURCE_KEY)
+
+        slice_service = ietf_data["network-slice-services"]["slice-service"][0]
+        connection_groups = slice_service["connection-groups"]["connection-group"]
+        sdps = slice_service["sdps"]["sdp"]
+
+        # Find the referenced connection group
+        found_cg = next(
+            (cg for cg in connection_groups if cg["id"] == target_connection_group_id),
+            None,
+        )
+        if not found_cg:
+            raise Exception(
+                f"Connection group '{target_connection_group_id}' not found"
+            )
+
+        # Build constraints from that connection group
+        list_constraints = build_constraints_from_connection_group(found_cg)
+
+        # Add match-criterion to the relevant SDP
+        sdp_to_update = next((s for s in sdps if s["id"] == sdp_id), None)
+        if not sdp_to_update:
+            raise Exception(f"SDP '{sdp_id}' not found")
+
+        sdp_to_update["service-match-criteria"]["match-criterion"].append(
+            new_match_criterion
+        )
+
+        # Update constraints at the slice level as needed
+        del slice_request.slice_constraints[:]
+        slice_request.slice_constraints.extend(list_constraints)
+        slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED
+
+        update_ietf_data_in_config(slice_request, CANDIDATE_RESOURCE_KEY, ietf_data)
+        return slice_request
+
+    @staticmethod
+    def delete_match_criteria(
+        slice_uuid: str,
+        sdp_id: str,
+        match_criterion_id: int,
+        context_client: ContextClient,
+    ) -> Slice:
+        """
+        Delete the specified match-criterion from an SDP in the slice's candidate IETF data.
+        """
+        slice_request = get_slice_by_defualt_name(
+            context_client, slice_uuid, rw_copy=False
+        )
+        ietf_data = get_ietf_data_from_config(slice_request, CANDIDATE_RESOURCE_KEY)
+
+        slice_service = ietf_data["network-slice-services"]["slice-service"][0]
+        sdps = slice_service["sdps"]["sdp"]
+
+        # Find and modify the specified SDP
+        sdp_to_update = next((s for s in sdps if s["id"] == sdp_id), None)
+        if not sdp_to_update:
+            raise Exception(f"SDP '{sdp_id}' not found in slice '{slice_uuid}'")
+
+        match_criteria = sdp_to_update["service-match-criteria"]["match-criterion"]
+        mc_index = next(
+            (
+                i
+                for i, m in enumerate(match_criteria)
+                if m["index"] == match_criterion_id
+            ),
+            None,
+        )
+        if mc_index is None:
+            raise Exception(
+                f"No match-criterion with index '{match_criterion_id}' found in SDP '{sdp_id}'"
+            )
+
+        match_criteria.pop(mc_index)
+        update_ietf_data_in_config(slice_request, CANDIDATE_RESOURCE_KEY, ietf_data)
+        return slice_request
+
+    @staticmethod
+    def copy_candidate_ietf_slice_data_to_running(
+        slice_uuid: str, context_client: ContextClient
+    ) -> Slice:
+        """
+        Copy candidate IETF slice data to the running IETF slice data for a given slice.
+        """
+        slice_request = get_slice_by_defualt_name(
+            context_client, slice_uuid, rw_copy=False
+        )
+        candidate_ietf_data = get_ietf_data_from_config(
+            slice_request, CANDIDATE_RESOURCE_KEY
+        )
+        update_ietf_data_in_config(
+            slice_request, RUNNING_RESOURCE_KEY, candidate_ietf_data
+        )
+        return slice_request
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-ac-common@2023-11-13.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-ac-common@2023-11-13.yang
new file mode 100644
index 0000000000000000000000000000000000000000..170e70fff67242b380fc984d815e3d83557eca06
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-ac-common@2023-11-13.yang
@@ -0,0 +1,1651 @@
+module ietf-ac-common {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-ac-common";
+  prefix ac-common;
+
+  import ietf-vpn-common {
+    prefix vpn-common;
+    reference
+      "RFC 9181: A Common YANG Data Model for Layer 2 and Layer 3
+                 VPNs";
+  }
+  import ietf-netconf-acm {
+    prefix nacm;
+    reference
+      "RFC 8341: Network Configuration Access Control Model";
+  }
+  import ietf-inet-types {
+    prefix inet;
+    reference
+      "RFC 6991: Common YANG Data Types, Section 4";
+  }
+  import ietf-yang-types {
+    prefix yang;
+    reference
+      "RFC 6991: Common YANG Data Types, Section 3";
+  }
+  import ietf-key-chain {
+    prefix key-chain;
+    reference
+      "RFC 8177: YANG Data Model for Key Chains";
+  }
+
+  organization
+    "IETF OPSAWG (Operations and Management Area Working Group)";
+  contact
+    "WG Web:   <https://datatracker.ietf.org/wg/opsawg/>
+     WG List:  <mailto:opsawg@ietf.org>
+
+     Editor:   Mohamed Boucadair
+               <mailto:mohamed.boucadair@orange.com>
+     Author:   Richard Roberts
+               <mailto:rroberts@juniper.net>
+     Author:   Oscar Gonzalez de Dios
+               <mailto:oscar.gonzalezdedios@telefonica.com>
+     Author:   Samier Barguil
+               <mailto:ssamier.barguil_giraldo@nokia.com>
+     Author:   Bo Wu
+               <mailto:lana.wubo@huawei.com>";
+  description
+    "This YANG module defines a common attachment circuit (AC)
+     YANG model.
+
+     Copyright (c) 2024 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Revised BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC XXXX; see the
+     RFC itself for full legal notices.";
+
+  revision 2023-11-13 {
+    description
+      "Initial revision.";
+    reference
+      "RFC XXXX: A Common YANG Data Model for Attachment Circuits";
+  }
+
+  /****************************Features************************/
+
+  feature layer2-ac {
+    description
+      "Indicates support of Layer 2 ACs.";
+  }
+
+  feature layer3-ac {
+    description
+      "Indicates support of Layer 3 ACs.";
+  }
+
+  feature server-assigned-reference {
+    description
+      "This feature indicates support for server-generated references
+       and use of such references to access related resources.";
+  }
+
+  /****************************Identities************************/
+  // IP address allocation types
+
+  identity address-allocation-type {
+    description
+      "Base identity for address allocation type in the AC.";
+  }
+
+  identity provider-dhcp {
+    base address-allocation-type;
+    description
+      "The provider's network provides a DHCP service to the
+       customer.";
+  }
+
+  identity provider-dhcp-relay {
+    base address-allocation-type;
+    description
+      "The provider's network provides a DHCP relay service to the
+       customer.";
+  }
+
+  identity provider-dhcp-slaac {
+    if-feature "vpn-common:ipv6";
+    base address-allocation-type;
+    description
+      "The provider's network provides a DHCP service to the customer
+       as well as IPv6 Stateless Address Autoconfiguration (SLAAC).";
+    reference
+      "RFC 4862: IPv6 Stateless Address Autoconfiguration";
+  }
+
+  identity static-address {
+    base address-allocation-type;
+    description
+      "The provider's network provides static IP addressing to the
+       customer.";
+  }
+
+  identity slaac {
+    if-feature "vpn-common:ipv6";
+    base address-allocation-type;
+    description
+      "The provider's network uses IPv6 SLAAC to provide addressing
+       to the customer.";
+    reference
+      "RFC 4862: IPv6 Stateless Address Autoconfiguration";
+  }
+
+  identity dynamic-infra {
+    base address-allocation-type;
+    description
+      "The IP address is dynamically allocated by the hosting
+       infrastrcture.";
+  }
+
+  // next-hop actions
+
+  identity local-defined-next-hop {
+    description
+      "Base identity of local defined next hops.";
+  }
+
+  identity discard {
+    base local-defined-next-hop;
+    description
+      "Indicates an action to discard traffic for the corresponding
+       destination. For example, this can be used to black-hole
+       traffic.";
+  }
+
+  identity local-link {
+    base local-defined-next-hop;
+    description
+      "Treat traffic towards addresses within the specified next-hop
+       prefix as though they are connected to a local link.";
+  }
+
+  // Layer 2 tunnel types
+
+  identity l2-tunnel-type {
+    description
+      "Base identity for Layer 2 tunnel selection for an AC.";
+  }
+
+  identity pseudowire {
+    base l2-tunnel-type;
+    description
+      "Pseudowire tunnel termination for the AC.";
+  }
+
+  identity vpls {
+    base l2-tunnel-type;
+    description
+      "Virtual Private LAN Service (VPLS) tunnel termination for
+       the AC.";
+  }
+
+  identity vxlan {
+    base l2-tunnel-type;
+    description
+      "Virtual eXtensible Local Area Network (VXLAN) tunnel
+       termination for the AC.";
+  }
+
+  // Layer 3 tunnel types
+
+  identity l3-tunnel-type {
+    description
+      "Base identity for Layer 3 tunnel selection for an AC.";
+  }
+
+  identity ip-in-ip {
+    base l3-tunnel-type;
+    description
+      "IP in IP Tunneling.";
+  }
+
+  identity ipsec {
+    base l3-tunnel-type;
+    description
+      "IP Security (IPsec).";
+  }
+
+  identity gre {
+    base l3-tunnel-type;
+    description
+      "Generic Routing Encapsulation (GRE).";
+  }
+
+  // Tagging precedence
+
+  identity precedence-type {
+    description
+      "Redundancy type. The service can be created with primary and
+       secondary tagging.";
+  }
+
+  identity primary {
+    base precedence-type;
+    description
+      "Identifies the main attachment circuit.";
+  }
+
+  identity secondary {
+    base precedence-type;
+    description
+      "Identifies the secondary attachment circuit.";
+  }
+  // AC Type
+
+  identity role {
+    description
+      "Base identity for the network role of an AC.";
+  }
+
+  identity uni {
+    base role;
+      description
+        "User-to-Network Interface (UNI).";
+  }
+
+  identity nni {
+    base role;
+    description
+      "Network-to-Network Interface (NNI).";
+  }
+
+  identity public-nni {
+    base role;
+    description
+      "Public peering.";
+  }
+
+  // More Admin status types
+
+  identity awaiting-validation {
+    base vpn-common:administrative-status;
+    description
+      "This administrative status reflects that a request is
+       pending an adiministrator approval.";
+  }
+
+  identity awaiting-processing {
+    base vpn-common:administrative-status;
+    description
+      "This administrative status reflects that a request was
+       approved and validated, but is awaiting more processing
+       before activation.";
+  }
+
+  identity admin-prohibited {
+    base vpn-common:administrative-status;
+    description
+      "This administrative status reflects that a request cannot
+       be handled because of administrative policies.";
+  }
+  identity rejected {
+    base vpn-common:administrative-status;
+    description
+      "This administrative status reflects that a request was
+       rejected because, e.g., there are no sufficient resources
+       or other reasons not covered by the other status types.";
+  }
+
+  identity bgp-role {
+    description
+      "Used to indicate BGP role when establishing a BGP session.";
+    reference
+      "RFC 9234: Route Leak Prevention and Detection Using
+                 Roles in UPDATE and OPEN Messages, Section 4";
+  }
+
+  identity provider {
+    base bgp-role;
+    description
+      "The local AS is a transit provider of the remote AS.";
+  }
+
+  identity client {
+    base bgp-role;
+    description
+      "The local AS is a transit provider of the remote AS.";
+  }
+
+  identity rs {
+    base bgp-role;
+    description
+      "The local AS is a Route Server (RS).";
+  }
+
+  identity rs-client {
+    base bgp-role;
+    description
+      "The local AS is a client of an RS and the RS is the
+       remote AS.";
+  }
+
+  identity peer {
+    base bgp-role;
+    description
+      "The local and remote ASes have a peering relationship.";
+  }
+
+  /****************************Typedefs************************/
+  typedef predefined-next-hop {
+    type identityref {
+      base local-defined-next-hop;
+    }
+    description
+      "Predefined next-hop designation for locally generated
+       routes.";
+  }
+
+  typedef area-address {
+    type string {
+      pattern '[0-9A-Fa-f]{2}(\.[0-9A-Fa-f]{4}){0,6}';
+    }
+    description
+      "This type defines the area address format.";
+  }
+
+  /************************Reusable groupings********************/
+  /**** Service Status ****/
+
+  grouping service-status {
+    description
+      "Service status grouping.";
+    container status {
+      description
+        "Service status.";
+      container admin-status {
+        description
+          "Administrative service status.";
+        leaf status {
+          type identityref {
+            base vpn-common:administrative-status;
+          }
+          description
+            "Administrative service status.";
+        }
+        leaf last-change {
+          type yang:date-and-time;
+          config false;
+          description
+            "Indicates the actual date and time of the service
+             status change.";
+        }
+      }
+      container oper-status {
+        config false;
+        description
+          "Operational service status.";
+        uses vpn-common:oper-status-timestamp;
+      }
+    }
+  }
+
+  /**** A set of profiles ****/
+
+  grouping ac-profile-cfg {
+    description
+      "Grouping for AC profile configuration.";
+    container valid-provider-identifiers {
+      description
+        "Container for valid provider profile identifiers.
+         The profiles only have significance within the service
+         provider's administrative domain.";
+      list encryption-profile-identifier {
+        key "id";
+        description
+          "List of encryption profile identifiers.";
+        leaf id {
+          type string;
+          description
+            "Identification of the encryption profile to be used.";
+        }
+      }
+      list qos-profile-identifier {
+        key "id";
+        description
+          "List of QoS profile identifiers.";
+        leaf id {
+          type string;
+          description
+            "Identification of the QoS profile to be used.";
+        }
+      }
+      list failure-detection-profile-identifier {
+        key "id";
+        description
+          "List of BFD profile identifiers.";
+        leaf id {
+          type string;
+          description
+            "Identification of the a failure detection (e.g., BFD)
+             profile to be used.";
+        }
+      }
+      list forwarding-profile-identifier {
+        key "id";
+        description
+          "List of forwarding profile identifiers.";
+        leaf id {
+          type string;
+          description
+            "Identification of the forwarding profile to be used.";
+        }
+      }
+      list routing-profile-identifier {
+        key "id";
+        description
+          "List of routing profile identifiers.";
+        leaf id {
+          type string;
+          description
+            "Identification of the routing profile to be used by
+             the routing protocols over an AC.";
+        }
+      }
+      nacm:default-deny-write;
+    }
+  }
+
+  /**** Operational instructions ****/
+
+  grouping op-instructions {
+    description
+      "Scheduling instructions.";
+    leaf requested-start {
+      type yang:date-and-time;
+      description
+        "Indicates the requested date and time when the service is
+         expected to be active.";
+    }
+    leaf requested-stop {
+      type yang:date-and-time;
+      description
+        "Indicates the requested date and time when the service is
+         expected to be disabled.";
+    }
+    leaf actual-start {
+      type yang:date-and-time;
+      config false;
+      description
+        "Indicates the actual date and time when the service
+         actually was enabled.";
+    }
+    leaf actual-stop {
+      type yang:date-and-time;
+      config false;
+      description
+        "Indicates the actual date and time when the service
+         actually was disabled.";
+    }
+  }
+
+  /**** Layer 2 encapsulations ****/
+  // Dot1q
+
+  grouping dot1q {
+    description
+      "Defines a grouping for tagged interfaces.";
+    leaf tag-type {
+      type identityref {
+        base vpn-common:tag-type;
+      }
+      description
+        "Tag type.";
+    }
+    leaf cvlan-id {
+      type uint16 {
+        range "1..4094";
+      }
+      description
+        "VLAN identifier.";
+    }
+  }
+
+  // priority-tagged
+
+  grouping priority-tagged {
+    description
+      "Priority tagged.";
+    leaf tag-type {
+      type identityref {
+        base vpn-common:tag-type;
+      }
+      description
+        "Tag type.";
+    }
+  }
+
+  // QinQ
+
+  grouping qinq {
+    description
+      "Includes QinQ parameters.";
+    leaf tag-type {
+      type identityref {
+        base vpn-common:tag-type;
+      }
+      description
+        "Tag type.";
+    }
+    leaf svlan-id {
+      type uint16 {
+        range "1..4094";
+      }
+      description
+        "Service VLAN (S-VLAN) identifier.";
+    }
+    leaf cvlan-id {
+      type uint16 {
+        range "1..4094";
+      }
+      description
+        "Customer VLAN (C-VLAN) identifier.";
+    }
+  }
+
+  /**** Layer 2 tunnel services ****/
+  // pseudowire (PW)
+
+  grouping pseudowire {
+    description
+      "Includes pseudowire termination parameters.";
+    leaf vcid {
+      type uint32;
+      description
+        "Indicates a PW or virtual circuit (VC) identifier.";
+    }
+    leaf far-end {
+      type union {
+        type uint32;
+        type inet:ip-address;
+      }
+      description
+        "Neighbor reference.";
+      reference
+        "RFC 8077: Pseudowire Setup and Maintenance Using the Label
+                   Distribution Protocol (LDP), Section 6.1";
+    }
+  }
+  // VPLS
+
+  grouping vpls {
+    description
+      "VPLS termination parameters.";
+    leaf vcid {
+      type uint32;
+      description
+        "VC identifier.";
+    }
+    leaf-list far-end {
+      type union {
+        type uint32;
+        type inet:ip-address;
+      }
+      description
+        "Neighbor reference.";
+    }
+  }
+
+  // VXLAN
+
+  grouping vxlan {
+    description
+      "VXLAN termination parameters.";
+    leaf vni-id {
+      type uint32;
+      description
+        "VXLAN Network Identifier (VNI).";
+    }
+    leaf peer-mode {
+      type identityref {
+        base vpn-common:vxlan-peer-mode;
+      }
+      description
+        "Specifies the VXLAN access mode. By default,
+         the peer mode is set to 'static-mode'.";
+    }
+    leaf-list peer-ip-address {
+      type inet:ip-address;
+      description
+        "List of a peer's IP addresses.";
+    }
+  }
+
+  // Layer 2 Tunnel service
+
+  grouping l2-tunnel-service {
+    description
+      "Defines a Layer 2 tunnel termination.";
+    leaf type {
+      type identityref {
+        base l2-tunnel-type;
+      }
+      description
+        "Selects the tunnel termination type for an AC.";
+    }
+    container pseudowire {
+      when "derived-from-or-self(../type, 'ac-common:pseudowire')" {
+        description
+          "Only applies when the Layer 2 service type is
+           'pseudowire'.";
+      }
+      description
+        "Includes pseudowire termination parameters.";
+      uses pseudowire;
+    }
+    container vpls {
+      when "derived-from-or-self(../type, 'ac-common:vpls')" {
+        description
+          "Only applies when the Layer 2 service type is 'vpls'.";
+      }
+      description
+        "VPLS termination parameters.";
+      uses vpls;
+    }
+    container vxlan {
+      when "derived-from-or-self(../type, 'ac-common:vxlan')" {
+        description
+          "Only applies when the Layer 2 service type is 'vxlan'.";
+      }
+      description
+        "VXLAN termination parameters.";
+      uses vxlan;
+    }
+  }
+
+  /**** Layer 3 connection *****/
+  // IPv4 allocation type
+
+  grouping ipv4-allocation-type {
+    description
+      "IPv4-specific parameters.";
+    leaf prefix-length {
+      type uint8 {
+        range "0..32";
+      }
+      description
+        "Subnet prefix length expressed in bits. It is applied to
+         both local and customer addresses.";
+    }
+    leaf address-allocation-type {
+      type identityref {
+        base address-allocation-type;
+      }
+      must "not(derived-from-or-self(current(), 'ac-common:slaac') "
+         + "or derived-from-or-self(current(), "
+         + "'ac-common:provider-dhcp-slaac'))" {
+        error-message "SLAAC is only applicable to IPv6.";
+      }
+      description
+        "Defines how IPv4 addresses are allocated to the peer site.";
+    }
+  }
+
+  // IPv6 allocation type
+
+  grouping ipv6-allocation-type {
+    description
+      "IPv6-specific parameters.";
+    leaf prefix-length {
+      type uint8 {
+        range "0..128";
+      }
+      description
+        "Subnet prefix length expressed in bits. It is applied to
+          both local and customer addresses.";
+    }
+    leaf address-allocation-type {
+      type identityref {
+        base address-allocation-type;
+      }
+      description
+        "Defines how IPv6 addresses are allocated to the peer site.";
+    }
+  }
+
+  // Basic parameters for IPv4 connection
+
+  grouping ipv4-connection-basic {
+    description
+      "Basic set fof IPv4-specific parameters for the connection.";
+    uses ipv4-allocation-type;
+    choice allocation-type {
+      description
+        "Choice of the IPv4 address allocation.";
+      case dynamic {
+        description
+          "When the addresses are allocated by DHCP or other dynamic
+           means local to the infrastructure.";
+        choice provider-dhcp {
+          description
+            "Parameters related to DHCP-allocated addresses. IP
+             addresses are allocated by DHCP, that is provided by
+             the operator.";
+          leaf dhcp-service-type {
+            type enumeration {
+              enum server {
+                description
+                  "Local DHCP server.";
+              }
+              enum relay {
+                description
+                  "Local DHCP relay.  DHCP requests are relayed to
+                   a provider's server.";
+              }
+            }
+            description
+              "Indicates the type of DHCP service to be enabled on
+               an AC.";
+          }
+        }
+        choice dhcp-relay {
+          description
+            "The DHCP relay is provided by the operator.";
+          container customer-dhcp-servers {
+            description
+              "Container for a list of the customer's DHCP servers.";
+            leaf-list server-ip-address {
+              type inet:ipv4-address;
+              description
+                "IPv4 addresses of the customer's DHCP server.";
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // Basic parameters for IPv6 connection
+
+  grouping ipv6-connection-basic {
+    description
+      "Basic set fof IPv6-specific parameters for the connection.";
+    uses ipv6-allocation-type;
+    choice allocation-type {
+      description
+        "Choice of the IPv6 address allocation.";
+      case dynamic {
+        description
+          "When the addresses are allocated by DHCP or other dynamic
+           means local to the infrastructure.";
+        choice provider-dhcp {
+          description
+            "Parameters related to DHCP-allocated addresses.
+             IP addresses are allocated by DHCP, that is provided
+             by the operator.";
+          leaf dhcp-service-type {
+            type enumeration {
+              enum server {
+                description
+                  "Local DHCP server.";
+              }
+              enum relay {
+                description
+                  "Local DHCP relay.  DHCP requests are relayed to a
+                   provider's server.";
+              }
+            }
+            description
+              "Indicates the type of DHCP service to be enabled on
+               the AC.";
+          }
+        }
+        choice dhcp-relay {
+          description
+            "The DHCP relay is provided by the operator.";
+          container customer-dhcp-servers {
+            description
+              "Container for a list of the customer's DHCP servers.";
+            leaf-list server-ip-address {
+              type inet:ipv6-address;
+              description
+                "IPv6 addresses of the customer's DHCP server.";
+            }
+          }
+        }
+      }
+    }
+  }
+  // Full parameters for the IPv4 connection
+
+  grouping ipv4-connection {
+    description
+      "IPv4-specific parameters.";
+    leaf local-address {
+      type inet:ipv4-address;
+      description
+        "The IP address used at the provider's interface.";
+    }
+    leaf virtual-address {
+      type inet:ipv4-address;
+      description
+        "This addresss may be used for redundancy purposes.";
+    }
+    uses ipv4-allocation-type;
+    choice allocation-type {
+      description
+        "Choice of the IPv4 address allocation.";
+      case dynamic {
+        description
+          "When the addresses are allocated by DHCP or other
+           dynamic means local to the infrastructure.";
+        choice address-assign {
+          description
+            "A choice for how IPv4 addresses are assigned.";
+          case number {
+            leaf number-of-dynamic-address {
+              type uint16;
+              description
+                "Specifies the number of IP addresses to be assigned
+                 to the customer on the AC.";
+            }
+          }
+          case explicit {
+            container customer-addresses {
+              description
+                "Container for customer addresses to be allocated
+                 using DHCP.";
+              list address-pool {
+                key "pool-id";
+                description
+                  "Describes IP addresses to be dyncamically
+                   allocated.
+
+                   When only 'start-address' is present, it
+                   represents a single address.
+
+                   When both 'start-address' and 'end-address' are
+                   specified, it implies a range inclusive of both
+                   addresses.";
+                leaf pool-id {
+                  type string;
+                  description
+                    "A pool identifier for the address range from
+                     'start-address' to 'end-address'.";
+                }
+                leaf start-address {
+                  type inet:ipv4-address;
+                  mandatory true;
+                  description
+                    "Indicates the first address in the pool.";
+                }
+                leaf end-address {
+                  type inet:ipv4-address;
+                  description
+                    "Indicates the last address in the pool.";
+                }
+              }
+            }
+          }
+        }
+        choice provider-dhcp {
+          description
+            "Parameters related to DHCP-allocated addresses. IP
+             addresses are allocated by DHCP, which is provided by
+             the operator.";
+          leaf dhcp-service-type {
+            type enumeration {
+              enum server {
+                description
+                  "Local DHCP server.";
+              }
+              enum relay {
+                description
+                  "Local DHCP relay.  DHCP requests are relayed to
+                   a provider's server.";
+              }
+            }
+            description
+              "Indicates the type of DHCP service to be enabled on
+               this AC.";
+          }
+        }
+        choice dhcp-relay {
+          description
+            "The DHCP relay is provided by the operator.";
+          container customer-dhcp-servers {
+            description
+              "Container for a list of the customer's DHCP servers.";
+            leaf-list server-ip-address {
+              type inet:ipv4-address;
+              description
+                "IPv4 addresses of the customer's DHCP server.";
+            }
+          }
+        }
+      }
+      case static-addresses {
+        description
+          "Lists the IPv4 addresses that are used.";
+        list address {
+          key "address-id";
+          ordered-by user;
+          description
+            "Lists the IPv4 addresses that are used. The first
+             address of the list is the primary address of the
+             connection.";
+          leaf address-id {
+            type string;
+            description
+              "An identifier of the static IPv4 address.";
+          }
+          leaf customer-address {
+            type inet:ipv4-address;
+            description
+              "An IPv4 address of the customer side.";
+          }
+        }
+      }
+    }
+  }
+
+  // Full parameters for the IPv6 connection
+
+  grouping ipv6-connection {
+    description
+      "IPv6-specific parameters.";
+    leaf local-address {
+      type inet:ipv6-address;
+      description
+        "IPv6 address of the provider side.";
+    }
+    leaf virtual-address {
+      type inet:ipv6-address;
+      description
+        "This addresss may be used for redundancy purposes.";
+    }
+    uses ipv6-allocation-type;
+    choice allocation-type {
+      description
+        "Choice of the IPv6 address allocation.";
+      case dynamic {
+        description
+          "When the addresses are allocated by DHCP or other
+           dynamic means local to the infrastructure.";
+        choice address-assign {
+          description
+            "A choice for how IPv6 addresses are assigned.";
+          case number {
+            leaf number-of-dynamic-address {
+              type uint16;
+              description
+                "Specifies the number of IP addresses to be
+                 assigned to the customer on this access.";
+            }
+          }
+          case explicit {
+            container customer-addresses {
+              description
+                "Container for customer addresses to be allocated
+                 using DHCP.";
+              list address-pool {
+                key "pool-id";
+                description
+                  "Describes IP addresses to be dyncamically
+                   allocated.
+
+                   When only 'start-address' is present, it
+                   represents a single address.
+
+                   When both 'start-address' and 'end-address' are
+                   specified, it implies a range inclusive of both
+                   addresses.";
+                leaf pool-id {
+                  type string;
+                  description
+                    "A pool identifier for the address range from
+                     'start-address' to 'end-address'.";
+                }
+                leaf start-address {
+                  type inet:ipv6-address;
+                  mandatory true;
+                  description
+                    "Indicates the first address in the pool.";
+                }
+                leaf end-address {
+                  type inet:ipv6-address;
+                  description
+                    "Indicates the last address in the pool.";
+                }
+              }
+            }
+          }
+        }
+        choice provider-dhcp {
+          description
+            "Parameters related to DHCP-allocated addresses.
+             IP addresses are allocated by DHCP, which is provided
+             by the operator.";
+          leaf dhcp-service-type {
+            type enumeration {
+              enum server {
+                description
+                  "Local DHCP server.";
+              }
+              enum relay {
+                description
+                  "Local DHCP relay.  DHCP requests are relayed
+                   to a provider's server.";
+              }
+            }
+            description
+              "Indicates the type of DHCP service to
+               be enabled on this access.";
+          }
+        }
+        choice dhcp-relay {
+          description
+            "The DHCP relay is provided by the operator.";
+          container customer-dhcp-servers {
+            description
+              "Container for a list of the customer's DHCP servers.";
+            leaf-list server-ip-address {
+              type inet:ipv6-address;
+              description
+                "IPv6 addresses of the customer's DHCP server.";
+            }
+          }
+        }
+      }
+      case static-addresses {
+        description
+          "Lists the IPv6 addresses that are used.";
+        list address {
+          key "address-id";
+          ordered-by user;
+          description
+            "Lists the IPv6 addresses that are used. The first
+             address of the list is the primary IP address of
+             the connection.";
+          leaf address-id {
+            type string;
+            description
+              "An identifier of the static IPv6 address.";
+          }
+          leaf customer-address {
+            type inet:ipv6-address;
+            description
+              "An IPv6 address of the customer side.";
+          }
+        }
+      }
+    }
+  }
+
+  /**** Routing ****/
+  // Routing authentication
+
+  grouping bgp-authentication {
+    description
+      "Grouping for BGP authentication parameters.";
+    container authentication {
+      description
+        "Container for BGP authentication  parameters.";
+      leaf enabled {
+        type boolean;
+        description
+          "Enables or disables authentication.";
+      }
+      container keying-material {
+        when "../enabled = 'true'";
+        description
+          "Container for describing how a BGP routing session is to
+           be secured on an AC.";
+        choice option {
+          description
+            "Choice of authentication options.";
+          case ao {
+            description
+              "Uses the TCP Authentication Option (TCP-AO).";
+            reference
+              "RFC 5925: The TCP Authentication Option";
+            leaf enable-ao {
+              type boolean;
+              description
+                "Enables the TCP-AO.";
+            }
+            leaf ao-keychain {
+              type key-chain:key-chain-ref;
+              description
+                "Reference to the TCP-AO key chain.";
+              reference
+                "RFC 8177: YANG Data Model for Key Chains";
+            }
+          }
+          case md5 {
+            description
+              "Uses MD5 to secure the session.";
+            reference
+              "RFC 4364: BGP/MPLS IP Virtual Private Networks
+                         (VPNs), Section 13.2";
+            leaf md5-keychain {
+              type key-chain:key-chain-ref;
+              description
+                "Reference to the MD5 key chain.";
+              reference
+                "RFC 8177: YANG Data Model for Key Chains";
+            }
+          }
+          case explicit {
+            leaf key-id {
+              type uint32;
+              description
+                "Key identifier.";
+            }
+            leaf key {
+              type string;
+              description
+                "BGP authentication key.
+
+                 This model only supports the subset of keys that
+                 are representable as ASCII strings.";
+            }
+            leaf crypto-algorithm {
+              type identityref {
+                base key-chain:crypto-algorithm;
+              }
+              description
+                "Indicates the cryptographic algorithm associated
+                 with the key.";
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping ospf-authentication {
+    description
+      "Authentication configuration.";
+    container authentication {
+      description
+        "Container for OSPF authentication  parameters.";
+      leaf enabled {
+        type boolean;
+        description
+          "Enables or disables authentication.";
+      }
+      container keying-material {
+        when "../enabled = 'true'";
+        description
+          "Container for describing how an OSPF session is to be
+           secured for this AC.";
+        choice option {
+          description
+            "Options for OSPF authentication.";
+          case auth-key-chain {
+            leaf key-chain {
+              type key-chain:key-chain-ref;
+              description
+                "Name of the key chain.";
+            }
+          }
+          case auth-key-explicit {
+            leaf key-id {
+              type uint32;
+              description
+                "Key identifier.";
+            }
+            leaf key {
+              type string;
+              description
+                "OSPF authentication key.
+                 This model only supports the subset of keys that
+                 are representable as ASCII strings.";
+            }
+            leaf crypto-algorithm {
+              type identityref {
+                base key-chain:crypto-algorithm;
+              }
+              description
+                "Indicates the cryptographic algorithm associated
+                 with the key.";
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping isis-authentication {
+    description
+      "IS-IS authentication configuration.";
+    container authentication {
+      description
+        "Container for IS-IS authentication  parameters.";
+      leaf enabled {
+        type boolean;
+        description
+          "Enables or disables authentication.";
+      }
+      container keying-material {
+        when "../enabled = 'true'";
+        description
+          "Container for describing how an IS-IS session is secured
+           over an AC.";
+        choice option {
+          description
+            "Options for IS-IS authentication.";
+          case auth-key-chain {
+            leaf key-chain {
+              type key-chain:key-chain-ref;
+              description
+                "Name of the key chain.";
+            }
+          }
+          case auth-key-explicit {
+            leaf key-id {
+              type uint32;
+              description
+                "Key identifier.";
+            }
+            leaf key {
+              type string;
+              description
+                "IS-IS authentication key.
+
+                 This model only supports the subset of keys that
+                 are representable as ASCII strings.";
+            }
+            leaf crypto-algorithm {
+              type identityref {
+                base key-chain:crypto-algorithm;
+              }
+              description
+                "Indicates the cryptographic algorithm associated
+                 with the key.";
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping rip-authentication {
+    description
+      "RIP authentication configuration.";
+    container authentication {
+      description
+        "Container for RIP authentication  parameters.";
+      leaf enabled {
+        type boolean;
+        description
+          "Enables or disables authentication.";
+      }
+      container keying-material {
+        when "../enabled = 'true'";
+        description
+          "Container for describing how a RIP session is to be
+           secured on this AC.";
+        choice option {
+          description
+            "Specifies the authentication
+             scheme.";
+          case auth-key-chain {
+            leaf key-chain {
+              type key-chain:key-chain-ref;
+              description
+                "Name of the key chain.";
+            }
+          }
+          case auth-key-explicit {
+            leaf key {
+              type string;
+              description
+                "RIP authentication key.
+
+                 This model only supports the subset of keys that
+                 are representable as ASCII strings.";
+            }
+            leaf crypto-algorithm {
+              type identityref {
+                base key-chain:crypto-algorithm;
+              }
+              description
+                "Indicates the cryptographic algorithm associated
+                 with the key.";
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // Basic routing parameters
+
+  grouping bgp-peer-group-without-name {
+    description
+      "Identifies a BGP peer-group configured on the local system.";
+    leaf local-as {
+      type inet:as-number;
+      description
+        "Indicates a local AS Number (ASN). This ASN is exposed
+         to a customer so that it knows which ASN to use
+         to set up a BGP session.";
+    }
+    leaf peer-as {
+      type inet:as-number;
+      description
+        "Indicates the customer's ASN when the customer
+         requests BGP routing.";
+    }
+    leaf address-family {
+      type identityref {
+        base vpn-common:address-family;
+      }
+      description
+        "This node contains the address families to be activated.
+         'dual-stack' means that both IPv4 and IPv6 will be
+         activated.";
+    }
+    leaf role {
+      type identityref {
+        base ac-common:bgp-role;
+      }
+      description
+        "Specifies the BGP role (provider, customer, peer, etc.).";
+      reference
+        "RFC 9234: Route Leak Prevention and Detection Using
+                   Roles in UPDATE and OPEN Messages, Section 4";
+    }
+  }
+
+  grouping bgp-peer-group-with-name {
+    description
+      "Identifies a BGP peer-group configured on the local system -
+       identified by a peer-group name.";
+    leaf name {
+      type string;
+      description
+        "Name of the BGP peer-group.";
+    }
+    uses bgp-peer-group-without-name;
+  }
+
+  grouping ospf-basic {
+    description
+      "Configuration specific to OSPF.";
+    leaf address-family {
+      type identityref {
+        base vpn-common:address-family;
+      }
+      description
+        "Indicates whether IPv4, IPv6, or both are to be activated.";
+    }
+    leaf area-id {
+      type yang:dotted-quad;
+      mandatory true;
+      description
+        "Area ID.";
+      reference
+        "RFC 4577: OSPF as the Provider/Customer Edge Protocol
+                   for BGP/MPLS IP Virtual Private Networks
+                   (VPNs), Section 4.2.3
+         RFC 6565: OSPFv3 as a Provider Edge to Customer Edge
+                   (PE-CE) Routing Protocol, Section 4.2";
+    }
+    leaf metric {
+      type uint16;
+      description
+        "Metric of the AC.  It is used in the routing state
+         calculation and path selection.";
+    }
+  }
+
+  grouping isis-basic {
+    description
+      "Basic configuration specific to IS-IS.";
+    leaf address-family {
+      type identityref {
+        base vpn-common:address-family;
+      }
+      description
+        "Indicates whether IPv4, IPv6, or both are to be activated.";
+    }
+    leaf area-address {
+      type area-address;
+      mandatory true;
+      description
+        "Area address.";
+    }
+  }
+
+  // Static routing
+
+  grouping ipv4-static-rtg-entry {
+    description
+      "Paramters to configure a specific IPv4 static routing entry.";
+    leaf lan {
+      type inet:ipv4-prefix;
+      description
+        "LAN prefix.";
+    }
+    leaf lan-tag {
+      type string;
+      description
+        "Internal tag to be used in service policies.";
+    }
+    leaf next-hop {
+      type union {
+        type inet:ip-address;
+        type predefined-next-hop;
+      }
+      description
+        "The next hop that is to be used for the static route.
+         This may be specified as an IP address or a
+         predefined next-hop type (e.g., 'discard' or
+         'local-link').";
+    }
+    leaf metric {
+      type uint32;
+      description
+        "Indicates the metric associated with the static route.";
+    }
+  }
+
+  grouping ipv4-static-rtg {
+    description
+      "Configuration specific to IPv4 static routing.";
+    list ipv4-lan-prefixes {
+      if-feature "vpn-common:ipv4";
+      key "lan next-hop";
+      description
+        "List of LAN prefixes for the site.";
+      uses ipv4-static-rtg-entry;
+      uses ac-common:service-status;
+    }
+  }
+
+  grouping ipv6-static-rtg-entry {
+    description
+      "Paramters to configure a specific IPv6 static routing entry.";
+    leaf lan {
+      type inet:ipv6-prefix;
+      description
+        "LAN prefixes.";
+    }
+    leaf lan-tag {
+      type string;
+      description
+        "Internal tag to be used in service (e.g., VPN) policies.";
+    }
+    leaf next-hop {
+      type union {
+        type inet:ip-address;
+        type predefined-next-hop;
+      }
+      description
+        "The next hop that is to be used for the static route.
+         This may be specified as an IP address or a predefined
+         next-hop type (e.g., 'discard' or 'local-link').";
+    }
+    leaf metric {
+      type uint32;
+      description
+        "Indicates the metric associated with the static route.";
+    }
+  }
+
+  grouping ipv6-static-rtg {
+    description
+      "Configuration specific to IPv6 static routing.";
+    list ipv6-lan-prefixes {
+      if-feature "vpn-common:ipv6";
+      key "lan next-hop";
+      description
+        "List of LAN prefixes for the site.";
+      uses ipv6-static-rtg-entry;
+      uses ac-common:service-status;
+    }
+  }
+
+  // OAM
+
+  grouping bfd {
+    description
+      "A grouping for basic BFD.";
+    leaf holdtime {
+      type uint32;
+      units "milliseconds";
+      description
+        "Expected BFD holdtime.
+         The customer may impose some fixed values
+         for the holdtime period if the provider allows
+         the customer to use this function.
+         If the provider doesn't allow the customer to
+         use this function, fixed values will not be set.";
+      reference
+        "RFC 5880: Bidirectional Forwarding Detection (BFD),
+                   Section 6.8.18";
+    }
+  }
+
+  // redundancy
+
+  grouping redundancy-group {
+    description
+      "A grouping for redundancy group.";
+    list group {
+       key "group-id";
+       description
+         "List of group-ids.";
+       leaf group-id {
+         type string;
+         description
+           "Indicates the group-id to which the AC belongs.";
+       }
+       leaf precedence {
+         type identityref {
+           base ac-common:precedence-type;
+         }
+         description
+           "Defines redundancy of an AC.";
+       }
+     }
+   }
+
+  // QoS
+
+  grouping bandwidth-parameters {
+    description
+      "A grouping for bandwidth parameters.";
+    leaf cir {
+      type uint64;
+      units "bps";
+      description
+        "Committed Information Rate (CIR). The maximum number of bits
+         that a port can receive or send during one second over
+         an interface.";
+    }
+    leaf cbs {
+      type uint64;
+      units "bytes";
+      description
+        "Committed Burst Size (CBS). CBS controls the bursty nature
+         of the traffic.  Traffic that does not use the configured
+         CIR accumulates credits until the credits reach the
+         configured CBS.";
+    }
+    leaf eir {
+      type uint64;
+      units "bps";
+      description
+        "Excess Information Rate (EIR), i.e., excess frame delivery
+         allowed not subject to a Service Level Agreement (SLA).
+         The traffic rate can be limited by EIR.";
+    }
+    leaf ebs {
+      type uint64;
+      units "bytes";
+      description
+        "Excess Burst Size (EBS).  The bandwidth available for burst
+         traffic from the EBS is subject to the amount of bandwidth
+         that is accumulated during periods when traffic allocated
+         by the EIR policy is not used.";
+    }
+    leaf pir {
+      type uint64;
+      units "bps";
+      description
+        "Peak Information Rate (PIR), i.e., maximum frame delivery
+         allowed. It is equal to or less than sum of CIR and EIR.";
+    }
+    leaf pbs {
+      type uint64;
+      units "bytes";
+      description
+        "Peak Burst Size (PBS).";
+    }
+  }
+
+  grouping bandwidth-per-type {
+    description
+      "Grouping for bandwidth per type.";
+    list bandwidth {
+      key "bw-type";
+      description
+        "List for bandwidth per type data nodes.";
+      leaf bw-type {
+        type identityref {
+          base vpn-common:bw-type;
+        }
+        description
+          "Indicates the bandwidth type.";
+      }
+      choice type {
+        description
+          "Choice based upon bandwidth type.";
+        case per-cos {
+          description
+            "Bandwidth per CoS.";
+          list cos {
+            key "cos-id";
+            description
+              "List of Class of Services.";
+            leaf cos-id {
+              type uint8;
+              description
+                "Identifier of the CoS, indicated by a Differentiated
+                 Services Code Point (DSCP) or a CE-CLAN CoS (802.1p)
+                 value in the service frame.";
+              reference
+                "IEEE Std 802.1Q: Bridges and Bridged Networks";
+            }
+            uses bandwidth-parameters;
+          }
+        }
+        case other {
+          description
+            "Other bandwidth types.";
+          uses bandwidth-parameters;
+        }
+      }
+    }
+  }
+}
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-ac-svc@2024-08-06.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-ac-svc@2024-08-06.yang
new file mode 100644
index 0000000000000000000000000000000000000000..a5790644f1f7600cfad42663f2e7c7ed13134ac1
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-ac-svc@2024-08-06.yang
@@ -0,0 +1,1252 @@
+module ietf-ac-svc {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-ac-svc";
+  prefix ac-svc;
+
+  import ietf-ac-common {
+    prefix ac-common;
+    reference
+      "RFC CCCC: A Common YANG Data Model for Attachment Circuits";
+  }
+  import ietf-vpn-common {
+    prefix vpn-common;
+    reference
+      "RFC 9181: A Common YANG Data Model for Layer 2 and Layer 3
+                 VPNs";
+  }
+  import ietf-netconf-acm {
+    prefix nacm;
+    reference
+      "RFC 8341: Network Configuration Access Control Model";
+  }
+  import ietf-inet-types {
+    prefix inet;
+    reference
+      "RFC 6991: Common YANG Data Types, Section 4";
+  }
+  import ietf-key-chain {
+    prefix key-chain;
+    reference
+      "RFC 8177: YANG Data Model for Key Chains";
+  }
+
+  organization
+    "IETF OPSAWG (Operations and Management Area Working Group)";
+  contact
+    "WG Web:   <https://datatracker.ietf.org/wg/opsawg/>
+     WG List:  <mailto:opsawg@ietf.org>
+
+     Editor:   Mohamed Boucadair
+               <mailto:mohamed.boucadair@orange.com>
+     Author:   Richard Roberts
+               <mailto:rroberts@juniper.net>
+     Author:   Oscar Gonzalez de Dios
+               <mailto:oscar.gonzalezdedios@telefonica.com>
+     Author:   Samier Barguil
+               <mailto:ssamier.barguil_giraldo@nokia.com>
+     Author:   Bo Wu
+               <mailto:lana.wubo@huawei.com>";
+  description
+    "This YANG module defines a YANG model for exposing
+     attachment circuits as a service (ACaaS).
+
+     Copyright (c) 2024 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Revised BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC XXXX; see the
+     RFC itself for full legal notices.";
+
+  revision 2024-08-06 {
+    description
+      "Initial revision.";
+    reference
+      "RFC XXXX: YANG Data Models for Bearers and 'Attachment
+                 Circuits'-as-a-Service (ACaaS)";
+  }
+
+  /* A set of typedefs to ease referencing cross-modules */
+
+  typedef attachment-circuit-reference {
+    type leafref {
+      path "/ac-svc:attachment-circuits/ac-svc:ac/ac-svc:name";
+    }
+    description
+      "Defines a reference to an attachment circuit that can be used
+       by other modules.";
+  }
+
+  typedef ac-group-reference {
+    type leafref {
+      path "/ac-svc:attachment-circuits/ac-svc:ac-group-profile"
+         + "/ac-svc:name";
+    }
+    description
+      "Defines a reference to an attachment circuit profile.";
+  }
+
+  typedef encryption-profile-reference {
+    type leafref {
+      path
+        "/ac-svc:specific-provisioning-profiles"
+      + "/ac-svc:valid-provider-identifiers"
+      + "/ac-svc:encryption-profile-identifier/ac-svc:id";
+    }
+    description
+      "Defines a reference to an encryption profile.";
+  }
+
+  typedef qos-profile-reference {
+    type leafref {
+      path
+        "/ac-svc:specific-provisioning-profiles"
+      + "/ac-svc:valid-provider-identifiers"
+      + "/ac-svc:qos-profile-identifier/ac-svc:id";
+    }
+    description
+      "Defines a reference to a QoS profile.";
+  }
+
+  typedef failure-detection-profile-reference {
+    type leafref {
+      path
+        "/ac-svc:specific-provisioning-profiles"
+      + "/ac-svc:valid-provider-identifiers"
+      + "/ac-svc:failure-detection-profile-identifier"
+      + "/ac-svc:id";
+    }
+    description
+      "Defines a reference to a BFD profile.";
+  }
+
+  typedef forwarding-profile-reference {
+    type leafref {
+      path
+        "/ac-svc:specific-provisioning-profiles"
+      + "/ac-svc:valid-provider-identifiers"
+      + "/ac-svc:forwarding-profile-identifier/ac-svc:id";
+    }
+    description
+      "Defines a reference to a forwarding profile.";
+  }
+
+  typedef routing-profile-reference {
+    type leafref {
+      path
+        "/ac-svc:specific-provisioning-profiles"
+      + "/ac-svc:valid-provider-identifiers"
+      + "/ac-svc:routing-profile-identifier/ac-svc:id";
+    }
+    description
+      "Defines a reference to a routing profile.";
+  }
+
+  typedef service-profile-reference {
+    type leafref {
+      path
+        "/ac-svc:service-provisioning-profiles"
+      + "/ac-svc:service-profile-identifier"
+      + "/ac-svc:id";
+    }
+    description
+      "Defines a reference to a service profile.";
+  }
+
+  /******************** Reusable groupings ********************/
+  // Basic Layer 2 connection
+
+  grouping l2-connection-basic {
+    description
+      "Defines Layer 2 protocols and parameters that can be
+       factorized when provisioning Layer 2 connectivity
+       among multiple ACs.";
+    container encapsulation {
+      description
+        "Container for Layer 2 encapsulation.";
+      leaf type {
+        type identityref {
+          base vpn-common:encapsulation-type;
+        }
+        description
+          "Encapsulation type.";
+      }
+      container dot1q {
+        when "derived-from-or-self(../type, 'vpn-common:dot1q')" {
+          description
+            "Only applies when the type of the tagged interface
+             is 'dot1q'.";
+        }
+        description
+          "Tagged interface.";
+        uses ac-common:dot1q;
+      }
+      container qinq {
+        when "derived-from-or-self(../type, 'vpn-common:qinq')" {
+          description
+            "Only applies when the type of the tagged interface
+             is 'qinq'.";
+        }
+        description
+          "Includes QinQ parameters.";
+        uses ac-common:qinq;
+      }
+    }
+  }
+
+  // Full Layer 2 connection
+
+  grouping l2-connection {
+    description
+      "Defines Layer 2 protocols and parameters that are used to
+       enable AC connectivity.";
+    container encapsulation {
+      description
+        "Container for Layer 2 encapsulation.";
+      leaf type {
+        type identityref {
+          base vpn-common:encapsulation-type;
+        }
+        description
+          "Indicates the encapsulation type.";
+      }
+      container dot1q {
+        when "derived-from-or-self(../type, 'vpn-common:dot1q')" {
+          description
+            "Only applies when the type of the tagged interface
+             is 'dot1q'.";
+        }
+        description
+          "Tagged interface.";
+        uses ac-common:dot1q;
+      }
+      container priority-tagged {
+        when "derived-from-or-self(../type, "
+           + "'vpn-common:priority-tagged')" {
+          description
+            "Only applies when the type of the tagged interface is
+             'priority-tagged'.";
+        }
+        description
+          "Priority-tagged interface.";
+        uses ac-common:priority-tagged;
+      }
+      container qinq {
+        when "derived-from-or-self(../type, 'vpn-common:qinq')" {
+          description
+            "Only applies when the type of the tagged interface
+             is 'qinq'.";
+        }
+        description
+          "Includes QinQ parameters.";
+        uses ac-common:qinq;
+      }
+    }
+    choice l2-service {
+      description
+        "The Layer 2 connectivity service can be provided by
+         indicating a pointer to an L2VPN or by specifying a
+         Layer 2 tunnel service.";
+      container l2-tunnel-service {
+        description
+          "Defines a Layer 2 tunnel termination.
+           It is only applicable when a tunnel is required.";
+        uses ac-common:l2-tunnel-service;
+      }
+      case l2vpn {
+        leaf l2vpn-id {
+          type vpn-common:vpn-id;
+          description
+            "Indicates the L2VPN service associated with an
+             Integrated Routing and Bridging (IRB) interface.";
+        }
+      }
+    }
+    leaf bearer-reference {
+      if-feature "ac-common:server-assigned-reference";
+      type string;
+      description
+        "This is an internal reference for the service provider
+         to identify the bearer associated with this AC.";
+    }
+  }
+
+  // Basic IP connection
+
+  grouping ip-connection-basic {
+    description
+      "Defines basic IP connection parameters.";
+    container ipv4 {
+      if-feature "vpn-common:ipv4";
+      description
+        "IPv4-specific parameters.";
+      uses ac-common:ipv4-connection-basic;
+    }
+    container ipv6 {
+      if-feature "vpn-common:ipv6";
+      description
+        "IPv6-specific parameters.";
+      uses ac-common:ipv6-connection-basic;
+    }
+  }
+
+  // Full IP connection
+
+  grouping ip-connection {
+    description
+      "Defines IP connection parameters.";
+    container ipv4 {
+      if-feature "vpn-common:ipv4";
+      description
+        "IPv4-specific parameters.";
+      uses ac-common:ipv4-connection {
+        augment ac-svc:allocation-type/static-addresses/address {
+          leaf failure-detection-profile {
+            if-feature "vpn-common:bfd";
+            type failure-detection-profile-reference;
+            description
+              "Points to a failure detection profile.";
+          }
+          description
+            "Adds a failure detection profile.";
+        }
+      }
+    }
+    container ipv6 {
+      if-feature "vpn-common:ipv6";
+      description
+        "IPv6-specific parameters.";
+      uses ac-common:ipv6-connection {
+        augment ac-svc:allocation-type/static-addresses/address {
+          leaf failure-detection-profile {
+            if-feature "vpn-common:bfd";
+            type failure-detection-profile-reference;
+            description
+              "Points to a failure detection profile.";
+          }
+          description
+            "Adds a failure detection profile.";
+        }
+      }
+    }
+    choice l3-service {
+      description
+        "The Layer 3 connectivity service can be provided by
+         specifying a Layer 3 tunnel service.";
+      container l3-tunnel-service {
+        description
+          "Defines a Layer 3 tunnel termination.
+           It is only applicable when a tunnel is required.";
+        leaf type {
+          type identityref {
+            base ac-common:l3-tunnel-type;
+          }
+          description
+            "Selects the tunnel termination type for an AC.";
+        }
+      }
+    }
+  }
+
+  // Routing protocol list
+
+  grouping routing-protocol-list {
+    description
+      "List of routing protocols used on the AC.";
+    leaf type {
+      type identityref {
+        base vpn-common:routing-protocol-type;
+      }
+      description
+        "Type of routing protocol.";
+    }
+    list routing-profiles {
+      key "id";
+      description
+        "Routing profiles.";
+      leaf id {
+        type routing-profile-reference;
+        description
+          "Reference to the routing profile to be used.";
+      }
+      leaf type {
+        type identityref {
+          base vpn-common:ie-type;
+        }
+        description
+          "Import, export, or both.";
+      }
+    }
+  }
+
+  // Static routing with BFD
+
+  grouping ipv4-static-rtg-with-bfd {
+    description
+      "Configuration specific to IPv4 static routing with
+       failure protection (e.g., BFD).";
+    list ipv4-lan-prefix {
+      if-feature "vpn-common:ipv4";
+      key "lan next-hop";
+      description
+        "List of LAN prefixes for the site.";
+      uses ac-common:ipv4-static-rtg-entry;
+      leaf failure-detection-profile {
+        if-feature "vpn-common:bfd";
+        type failure-detection-profile-reference;
+        description
+          "Points to a failure detection profile.";
+      }
+      uses ac-common:service-status;
+    }
+  }
+
+  grouping ipv6-static-rtg-with-bfd {
+    description
+      "Configuration specific to IPv6 static routing with
+       failure protection (e.g., BFD).";
+    list ipv6-lan-prefix {
+      if-feature "vpn-common:ipv6";
+      key "lan next-hop";
+      description
+        "List of LAN prefixes for the site.";
+      uses ac-common:ipv6-static-rtg-entry;
+      leaf failure-detection-profile {
+        if-feature "vpn-common:bfd";
+        type failure-detection-profile-reference;
+        description
+          "Points to a failure detection profile.";
+      }
+      uses ac-common:service-status;
+    }
+  }
+
+  //  BGP Service 
+
+  grouping bgp-neighbor-without-name {
+    description
+      "A grouping with generic parameters for configuring a BGP 
+       neighbor.";
+    leaf remote-address {
+      type inet:ip-address;
+      description
+        "The remote IP address of this entry's BGP peer. This is
+         a customer IP address.
+
+         If this leaf is not present, this means that the primary
+         customer IP address is used as remote IP address.";
+    }
+    leaf local-address {
+      type inet:ip-address;
+      description
+        "The provider's IP address that will be used to establish
+         the BGP session.";
+    }
+    uses ac-common:bgp-peer-group-without-name;
+    container bgp-max-prefix {
+      description
+        "A container for the maximum number of BGP prefixes
+         allowed in the BGP session.";
+      leaf max-prefix {
+        type uint32;
+        description
+          "Indicates the maximum number of BGP prefixes allowed
+           in the BGP session.
+
+           It allows control of how many prefixes can be received
+           from a neighbor.";
+        reference
+          "RFC 4271: A Border Gateway Protocol 4 (BGP-4),
+                     Section 8.2.2";
+      }
+    }
+    uses ac-common:bgp-authentication;
+    uses ac-common:op-instructions;
+    uses ac-common:service-status;
+  }
+
+  grouping bgp-neighbor-with-name {
+    description
+      "A grouping with generic parameters for configuring a BGP 
+       neighbor with an identifier.";
+    leaf id {
+      type string;
+      description
+        "An identifier that uniquely identifies a neighbor.";
+    }
+    uses ac-svc:bgp-neighbor-without-name;
+  }
+
+  grouping bgp-neighbor-with-server-reference {
+    description
+      "A grouping with generic parameters for configuring a BGP 
+       neighbor with a reference generated by the provider.";
+    leaf server-reference {
+      if-feature "ac-common:server-assigned-reference";
+      type string;
+      config false;
+      description
+        "This is an internal reference for the service provider
+         to identify the BGP session.";
+    }
+    uses ac-svc:bgp-neighbor-without-name;
+  }
+
+  grouping bgp-neighbor-with-name-server-reference {
+    description
+      "A grouping with generic parameters for configuring a BGP 
+       neighbor with an identifier and a reference generated by 
+       the provider.";
+    leaf id {
+      type string;
+      description
+        "An identifier that uniquely identifiers a neighbor.";
+    }
+    uses ac-svc:bgp-neighbor-with-server-reference;
+  }
+
+  grouping bgp-svc {
+    description
+      "Configuration specific to BGP.";
+    container peer-groups {
+      description
+        "Configuration for BGP peer-groups";
+      list peer-group {
+        key "name";
+        description
+          "List of BGP peer-groups configured on the local 
+           system - uniquely identified by peer-group
+           name.";
+        uses ac-common:bgp-peer-group-with-name;
+        leaf local-address {
+          type inet:ip-address;
+          description
+            "The provider's local IP address that will be used to
+             establish the BGP session.";
+        }
+        container bgp-max-prefix {
+          description
+            "A container for the maximum number of BGP prefixes
+             allowed in the BGP session.";
+          leaf max-prefix {
+            type uint32;
+            description
+              "Indicates the maximum number of BGP prefixes allowed
+               in the BGP session.
+
+               It allows control of how many prefixes can be received
+               from a neighbor.";
+            reference
+              "RFC 4271: A Border Gateway Protocol 4 (BGP-4),
+                         Section 8.2.2";
+          }
+        }
+        uses ac-common:bgp-authentication;
+      }
+    }
+    list neighbor {
+      key "id";
+      description
+        "List of BGP neighbors.";
+      uses ac-svc:bgp-neighbor-with-name-server-reference;
+      leaf peer-group {
+        type leafref {
+          path "../../peer-groups/peer-group/name";
+        }
+        description
+          "The peer-group with which this neighbor is associated.";
+      }
+      leaf failure-detection-profile {
+        if-feature "vpn-common:bfd";
+        type failure-detection-profile-reference;
+        description
+          "Points to a failure detection profile.";
+      }
+    }
+  }
+
+  //  OSPF Service 
+
+  grouping ospf-svc {
+    description
+      "Service configuration specific to OSPF.";
+    uses ac-common:ospf-basic;
+    uses ac-common:ospf-authentication;
+    uses ac-common:service-status;
+  }
+
+  //  IS-IS Service 
+
+  grouping isis-svc {
+    description
+      "Service configuration specific to IS-IS.";
+    uses ac-common:isis-basic;
+    uses ac-common:isis-authentication;
+    uses ac-common:service-status;
+  }
+
+  //  RIP Service 
+
+  grouping rip-svc {
+    description
+      "Service configuration specific to RIP routing.";
+    leaf address-family {
+      type identityref {
+        base vpn-common:address-family;
+      }
+      description
+        "Indicates whether IPv4, IPv6, or both address families
+         are to be activated.";
+    }
+    uses ac-common:rip-authentication;
+    uses ac-common:service-status;
+  }
+
+  //  VRRP Service 
+
+  grouping vrrp-svc {
+    description
+      "Service configuration specific to VRRP.";
+    reference
+      "RFC 9568: Virtual Router Redundancy Protocol (VRRP)
+                 Version 3 for IPv4 and IPv6";
+    leaf address-family {
+      type identityref {
+        base vpn-common:address-family;
+      }
+      description
+        "Indicates whether IPv4, IPv6, or both
+         address families are to be enabled.";
+    }
+    uses ac-common:service-status;
+  }
+
+  // Basic routing parameters
+
+  grouping routing-basic {
+    description
+      "Defines basic parameters for routing protocols.";
+    list routing-protocol {
+      key "id";
+      description
+        "List of routing protocols used on the AC.";
+      leaf id {
+        type string;
+        description
+          "Unique identifier for the routing protocol.";
+      }
+      uses routing-protocol-list;
+      container bgp {
+        when
+          "derived-from-or-self(../type, 'vpn-common:bgp-routing')" {
+          description
+            "Only applies when the protocol is BGP.";
+        }
+        if-feature "vpn-common:rtg-bgp";
+        description
+          "Configuration specific to BGP.";
+        container peer-groups {
+          description
+            "Configuration for BGP peer-groups";
+          list peer-group {
+            key "name";
+            description
+              "List of BGP peer-groups configured on the local
+               system - uniquely identified by peer-group
+               name.";
+            uses ac-common:bgp-peer-group-with-name;
+          }
+        }
+      }
+      container ospf {
+        when "derived-from-or-self(../type, "
+           + "'vpn-common:ospf-routing')" {
+          description
+            "Only applies when the protocol is OSPF.";
+        }
+        if-feature "vpn-common:rtg-ospf";
+        description
+          "Configuration specific to OSPF.";
+        uses ac-common:ospf-basic;
+      }
+      container isis {
+        when "derived-from-or-self(../type, "
+           + "'vpn-common:isis-routing')" {
+          description
+            "Only applies when the protocol is IS-IS.";
+        }
+       if-feature "vpn-common:rtg-isis";
+        description
+          "Configuration specific to IS-IS.";
+        uses ac-common:isis-basic;
+      }
+      container rip {
+        when "derived-from-or-self(../type, "
+           + "'vpn-common:rip-routing')" {
+          description
+            "Only applies when the protocol is RIP.
+             For IPv4, the model assumes that RIP
+             version 2 is used.";
+        }
+        if-feature "vpn-common:rtg-rip";
+        description
+          "Configuration specific to RIP routing.";
+        leaf address-family {
+          type identityref {
+            base vpn-common:address-family;
+          }
+          description
+            "Indicates whether IPv4, IPv6, or both
+             address families are to be activated.";
+        }
+      }
+      container vrrp {
+        when "derived-from-or-self(../type, "
+           + "'vpn-common:vrrp-routing')" {
+          description
+            "Only applies when the protocol is the
+             Virtual Router Redundancy Protocol (VRRP).";
+        }
+        if-feature "vpn-common:rtg-vrrp";
+        description
+          "Configuration specific to VRRP.";
+        leaf address-family {
+          type identityref {
+            base vpn-common:address-family;
+          }
+          description
+            "Indicates whether IPv4, IPv6, or both address families
+             are to be enabled.";
+        }
+      }
+    }
+  }
+
+  // Full routing parameters
+
+  grouping routing {
+    description
+      "Defines routing protocols.";
+    list routing-protocol {
+      key "id";
+      description
+        "List of routing protocols used on the AC.";
+      leaf id {
+        type string;
+        description
+          "Unique identifier for the routing protocol.";
+      }
+      uses routing-protocol-list;
+      container static {
+        when "derived-from-or-self(../type, "
+           + "'vpn-common:static-routing')" {
+          description
+            "Only applies when the protocol is static routing
+             protocol.";
+        }
+        description
+          "Configuration specific to static routing.";
+        container cascaded-lan-prefixes {
+          description
+            "LAN prefixes from the customer.";
+          uses ipv4-static-rtg-with-bfd;
+          uses ipv6-static-rtg-with-bfd;
+        }
+      }
+      container bgp {
+        when "derived-from-or-self(../type, "
+           + "'vpn-common:bgp-routing')" {
+          description
+            "Only applies when the protocol is BGP.";
+        }
+        if-feature "vpn-common:rtg-bgp";
+        description
+          "Configuration specific to BGP.";
+        uses bgp-svc;
+      }
+      container ospf {
+        when "derived-from-or-self(../type, "
+           + "'vpn-common:ospf-routing')" {
+          description
+            "Only applies when the protocol is OSPF.";
+        }
+        if-feature "vpn-common:rtg-ospf";
+        description
+          "Configuration specific to OSPF.";
+        uses ospf-svc;
+      }
+      container isis {
+        when "derived-from-or-self(../type, "
+           + "'vpn-common:isis-routing')" {
+          description
+            "Only applies when the protocol is IS-IS.";
+        }
+        if-feature "vpn-common:rtg-isis";
+        description
+          "Configuration specific to IS-IS.";
+        uses isis-svc;
+      }
+      container rip {
+        when "derived-from-or-self(../type, "
+           + "'vpn-common:rip-routing')" {
+          description
+            "Only applies when the protocol is RIP.
+             For IPv4, the model assumes that RIP version 2 is
+             used.";
+        }
+        if-feature "vpn-common:rtg-rip";
+        description
+          "Configuration specific to RIP routing.";
+        uses rip-svc;
+      }
+      container vrrp {
+        when "derived-from-or-self(../type, "
+           + "'vpn-common:vrrp-routing')" {
+          description
+            "Only applies when the protocol is the Virtual Router
+             Redundancy Protocol (VRRP).";
+        }
+        if-feature "vpn-common:rtg-vrrp";
+        description
+          "Configuration specific to VRRP.";
+        uses vrrp-svc;
+      }
+    }
+  }
+
+  // Encryption choice
+
+  grouping encryption-choice {
+    description
+      "Container for the encryption profile.";
+    choice profile {
+      description
+        "Choice for the encryption profile.";
+      case provider-profile {
+        leaf provider-profile {
+          type encryption-profile-reference;
+          description
+            "Reference to a provider encryption profile.";
+        }
+      }
+      case customer-profile {
+        leaf customer-key-chain {
+          type key-chain:key-chain-ref;
+          description
+            "Customer-supplied key chain.";
+        }
+      }
+    }
+  }
+
+  // Basic security parameters
+
+  grouping ac-security-basic {
+    description
+      "AC-specific security parameters.";
+    container encryption {
+      if-feature "vpn-common:encryption";
+      description
+        "Container for AC security encryption.";
+      leaf enabled {
+        type boolean;
+        description
+          "If set to 'true', traffic encryption on the connection
+           is required.  Otherwise, it is disabled.";
+      }
+      leaf layer {
+        when "../enabled = 'true'" {
+          description
+            "Included only when encryption is enabled.";
+        }
+        type enumeration {
+          enum layer2 {
+            description
+              "Encryption occurs at Layer 2.";
+          }
+          enum layer3 {
+            description
+              "Encryption occurs at Layer 3.
+               For example, IPsec may be used when a customer 
+               requests Layer 3 encryption.";
+          }
+        }
+        description
+          "Indicates the layer on which encryption is applied.";
+      }
+    }
+    container encryption-profile {
+      when "../encryption/enabled = 'true'" {
+        description
+          "Indicates the layer on which encryption is enabled.";
+      }
+      description
+        "Container for the encryption profile.";
+      uses encryption-choice;
+    }
+  }
+
+  // Bandwith parameters
+
+  grouping bandwidth {
+    description
+      "Container for bandwidth.";
+    container svc-pe-to-ce-bandwidth {
+      if-feature "vpn-common:inbound-bw";
+      description
+        "From the customer site's perspective, the inbound
+         bandwidth of the AC or download bandwidth from the
+         service provider to the site.";
+      uses ac-common:bandwidth-per-type;
+    }
+    container svc-ce-to-pe-bandwidth {
+      if-feature "vpn-common:outbound-bw";
+      description
+        "From the customer site's perspective, the outbound
+         bandwidth of the AC or upload bandwidth from
+         the CE to the PE.";
+      uses ac-common:bandwidth-per-type;
+    }
+  }
+
+  // Basic AC parameters
+
+  grouping ac-basic {
+    description
+      "Grouping for basic parameters for an attachment circuit.";
+    leaf name {
+      type string;
+      description
+        "A name that uniquely identifies the AC.";
+    }
+    container l2-connection {
+      if-feature "ac-common:layer2-ac";
+      description
+        "Defines Layer 2 protocols and parameters that are required 
+         to enable AC connectivity.";
+      uses l2-connection-basic;
+    }
+    container ip-connection {
+      if-feature "ac-common:layer3-ac";
+      description
+        "Defines IP connection parameters.";
+      uses ip-connection-basic;
+    }
+    container routing-protocols {
+      description
+        "Defines routing protocols.";
+      uses routing-basic;
+    }
+    container oam {
+      description
+        "Defines the Operations, Administration, and Maintenance
+         (OAM) mechanisms used.";
+      container bfd {
+        if-feature "vpn-common:bfd";
+        description
+          "Container for BFD.";
+        uses ac-common:bfd;
+      }
+    }
+    container security {
+      description
+        "AC-specific security parameters.";
+      uses ac-security-basic;
+    }
+    container service {
+      description
+        "AC-specific bandwith parameters.";
+      leaf mtu {
+        type uint32;
+        units "bytes";
+        description
+          "Layer 2 MTU.";
+      }
+      uses bandwidth;
+    }
+  }
+
+  // Full AC parameters
+
+  grouping ac {
+    description
+      "Grouping for an attachment circuit.";
+    leaf name {
+      type string;
+      description
+        "A name of the AC. Data models that need to reference  
+         an attachment circuit should use 
+         attachment-circuit-reference.";
+    }
+    leaf-list service-profile {
+      type service-profile-reference;
+      description
+        "A reference to a service profile.";
+    }
+    container l2-connection {
+      if-feature "ac-common:layer2-ac";
+      description
+        "Defines Layer 2 protocols and parameters that are required 
+         to enable AC connectivity.";
+      uses l2-connection;
+    }
+    container ip-connection {
+      if-feature "ac-common:layer3-ac";
+      description
+        "Defines IP connection parameters.";
+      uses ip-connection;
+    }
+    container routing-protocols {
+      description
+        "Defines routing protocols.";
+      uses routing;
+    }
+    container oam {
+      description
+        "Defines the OAM mechanisms used.";
+      container bfd {
+        if-feature "vpn-common:bfd";
+        description
+          "Container for BFD.";
+        list session {
+          key "id";
+          description
+            "List of BFD sessions.";
+          leaf id {
+             type string;
+             description
+               "A unique identifer for the BFD session.";
+          }
+          leaf local-address {
+            type inet:ip-address;
+            description
+              "Provider's IP address of the BFD session.";
+          }
+          leaf remote-address {
+            type inet:ip-address;
+            description
+              "Customer's IP address of the BFD session.";
+          }
+          leaf profile {
+            type failure-detection-profile-reference;
+            description
+              "Points to a BFD profile.";
+          }
+          uses ac-common:bfd;
+          uses ac-common:service-status;
+        } 
+      }
+    }
+    container security {
+      description
+        "AC-specific security parameters.";
+      uses ac-security-basic;
+    }
+    container service {
+      description
+        "AC-specific bandwith parameters.";
+      leaf mtu {
+        type uint32;
+        units "bytes";
+        description
+          "Layer 2 MTU.";
+      }
+      uses bandwidth;
+      container qos {
+        if-feature "vpn-common:qos";
+        description
+          "QoS configuration.";
+        container qos-profiles {
+          description
+            "QoS profile configuration.";
+          list qos-profile {
+            key "profile";
+            description
+              "Points to a QoS profile.";
+            leaf profile {
+              type qos-profile-reference;
+              description
+                "QoS profile to be used.";
+            }
+            leaf direction {
+              type identityref {
+                base vpn-common:qos-profile-direction;
+              }
+              description
+                "The direction to which the QoS profile
+                 is applied.";
+            }
+          }
+        }
+      }
+      container access-control-list {
+        description
+          "Container for the Access Control List (ACL).";
+        container acl-profiles {
+          description
+            "ACL profile configuration.";
+          list acl-profile {
+            key "profile";
+            description
+              "Points to an ACL profile.";
+            leaf profile {
+              type forwarding-profile-reference;
+              description
+                "Forwarding profile to be used.";
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // Parent and Child ACs
+
+  grouping ac-hierarchy {
+    description
+      "Container for parent and child AC references.";
+    leaf-list parent-ref {
+      type ac-svc:attachment-circuit-reference;
+      description
+        "Specifies a parent AC that is inherited by an AC.
+         In contexts where dynamic terminating points are 
+         bound to the same AC, a parent AC with stable
+         information is created with a set of child ACs
+         to track dynamic AC information.";
+    }
+    leaf-list child-ref {
+      type ac-svc:attachment-circuit-reference;
+      config false;
+      description
+        "Specifies a child AC that relies upon a parent AC.";
+    }
+  }
+
+  /******************** Main AC containers ********************/
+
+  container specific-provisioning-profiles {
+    description
+      "Contains a set of valid profiles to reference for an AC.";
+    uses ac-common:ac-profile-cfg;
+  }
+  container service-provisioning-profiles {
+    description
+      "Contains a set of valid profiles to reference for an AC.";
+    list service-profile-identifier {
+      key "id";
+      description
+        "List of generic service profile identifiers.";
+      leaf id {
+        type string;
+        description
+          "Identification of the service profile to be used.
+           The profile only has significance within the service
+           provider's administrative domain.";
+      }
+    }
+    nacm:default-deny-write;
+  }
+  container attachment-circuits {
+    description
+      "Main container for the attachment circuits.";
+    list ac-group-profile {
+      key "name";
+      description
+        "Maintains a list of profiles that are shared among
+         a set of ACs.";
+      uses ac;
+    }
+    container placement-constraints {
+      description
+        "Diversity constraint type.";
+      uses vpn-common:placement-constraints;
+    }
+    leaf customer-name {
+      type string;
+      description
+        "Indicates the name of the customer that requested these
+         ACs.";
+    }
+    uses ac-common:op-instructions;
+    list ac {
+      key "name";
+      description
+        "Global provisioning of attachment circuits.";
+      leaf customer-name {
+        type string;
+        description
+          "Indicates the name of the customer that requested this
+           AC.";
+      }
+      leaf description {
+        type string;
+        description
+          "Associates a description with an AC.";
+      }
+      leaf test-only {
+        type empty;
+        description
+         "When present, this indicates that this is a feasibility
+          check request. No resources are commited for such AC 
+          requests.";
+      }
+      uses ac-common:op-instructions;
+      leaf role {
+        type identityref {
+          base ac-common:role;
+        }
+        description
+          "Indicates whether this AC is used as UNI, NNI, etc.";
+      }
+      leaf-list peer-sap-id {
+        type string;
+        description
+          "One or more peer SAPs can be indicated.";
+      }
+      leaf-list group-profile-ref {
+        type ac-group-reference;
+        description
+          "A reference to an AC profile.";
+      }
+      uses ac-hierarchy;
+      uses ac-common:redundancy-group;
+      list service-ref {
+        key "service-type service-id";
+        config false;
+        description
+          "Reports the set of services that are bound to the AC.";
+        leaf service-type {
+          type identityref {
+            base vpn-common:service-type;
+          }
+          description
+            "Indicates the service type (e.g., L3VPN or Network Slice
+             Service).";
+          reference
+            "RFC 9408: A YANG Network Data Model for Service 
+                       Attachment Points (SAPs), Section 5";
+        }
+        leaf service-id {
+          type string;
+          description
+            "Indicates an identifier of a service instance
+             of a given type that uses the AC.";
+        }
+      }
+      leaf server-reference {
+        if-feature "ac-common:server-assigned-reference";
+        type string;
+        config false;
+        description
+          "Reports an internal reference for the service provider
+           to identify the AC.";
+      }
+      uses ac;
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-ethertypes@2019-03-04.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-ethertypes@2019-03-04.yang
new file mode 100644
index 0000000000000000000000000000000000000000..fd055074aeba5c277bbefdce0b81ebd24d0d3551
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-ethertypes@2019-03-04.yang
@@ -0,0 +1,381 @@
+module ietf-ethertypes {
+  namespace "urn:ietf:params:xml:ns:yang:ietf-ethertypes";
+  prefix ethertypes;
+
+  organization
+    "IETF NETMOD (Network Modeling) Working Group.";
+
+  contact
+    "WG Web:   <https://datatracker.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     Editor:   Mahesh Jethanandani
+               <mjethanandani@gmail.com>";
+
+  description
+    "This module contains common definitions for the
+     Ethertype used by different modules.  It is a
+     placeholder module, till such time that IEEE
+     starts a project to define these Ethertypes
+     and publishes a standard.
+
+     At that time, this module can be deprecated.
+
+     Copyright (c) 2019 IETF Trust and the persons identified as
+     the document authors.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD
+     License set forth in Section 4.c of the IETF Trust's Legal
+     Provisions Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 8519; see
+     the RFC itself for full legal notices.";
+
+  revision 2019-03-04 {
+    description
+      "Initial revision.";
+    reference
+      "RFC 8519: YANG Data Model for Network Access Control
+                 Lists (ACLs).";
+  }
+
+  typedef ethertype {
+    type union {
+      type uint16;
+      type enumeration {
+        enum ipv4 {
+          value 2048;
+          description
+            "Internet Protocol version 4 (IPv4) with a
+             hex value of 0x0800.";
+          reference
+            "RFC 791: Internet Protocol.";
+        }
+        enum arp {
+          value 2054;
+          description
+            "Address Resolution Protocol (ARP) with a
+             hex value of 0x0806.";
+          reference
+            "RFC 826: An Ethernet Address Resolution Protocol: Or
+                      Converting Network Protocol Addresses to 48.bit
+                      Ethernet Address for Transmission on Ethernet
+                      Hardware.";
+        }
+        enum wlan {
+          value 2114;
+          description
+            "Wake-on-LAN.  Hex value of 0x0842.";
+        }
+        enum trill {
+          value 8947;
+          description
+            "Transparent Interconnection of Lots of Links.
+             Hex value of 0x22F3.";
+          reference
+            "RFC 6325: Routing Bridges (RBridges): Base Protocol
+                       Specification.";
+        }
+        enum srp {
+          value 8938;
+          description
+            "Stream Reservation Protocol.  Hex value of
+             0x22EA.";
+          reference
+            "IEEE 801.1Q-2011.";
+        }
+        enum decnet {
+          value 24579;
+          description
+            "DECnet Phase IV.  Hex value of 0x6003.";
+        }
+        enum rarp {
+          value 32821;
+          description
+            "Reverse Address Resolution Protocol.
+             Hex value 0x8035.";
+          reference
+            "RFC 903: A Reverse Address Resolution Protocol.";
+        }
+        enum appletalk {
+          value 32923;
+          description
+            "Appletalk (Ethertalk).  Hex value of 0x809B.";
+        }
+        enum aarp {
+          value 33011;
+          description
+            "Appletalk Address Resolution Protocol.  Hex value
+             of 0x80F3.";
+        }
+        enum vlan {
+          value 33024;
+          description
+            "VLAN-tagged frame (IEEE 802.1Q) and Shortest Path
+             Bridging IEEE 802.1aq with Network-Network
+             Interface (NNI) compatibility.  Hex value of
+             0x8100.";
+          reference
+            "IEEE 802.1Q.";
+        }
+        enum ipx {
+          value 33079;
+          description
+            "Internetwork Packet Exchange (IPX).  Hex value
+             of 0x8137.";
+        }
+        enum qnx {
+          value 33284;
+          description
+            "QNX Qnet.  Hex value of 0x8204.";
+        }
+        enum ipv6 {
+          value 34525;
+          description
+            "Internet Protocol Version 6 (IPv6).  Hex value
+             of 0x86DD.";
+          reference
+            "RFC 8200: Internet Protocol, Version 6 (IPv6)
+                       Specification
+             RFC 8201: Path MTU Discovery for IP version 6.";
+        }
+        enum efc {
+          value 34824;
+          description
+            "Ethernet flow control using pause frames.
+             Hex value of 0x8808.";
+          reference
+            "IEEE 802.1Qbb.";
+        }
+        enum esp {
+          value 34825;
+          description
+            "Ethernet Slow Protocol.  Hex value of 0x8809.";
+          reference
+            "IEEE 802.3-2015.";
+        }
+        enum cobranet {
+          value 34841;
+          description
+            "CobraNet.  Hex value of 0x8819.";
+        }
+        enum mpls-unicast {
+          value 34887;
+          description
+            "Multiprotocol Label Switching (MPLS) unicast traffic.
+             Hex value of 0x8847.";
+          reference
+            "RFC 3031: Multiprotocol Label Switching Architecture.";
+        }
+        enum mpls-multicast {
+          value 34888;
+          description
+            "MPLS multicast traffic.  Hex value of 0x8848.";
+          reference
+            "RFC 3031: Multiprotocol Label Switching Architecture.";
+        }
+        enum pppoe-discovery {
+          value 34915;
+          description
+            "Point-to-Point Protocol over Ethernet.  Used during
+             the discovery process.  Hex value of 0x8863.";
+          reference
+            "RFC 2516: A Method for Transmitting PPP Over Ethernet
+                       (PPPoE).";
+        }
+        enum pppoe-session {
+          value 34916;
+          description
+            "Point-to-Point Protocol over Ethernet.  Used during
+             session stage.  Hex value of 0x8864.";
+          reference
+            "RFC 2516: A Method for Transmitting PPP Over Ethernet
+                       (PPPoE).";
+        }
+        enum intel-ans {
+          value 34925;
+          description
+            "Intel Advanced Networking Services.  Hex value of
+             0x886D.";
+        }
+        enum jumbo-frames {
+          value 34928;
+          description
+            "Jumbo frames or Ethernet frames with more than
+             1500 bytes of payload, up to 9000 bytes.";
+        }
+        enum homeplug {
+          value 34939;
+          description
+            "Family name for the various power line
+             communications.  Hex value of 0x887B.";
+        }
+        enum eap {
+          value 34958;
+          description
+            "Ethernet Access Protocol (EAP) over LAN.  Hex value
+             of 0x888E.";
+          reference
+            "IEEE 802.1X.";
+        }
+        enum profinet {
+          value 34962;
+          description
+            "PROcess FIeld Net (PROFINET).  Hex value of 0x8892.";
+        }
+        enum hyperscsi {
+          value 34970;
+          description
+            "Small Computer System Interface (SCSI) over Ethernet.
+             Hex value of 0x889A.";
+        }
+        enum aoe {
+          value 34978;
+          description
+            "Advanced Technology Advancement (ATA) over Ethernet.
+             Hex value of 0x88A2.";
+        }
+        enum ethercat {
+          value 34980;
+          description
+            "Ethernet for Control Automation Technology (EtherCAT).
+             Hex value of 0x88A4.";
+        }
+        enum provider-bridging {
+          value 34984;
+          description
+            "Provider Bridging (802.1ad) and Shortest Path Bridging
+             (801.1aq).  Hex value of 0x88A8.";
+          reference
+            "IEEE 802.1ad and IEEE 802.1aq).";
+        }
+        enum ethernet-powerlink {
+          value 34987;
+          description
+            "Ethernet Powerlink.  Hex value of 0x88AB.";
+        }
+        enum goose {
+          value 35000;
+          description
+            "Generic Object Oriented Substation Event (GOOSE).
+             Hex value of 0x88B8.";
+          reference
+            "IEC/ISO 8802-2 and 8802-3.";
+        }
+        enum gse {
+          value 35001;
+          description
+            "Generic Substation Events.  Hex value of 88B9.";
+          reference
+            "IEC 61850.";
+        }
+        enum sv {
+          value 35002;
+          description
+            "Sampled Value Transmission.  Hex value of 0x88BA.";
+          reference
+            "IEC 61850.";
+        }
+        enum lldp {
+          value 35020;
+          description
+            "Link Layer Discovery Protocol (LLDP).  Hex value of
+             0x88CC.";
+          reference
+            "IEEE 802.1AB.";
+        }
+        enum sercos {
+          value 35021;
+          description
+            "Sercos Interface.  Hex value of 0x88CD.";
+        }
+        enum wsmp {
+          value 35036;
+          description
+            "WAVE Short Message Protocol (WSMP).  Hex value of
+             0x88DC.";
+        }
+        enum homeplug-av-mme {
+          value 35041;
+          description
+            "HomePlug AV Mobile Management Entity (MME).  Hex value
+             of 88E1.";
+        }
+        enum mrp {
+          value 35043;
+          description
+            "Media Redundancy Protocol (MRP).  Hex value of
+             0x88E3.";
+          reference
+            "IEC 62439-2.";
+        }
+        enum macsec {
+          value 35045;
+          description
+            "MAC Security.  Hex value of 0x88E5.";
+          reference
+            "IEEE 802.1AE.";
+        }
+        enum pbb {
+          value 35047;
+          description
+            "Provider Backbone Bridges (PBB).  Hex value of
+             0x88E7.";
+          reference
+            "IEEE 802.1ah.";
+        }
+        enum cfm {
+          value 35074;
+          description
+            "Connectivity Fault Management (CFM).  Hex value of
+             0x8902.";
+          reference
+            "IEEE 802.1ag.";
+        }
+        enum fcoe {
+          value 35078;
+          description
+            "Fiber Channel over Ethernet (FCoE).  Hex value of
+             0x8906.";
+          reference
+            "T11 FC-BB-5.";
+        }
+        enum fcoe-ip {
+          value 35092;
+          description
+            "FCoE Initialization Protocol.  Hex value of 0x8914.";
+        }
+        enum roce {
+          value 35093;
+          description
+            "RDMA over Converged Ethernet (RoCE).  Hex value of
+             0x8915.";
+        }
+        enum tte {
+          value 35101;
+          description
+            "TTEthernet Protocol Control Frame (TTE).  Hex value
+             of 0x891D.";
+          reference
+            "SAE AS6802.";
+        }
+        enum hsr {
+          value 35119;
+          description
+            "High-availability Seamless Redundancy (HSR).  Hex
+             value of 0x892F.";
+          reference
+            "IEC 62439-3:2016.";
+        }
+      }
+    }
+    description
+      "The uint16 type placeholder is defined to enable
+       users to manage their own ethertypes not
+       covered by the module.  Otherwise, the module contains
+       enum definitions for the more commonly used ethertypes.";
+  }
+}
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-geo-location@2022-02-11.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-geo-location@2022-02-11.yang
new file mode 100644
index 0000000000000000000000000000000000000000..b815446f819ac2dcba50e63e5781e8a1be9b59c6
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-geo-location@2022-02-11.yang
@@ -0,0 +1,278 @@
+module ietf-geo-location {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-geo-location";
+  prefix geo;
+  import ietf-yang-types {
+    prefix yang;
+    reference "RFC 6991: Common YANG Data Types";
+  }
+
+  organization
+    "IETF NETMOD Working Group (NETMOD)";
+  contact
+   "WG Web:   <https://datatracker.ietf.org/wg/netmod/>
+    WG List:  <mailto:netmod@ietf.org>
+
+    Editor:   Christian Hopps
+              <mailto:chopps@chopps.org>";
+
+  description
+    "This module defines a grouping of a container object for
+     specifying a location on or around an astronomical object (e.g.,
+     'earth').
+
+     The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL
+     NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED',
+     'MAY', and 'OPTIONAL' in this document are to be interpreted as
+     described in BCP 14 (RFC 2119) (RFC 8174) when, and only when,
+     they appear in all capitals, as shown here.
+
+     Copyright (c) 2022 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms,
+     with or without modification, is permitted pursuant to,
+     and subject to the license terms contained in, the
+     Revised BSD License set forth in Section 4.c of the
+     IETF Trust's Legal Provisions Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 9179
+     (https://www.rfc-editor.org/info/rfc9179); see the RFC itself
+     for full legal notices.";
+
+  revision 2022-02-11 {
+    description
+      "Initial Revision";
+    reference
+      "RFC 9179: A YANG Grouping for Geographic Locations";
+  }
+
+  feature alternate-systems {
+    description
+      "This feature means the device supports specifying locations
+       using alternate systems for reference frames.";
+  }
+
+  grouping geo-location {
+    description
+      "Grouping to identify a location on an astronomical object.";
+
+    container geo-location {
+      description
+        "A location on an astronomical body (e.g., 'earth')
+         somewhere in a universe.";
+
+      container reference-frame {
+        description
+          "The Frame of Reference for the location values.";
+
+        leaf alternate-system {
+          if-feature "alternate-systems";
+          type string;
+          description
+            "The system in which the astronomical body and
+             geodetic-datum is defined.  Normally, this value is not
+             present and the system is the natural universe; however,
+             when present, this value allows for specifying alternate
+             systems (e.g., virtual realities).  An alternate-system
+             modifies the definition (but not the type) of the other
+             values in the reference frame.";
+        }
+        leaf astronomical-body {
+          type string {
+            pattern '[ -@\[-\^_-~]*';
+          }
+          default "earth";
+          description
+            "An astronomical body as named by the International
+             Astronomical Union (IAU) or according to the alternate
+             system if specified.  Examples include 'sun' (our star),
+             'earth' (our planet), 'moon' (our moon), 'enceladus' (a
+             moon of Saturn), 'ceres' (an asteroid), and
+             '67p/churyumov-gerasimenko (a comet).  The ASCII value
+             SHOULD have uppercase converted to lowercase and not
+             include control characters (i.e., values 32..64, and
+             91..126).  Any preceding 'the' in the name SHOULD NOT be
+             included.";
+          reference
+            "https://www.iau.org/";
+        }
+        container geodetic-system {
+          description
+            "The geodetic system of the location data.";
+          leaf geodetic-datum {
+            type string {
+              pattern '[ -@\[-\^_-~]*';
+            }
+            description
+              "A geodetic-datum defining the meaning of latitude,
+               longitude, and height.  The default when the
+               astronomical body is 'earth' is 'wgs-84', which is
+               used by the Global Positioning System (GPS).  The
+               ASCII value SHOULD have uppercase converted to
+               lowercase and not include control characters
+               (i.e., values 32..64, and 91..126).  The IANA registry
+               further restricts the value by converting all spaces
+               (' ') to dashes ('-').
+               The specification for the geodetic-datum indicates
+               how accurately it models the astronomical body in
+               question, both for the 'horizontal'
+               latitude/longitude coordinates and for height
+               coordinates.";
+            reference
+              "RFC 9179: A YANG Grouping for Geographic Locations,
+               Section 6.1";
+          }
+          leaf coord-accuracy {
+            type decimal64 {
+              fraction-digits 6;
+            }
+            description
+              "The accuracy of the latitude/longitude pair for
+               ellipsoidal coordinates, or the X, Y, and Z components
+               for Cartesian coordinates.  When coord-accuracy is
+               specified, it indicates how precisely the coordinates
+               in the associated list of locations have been
+               determined with respect to the coordinate system
+               defined by the geodetic-datum.  For example, there
+               might be uncertainty due to measurement error if an
+               experimental measurement was made to determine each
+               location.";
+          }
+          leaf height-accuracy {
+            type decimal64 {
+              fraction-digits 6;
+            }
+            units "meters";
+            description
+              "The accuracy of the height value for ellipsoidal
+               coordinates; this value is not used with Cartesian
+               coordinates.  When height-accuracy is specified, it
+               indicates how precisely the heights in the
+               associated list of locations have been determined
+               with respect to the coordinate system defined by the
+               geodetic-datum.  For example, there might be
+               uncertainty due to measurement error if an
+               experimental measurement was made to determine each
+               location.";
+          }
+        }
+      }
+      choice location {
+        description
+          "The location data either in latitude/longitude or
+           Cartesian values";
+        case ellipsoid {
+          leaf latitude {
+            type decimal64 {
+              fraction-digits 16;
+            }
+            units "decimal degrees";
+            description
+              "The latitude value on the astronomical body.  The
+               definition and precision of this measurement is
+               indicated by the reference-frame.";
+          }
+          leaf longitude {
+            type decimal64 {
+              fraction-digits 16;
+            }
+            units "decimal degrees";
+            description
+              "The longitude value on the astronomical body.  The
+               definition and precision of this measurement is
+               indicated by the reference-frame.";
+          }
+          leaf height {
+            type decimal64 {
+              fraction-digits 6;
+            }
+            units "meters";
+            description
+              "Height from a reference 0 value.  The precision and
+               '0' value is defined by the reference-frame.";
+          }
+        }
+        case cartesian {
+          leaf x {
+            type decimal64 {
+              fraction-digits 6;
+            }
+            units "meters";
+            description
+              "The X value as defined by the reference-frame.";
+          }
+          leaf y {
+            type decimal64 {
+              fraction-digits 6;
+            }
+            units "meters";
+            description
+              "The Y value as defined by the reference-frame.";
+          }
+          leaf z {
+            type decimal64 {
+              fraction-digits 6;
+            }
+            units "meters";
+            description
+              "The Z value as defined by the reference-frame.";
+          }
+        }
+      }
+      container velocity {
+        description
+          "If the object is in motion, the velocity vector describes
+           this motion at the time given by the timestamp.  For a
+           formula to convert these values to speed and heading, see
+           RFC 9179.";
+        reference
+          "RFC 9179: A YANG Grouping for Geographic Locations";
+
+        leaf v-north {
+          type decimal64 {
+            fraction-digits 12;
+          }
+          units "meters per second";
+          description
+            "v-north is the rate of change (i.e., speed) towards
+             true north as defined by the geodetic-system.";
+        }
+
+        leaf v-east {
+          type decimal64 {
+            fraction-digits 12;
+          }
+          units "meters per second";
+          description
+            "v-east is the rate of change (i.e., speed) perpendicular
+             to the right of true north as defined by
+             the geodetic-system.";
+        }
+
+        leaf v-up {
+          type decimal64 {
+            fraction-digits 12;
+          }
+          units "meters per second";
+          description
+            "v-up is the rate of change (i.e., speed) away from the
+             center of mass.";
+        }
+      }
+      leaf timestamp {
+        type yang:date-and-time;
+        description
+          "Reference time when location was recorded.";
+      }
+      leaf valid-until {
+        type yang:date-and-time;
+        description
+          "The timestamp for which this geo-location is valid until.
+           If unspecified, the geo-location has no specific
+           expiration time.";
+      }
+    }
+  }
+}
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-inet-types@2024-10-21.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-inet-types@2024-10-21.yang
new file mode 100644
index 0000000000000000000000000000000000000000..78c5201baf73f339d3ac409083b1f8ea13682faf
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-inet-types@2024-10-21.yang
@@ -0,0 +1,657 @@
+module ietf-inet-types {
+
+  namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+  prefix "inet";
+
+  organization
+   "IETF Network Modeling (NETMOD) Working Group";
+
+  contact
+   "WG Web:   <https://datatracker.ietf.org/wg/netmod/>
+    WG List:  <mailto:netmod@ietf.org>
+
+    Editor:   Juergen Schoenwaelder
+              <mailto:jschoenwaelder@constructor.university>";
+
+  description
+   "This module contains a collection of generally useful derived
+    YANG data types for Internet addresses and related things.
+
+    The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL
+    NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED',
+    'MAY', and 'OPTIONAL' in this document are to be interpreted as
+    described in BCP 14 (RFC 2119) (RFC 8174) when, and only when,
+    they appear in all capitals, as shown here.
+
+    Copyright (c) 2024 IETF Trust and the persons identified as
+    authors of the code.  All rights reserved.
+
+    Redistribution and use in source and binary forms, with or
+    without modification, is permitted pursuant to, and subject
+    to the license terms contained in, the Revised BSD License
+    set forth in Section 4.c of the IETF Trust's Legal Provisions
+    Relating to IETF Documents
+    (https://trustee.ietf.org/license-info).
+
+    This version of this YANG module is part of RFC XXXX;
+    see the RFC itself for full legal notices.";
+
+  revision 2024-10-21 {
+    description
+     "This revision adds the following new data types:
+      - inet:ip-address-and-prefix
+      - inet:ipv4-address-and-prefix
+      - inet:ipv6-address-and-prefix
+      - inet:protocol-number
+      - inet:host-name
+      - inet:email-address
+      - inet:ip-address-link-local
+      - inet:ipv4-address-link-local
+      - inet:ipv6-address-link-local
+      The inet:host union was changed to use inet:host-name instead
+      of inet:domain-name. Several pattern statements have been
+      improved.";
+    reference 
+     "RFC XXXX: Common YANG Data Types";
+  }
+
+  revision 2013-07-15 {
+    description
+     "This revision adds the following new data types:
+      - inet:ip-address-no-zone
+      - inet:ipv4-address-no-zone
+      - inet:ipv6-address-no-zone";
+    reference 
+     "RFC 6991: Common YANG Data Types";
+  }
+
+  revision 2010-09-24 {
+    description
+     "Initial revision.";
+    reference 
+     "RFC 6021: Common YANG Data Types";
+  }
+
+  /*** collection of types related to protocol fields ***/
+
+  typedef ip-version {
+    type enumeration {
+      enum unknown {
+        value "0"; 
+        description
+         "An unknown or unspecified version of the Internet
+          protocol.";
+      }
+      enum ipv4 {
+        value "1";
+        description
+         "The IPv4 protocol as defined in RFC 791.";
+      }
+      enum ipv6 {
+        value "2";
+        description
+         "The IPv6 protocol as defined in RFC 8200.";
+      }
+    }
+    description
+     "This value represents the version of the IP protocol.
+
+      In the value set and its semantics, this type is equivalent
+      to the InetVersion textual convention of the SMIv2.";
+    reference
+     "RFC  791: Internet Protocol
+      RFC 8200: Internet Protocol, Version 6 (IPv6) Specification
+      RFC 4001: Textual Conventions for Internet Network Addresses";
+  }
+
+  typedef dscp {
+    type uint8 {
+      range "0..63";
+    }
+    description
+     "The dscp type represents a Differentiated Services Code Point
+      that may be used for marking packets in a traffic stream.
+
+      In the value set and its semantics, this type is equivalent
+      to the Dscp textual convention of the SMIv2.";
+    reference 
+     "RFC 3289: Management Information Base for the Differentiated
+                Services Architecture
+      RFC 2474: Definition of the Differentiated Services Field
+                (DS Field) in the IPv4 and IPv6 Headers
+      RFC 2780: IANA Allocation Guidelines For Values In
+                the Internet Protocol and Related Headers";
+  }
+
+  typedef ipv6-flow-label {
+    type uint32 {
+      range "0..1048575";
+    }
+    description
+     "The ipv6-flow-label type represents the flow identifier or 
+      Flow Label in an IPv6 packet header that may be used to
+      discriminate traffic flows.
+
+      In the value set and its semantics, this type is equivalent
+      to the IPv6FlowLabel textual convention of the SMIv2.";
+    reference
+     "RFC 3595: Textual Conventions for IPv6 Flow Label
+      RFC 8200: Internet Protocol, Version 6 (IPv6) Specification";
+  }
+
+  typedef port-number {
+    type uint16 {
+      range "0..65535";
+    }
+    description
+     "The port-number type represents a 16-bit port number of an 
+      Internet transport-layer protocol such as UDP, TCP, DCCP, or 
+      SCTP.
+
+      Port numbers are assigned by IANA.  The current list of
+      all assignments is available from <https://www.iana.org/>.
+
+      Note that the port number value zero is reserved by IANA.  In
+      situations where the value zero does not make sense, it can
+      be excluded by subtyping the port-number type.
+
+      In the value set and its semantics, this type is equivalent
+      to the InetPortNumber textual convention of the SMIv2.";
+    reference
+     "RFC  768: User Datagram Protocol
+      RFC 9293: Transmission Control Protocol (TCP)
+      RFC 9260: Stream Control Transmission Protocol
+      RFC 4340: Datagram Congestion Control Protocol (DCCP)
+      RFC 4001: Textual Conventions for Internet Network Addresses";
+  }
+
+  typedef protocol-number {
+    type uint8;
+    description
+     "The protocol-number type represents an 8-bit Internet
+      protocol number, carried in the 'protocol' field of the
+      IPv4 header or in the 'next header' field of the IPv6
+      header. If IPv6 extension headers are present, then the
+      protocol number type represents the upper layer protocol 
+      number, i.e., the number of the last 'next header' field 
+      of the IPv6 extension headers.
+
+      Protocol numbers are assigned by IANA. The current list of
+      all assignments is available from <https://www.iana.org/>.";
+    reference
+     "RFC  791: Internet Protocol
+      RFC 8200: Internet Protocol, Version 6 (IPv6) Specification";
+  }
+
+  /*** collection of types related to autonomous systems ***/
+
+  typedef as-number {
+    type uint32;
+    description
+     "The as-number type represents autonomous system numbers
+      which identify an Autonomous System (AS).  An AS is a set
+      of routers under a single technical administration, using
+      an interior gateway protocol and common metrics to route
+      packets within the AS, and using an exterior gateway
+      protocol to route packets to other ASes.  IANA maintains
+      the AS number space and has delegated large parts to the
+      regional registries.
+
+      Autonomous system numbers were originally limited to 16 
+      bits.  BGP extensions have enlarged the autonomous system
+      number space to 32 bits.  This type therefore uses an uint32
+      base type without a range restriction in order to support
+      a larger autonomous system number space.
+
+      In the value set and its semantics, this type is equivalent
+      to the InetAutonomousSystemNumber textual convention of 
+      the SMIv2.";
+    reference
+     "RFC 1930: Guidelines for creation, selection, and registration
+                of an Autonomous System (AS)
+      RFC 4271: A Border Gateway Protocol 4 (BGP-4)
+      RFC 4001: Textual Conventions for Internet Network Addresses
+      RFC 6793: BGP Support for Four-Octet Autonomous System (AS)
+                Number Space";
+  }
+
+  /*** collection of types related to IP addresses and hostnames ***/
+
+  typedef ip-address {
+    type union {
+      type ipv4-address;
+      type ipv6-address;
+    }
+    description
+     "The ip-address type represents an IP address and is IP 
+      version neutral.  The format of the textual representation
+      implies the IP version.  This type supports scoped addresses
+      by allowing zone identifiers in the address format.";
+    reference
+     "RFC 4007: IPv6 Scoped Address Architecture";
+  }
+
+  typedef ipv4-address {
+    type string {
+      pattern 
+        '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+      +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+      + '(%.+)?';
+    }
+    description
+      "The ipv4-address type represents an IPv4 address in 
+       dotted-quad notation.  The IPv4 address may include a zone
+       index, separated by a % sign. If a system uses zone names
+       that are not represented in UTF-8, then an implementation
+       needs to use some mechanism to transform the local name
+       into UTF-8. The definition of such a mechanism is outside
+       the scope of this document.
+
+       The zone index is used to disambiguate identical address
+       values.  For link-local addresses, the zone index will
+       typically be the interface index number or the name of an
+       interface.  If the zone index is not present, the default
+       zone of the device will be used.
+
+       The canonical format for the zone index is the numerical
+       format";
+  }
+
+  typedef ipv6-address {
+    type string {
+      pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+            + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+            + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+            + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+            + '(%[A-Za-z0-9][A-Za-z0-9\-\._~/]*)?';
+      pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+            + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+            + '(%.+)?';
+    }
+    description
+     "The ipv6-address type represents an IPv6 address in full,
+      mixed, shortened, and shortened-mixed notation.  The IPv6
+      address may include a zone index, separated by a % sign.
+      If a system uses zone names that are not represented in
+      UTF-8, then an implementation needs to use some mechanism
+      to transform the local name into UTF-8. The definition of
+      such a mechanism is outside the scope of this document.
+
+      The zone index is used to disambiguate identical address
+      values.  For link-local addresses, the zone index will
+      typically be the interface index number or the name of an
+      interface.  If the zone index is not present, the default
+      zone of the device will be used.
+
+      The canonical format of IPv6 addresses uses the textual
+      representation defined in Section 4 of RFC 5952.  The
+      canonical format for the zone index is the numerical
+      format as described in Section 11.2 of RFC 4007.";
+    reference
+     "RFC 4291: IP Version 6 Addressing Architecture
+      RFC 4007: IPv6 Scoped Address Architecture
+      RFC 5952: A Recommendation for IPv6 Address Text
+                Representation";
+  }
+
+  typedef ip-address-no-zone {
+    type union {
+      type ipv4-address-no-zone;
+      type ipv6-address-no-zone;
+    }
+    description
+     "The ip-address-no-zone type represents an IP address and is 
+      IP version neutral.  The format of the textual representation
+      implies the IP version.  This type does not support scoped
+      addresses since it does not allow zone identifiers in the
+      address format.";
+    reference
+     "RFC 4007: IPv6 Scoped Address Architecture";
+  }
+
+  typedef ipv4-address-no-zone {
+    type ipv4-address {
+      pattern '[0-9\.]*';
+    }
+    description
+      "An IPv4 address without a zone index.  This type, derived
+       from the type ipv4-address, may be used in situations where
+       the zone is known from the context and no zone index is
+       needed.";
+  }
+
+  typedef ipv6-address-no-zone {
+    type ipv6-address {
+      pattern '[0-9a-fA-F:\.]*';
+    }
+    description
+      "An IPv6 address without a zone index.  This type, derived
+       from the type ipv6-address, may be used in situations where
+       the zone is known from the context and no zone index is
+       needed.";
+    reference
+     "RFC 4291: IP Version 6 Addressing Architecture
+      RFC 4007: IPv6 Scoped Address Architecture
+      RFC 5952: A Recommendation for IPv6 Address Text
+                Representation";
+  }
+
+  typedef ip-address-link-local {
+    type union {
+      type ipv4-address-link-local;
+      type ipv6-address-link-local;
+    }
+    description
+     "The ip-address-link-local type represents a link-local IP
+      address and is IP version neutral. The format of the textual
+      representation implies the IP version.";
+  }
+
+  typedef ipv4-address-link-local {
+    type ipv4-address {
+      pattern '169\.254\..*';
+    }
+    description
+      "A link-local IPv4 address in the prefix 169.254.0.0/16 as
+       defined in section 2.1. of RFC 3927.";
+    reference
+      "RFC 3927: Dynamic Configuration of IPv4 Link-Local Addresses";
+  }
+
+  typedef ipv6-address-link-local {
+    type ipv6-address {
+      pattern '[fF][eE]80:.*';
+    }
+    description
+      "A link-local IPv6 address in the prefix fe80::/10 as defined
+       in section 2.5.6. of RFC 4291.";
+    reference
+      "RFC 4291: IP Version 6 Addressing Architecture";
+  }
+
+  typedef ip-prefix {
+    type union {
+      type ipv4-prefix;
+      type ipv6-prefix;
+    }
+    description
+     "The ip-prefix type represents an IP prefix and is IP
+      version neutral.  The format of the textual representations
+      implies the IP version.";
+  }
+
+  typedef ipv4-prefix {
+    type string {
+      pattern
+         '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+       +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+       + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+    }
+    description
+     "The ipv4-prefix type represents an IPv4 prefix.
+      The prefix length is given by the number following the
+      slash character and must be less than or equal to 32. 
+
+      A prefix length value of n corresponds to an IP address
+      mask that has n contiguous 1-bits from the most
+      significant bit (MSB) and all other bits set to 0.
+
+      The canonical format of an IPv4 prefix has all bits of
+      the IPv4 address set to zero that are not part of the
+      IPv4 prefix.
+
+      The definition of ipv4-prefix does not require that bits,
+      which are not part of the prefix, are set to zero. However,
+      implementations have to return values in canonical format,
+      which requires non-prefix bits to be set to zero. This means
+      that 192.0.2.1/24 must be accepted as a valid value but it
+      will be converted into the canonical format 192.0.2.0/24.";
+  }
+
+  typedef ipv6-prefix {
+    type string {
+      pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+            + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+            + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+            + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+            + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+      pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+            + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+            + '(/.+)';
+    }
+    description
+     "The ipv6-prefix type represents an IPv6 prefix.
+      The prefix length is given by the number following the
+      slash character and must be less than or equal to 128. 
+
+      A prefix length value of n corresponds to an IP address
+      mask that has n contiguous 1-bits from the most
+      significant bit (MSB) and all other bits set to 0.
+
+      The canonical format of an IPv6 prefix has all bits of
+      the IPv6 address set to zero that are not part of the
+      IPv6 prefix.  Furthermore, the IPv6 address is represented
+      as defined in Section 4 of RFC 5952.
+
+      The definition of ipv6-prefix does not require that bits,
+      which are not part of the prefix, are set to zero. However,
+      implementations have to return values in canonical format,
+      which requires non-prefix bits to be set to zero. This means
+      that 2001:db8::1/64 must be accepted as a valid value but it
+      will be converted into the canonical format 2001:db8::/64.";
+    reference
+     "RFC 5952: A Recommendation for IPv6 Address Text
+                Representation";
+  }
+
+  typedef ip-address-and-prefix {
+    type union {
+      type ipv4-address-and-prefix;
+      type ipv6-address-and-prefix;
+    }
+    description
+     "The ip-address-and-prefix type represents an IP address and 
+      prefix and is IP version neutral.  The format of the textual
+      representations implies the IP version.";
+  }
+
+  typedef ipv4-address-and-prefix {
+    type string {
+      pattern
+         '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+       +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+       + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+    }
+    description
+     "The ipv4-address-and-prefix type represents an IPv4 
+      address and an associated IPv4 prefix.
+      The prefix length is given by the number following the
+      slash character and must be less than or equal to 32. 
+
+      A prefix length value of n corresponds to an IP address
+      mask that has n contiguous 1-bits from the most
+      significant bit (MSB) and all other bits set to 0.";
+  }
+
+  typedef ipv6-address-and-prefix {
+    type string {
+      pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+            + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+            + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+            + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+            + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+      pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+            + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+            + '(/.+)';
+    }
+    description
+     "The ipv6-address-and-prefix type represents an IPv6
+      address and an associated IPv6 prefix.
+      The prefix length is given by the number following the
+      slash character and must be less than or equal to 128. 
+
+      A prefix length value of n corresponds to an IP address
+      mask that has n contiguous 1-bits from the most
+      significant bit (MSB) and all other bits set to 0.
+
+      The canonical format requires that the IPv6 address is
+      represented as defined in Section 4 of RFC 5952.";
+    reference
+     "RFC 5952: A Recommendation for IPv6 Address Text
+                Representation";
+  }
+
+  /*** collection of domain name and URI types ***/
+
+  typedef domain-name {
+    type string {
+      length "1..253";
+      pattern 
+        '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+      + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+      + '|\.';
+    }
+    description
+     "The domain-name type represents a DNS domain name.  The 
+      name SHOULD be fully qualified whenever possible. This
+      type does not support wildcards (see RFC 4592) or
+      classless in-addr.arpa delegations (see RFC 2317).
+
+      Internet domain names are only loosely specified.  Section
+      3.5 of RFC 1034 recommends a syntax (modified in Section 
+      2.1 of RFC 1123).  The pattern above is intended to allow
+      for current practice in domain name use, and some possible
+      future expansion.  Note that Internet host names have a
+      stricter syntax (described in RFC 952) than the DNS 
+      recommendations in RFCs 1034 and 1123. Schema nodes
+      representing host names should use the host-name type
+      instead of the domain-type.
+
+      The encoding of DNS names in the DNS protocol is limited
+      to 255 characters.  Since the encoding consists of labels
+      prefixed by a length bytes and there is a trailing NULL
+      byte, only 253 characters can appear in the textual dotted
+      notation.
+
+      The description clause of schema nodes using the domain-name
+      type MUST describe when and how these names are resolved to
+      IP addresses.  Note that the resolution of a domain-name value
+      may require to query multiple DNS records (e.g., A for IPv4
+      and AAAA for IPv6).  The order of the resolution process and
+      which DNS record takes precedence can either be defined
+      explicitly or may depend on the configuration of the
+      resolver.
+
+      Domain-name values use the US-ASCII encoding.  Their canonical
+      format uses lowercase US-ASCII characters.  Internationalized
+      domain names MUST be A-labels as per RFC 5890.";
+    reference
+     "RFC  952: DoD Internet Host Table Specification
+      RFC 1034: Domain Names - Concepts and Facilities
+      RFC 1123: Requirements for Internet Hosts -- Application 
+                and Support
+      RFC 2317: Classless IN-ADDR.ARPA delegation
+      RFC 2782: A DNS RR for specifying the location of services
+                (DNS SRV)
+      RFC 4592: The Role of Wildcards in the Domain Name System
+      RFC 5890: Internationalized Domain Names in Applications
+                (IDNA): Definitions and Document Framework
+      RFC 9499: DNS Terminology";
+  }
+
+  typedef host-name {
+    type domain-name {
+      length "2..max";
+      pattern '[a-zA-Z0-9\-\.]+';
+    }
+    description
+     "The host-name type represents (fully qualified) host names.
+      Host names must be at least two characters long (see RFC 952)
+      and they are restricted to labels consisting of letters, digits
+      and hyphens separated by dots (see RFC1123 and RFC 952).";
+    reference
+     "RFC  952: DoD Internet Host Table Specification
+      RFC 1123: Requirements for Internet Hosts -- Application
+                and Support";
+  }
+
+  typedef host {
+    type union {
+      type ip-address;
+      type host-name;
+    }
+    description
+     "The host type represents either an IP address or a (fully
+      qualified) host name.";
+  }
+
+  typedef uri {
+    type string {
+      pattern '[a-z][a-z0-9+.-]*:.*';
+    }
+    description
+     "The uri type represents a Uniform Resource Identifier
+      (URI) as defined by the rule 'URI' in RFC 3986.
+
+      Objects using the uri type MUST be in US-ASCII encoding,
+      and MUST be normalized as described by RFC 3986 Sections
+      6.2.1, 6.2.2.1, and 6.2.2.2.  All unnecessary
+      percent-encoding is removed, and all case-insensitive
+      characters are set to lowercase except for hexadecimal
+      digits within a percent-encoded triplet, which are
+      normalized to uppercase as described in Section 6.2.2.1
+      of RFC 3986.
+
+      The purpose of this normalization is to help provide
+      unique URIs.  Note that this normalization is not
+      sufficient to provide uniqueness.  Two URIs that are
+      textually distinct after this normalization may still be
+      equivalent.
+
+      Objects using the uri type may restrict the schemes that
+      they permit.  For example, 'data:' and 'urn:' schemes
+      might not be appropriate.
+
+      A zero-length URI is not a valid URI.  This can be used to
+      express 'URI absent' where required.
+
+      In the value set and its semantics, this type is equivalent
+      to the Uri SMIv2 textual convention defined in RFC 5017.";
+    reference
+     "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
+      RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
+                Group: Uniform Resource Identifiers (URIs), URLs, 
+                and Uniform Resource Names (URNs): Clarifications
+                and Recommendations
+      RFC 5017: MIB Textual Conventions for Uniform Resource 
+                Identifiers (URIs)";
+  }
+
+  typedef email-address {
+    type string {
+      pattern '.+@.+';
+    }
+    description
+     "The email-address type represents an internationalized
+      email address.
+
+      The email address format is defined by the addr-spec
+      ABNF rule in RFC 5322 section 3.4.1. This format has
+      been extended by RFC 6532 to support internationalized
+      email addresses. Implementations MUST support the
+      internationalization extensions of RFC 6532. Support
+      of the obsolete obs-local-part, obs-domain, and
+      obs-qtext parts of RFC 5322 is not required.
+
+      The domain part may use both A-labels and U-labels
+      (see RFC 5890). The canonical format of the domain part
+      uses lowercase characters and U-labels (RFC 5890) where
+      applicable.";
+    reference
+     "RFC 5322: Internet Message Format
+      RFC 5890: Internationalized Domain Names in Applications
+                (IDNA): Definitions and Document Framework
+      RFC 6531: SMTP Extension for Internationalized Email";
+  }
+
+}
\ No newline at end of file
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-key-chain@2017-06-15.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-key-chain@2017-06-15.yang
new file mode 100644
index 0000000000000000000000000000000000000000..445d1994a5ac57366078b198200a9e143d4ccda8
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-key-chain@2017-06-15.yang
@@ -0,0 +1,382 @@
+module ietf-key-chain {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-key-chain";
+  prefix key-chain;
+
+  import ietf-yang-types {
+    prefix yang;
+  }
+  import ietf-netconf-acm {
+    prefix nacm;
+  }
+
+  organization
+    "IETF RTGWG - Routing Area Working Group";
+  contact
+    "WG Web:   <https://datatracker.ietf.org/group/rtgwg>
+     WG List:  <mailto:rtgwg@ietf.org>
+
+     Editor: Acee Lindem
+             <mailto:acee@cisco.com>
+             Yingzhen Qu
+             <mailto:yingzhen.qu@huawei.com>
+             Derek Yeung
+             <mailto:derek@arrcus.com>
+             Ing-Wher Chen
+             <mailto:Ing-Wher_Chen@jabail.com>
+             Jeffrey Zhang
+             <mailto:zzhang@juniper.net>";
+
+  description
+    "This YANG module defines the generic configuration
+     data for key chains.  It is intended that the module
+     will be extended by vendors to define vendor-specific
+     key chain configuration parameters.
+
+     Copyright (c) 2017 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 8177;
+     see the RFC itself for full legal notices.";
+
+  reference "RFC 8177";
+
+  revision 2017-06-15 {
+    description
+      "Initial RFC Revision";
+    reference "RFC 8177: YANG Data Model for Key Chains";
+  }
+
+  feature hex-key-string {
+    description
+      "Support hexadecimal key string.";
+  }
+
+  feature accept-tolerance {
+    description
+      "Support the tolerance or acceptance limit.";
+  }
+
+  feature independent-send-accept-lifetime {
+    description
+      "Support for independent send and accept key lifetimes.";
+  }
+
+  feature crypto-hmac-sha-1-12 {
+    description
+      "Support for TCP HMAC-SHA-1 12-byte digest hack.";
+  }
+
+  feature cleartext {
+    description
+      "Support for cleartext algorithm.  Usage is
+       NOT RECOMMENDED.";
+  }
+
+  feature aes-cmac-prf-128 {
+    description
+      "Support for AES Cipher-based Message Authentication
+       Code Pseudorandom Function.";
+  }
+
+  feature aes-key-wrap {
+    description
+      "Support for Advanced Encryption Standard (AES) Key Wrap.";
+  }
+
+  feature replay-protection-only {
+    description
+      "Provide replay protection without any authentication
+       as required by protocols such as Bidirectional
+       Forwarding Detection (BFD).";
+  }
+  identity crypto-algorithm {
+    description
+      "Base identity of cryptographic algorithm options.";
+  }
+
+  identity hmac-sha-1-12 {
+    base crypto-algorithm;
+    if-feature "crypto-hmac-sha-1-12";
+    description
+      "The HMAC-SHA1-12 algorithm.";
+  }
+
+  identity aes-cmac-prf-128 {
+    base crypto-algorithm;
+    if-feature "aes-cmac-prf-128";
+    description
+      "The AES-CMAC-PRF-128 algorithm - required by
+       RFC 5926 for TCP-AO key derivation functions.";
+  }
+
+  identity md5 {
+    base crypto-algorithm;
+    description
+      "The MD5 algorithm.";
+  }
+
+  identity sha-1 {
+    base crypto-algorithm;
+    description
+      "The SHA-1 algorithm.";
+  }
+
+  identity hmac-sha-1 {
+    base crypto-algorithm;
+    description
+      "HMAC-SHA-1 authentication algorithm.";
+  }
+
+  identity hmac-sha-256 {
+    base crypto-algorithm;
+    description
+      "HMAC-SHA-256 authentication algorithm.";
+  }
+
+  identity hmac-sha-384 {
+    base crypto-algorithm;
+    description
+      "HMAC-SHA-384 authentication algorithm.";
+  }
+
+  identity hmac-sha-512 {
+    base crypto-algorithm;
+    description
+      "HMAC-SHA-512 authentication algorithm.";
+  }
+
+  identity cleartext {
+    base crypto-algorithm;
+    if-feature "cleartext";
+    description
+      "cleartext.";
+  }
+
+  identity replay-protection-only {
+    base crypto-algorithm;
+    if-feature "replay-protection-only";
+    description
+      "Provide replay protection without any authentication as
+       required by protocols such as Bidirectional Forwarding
+       Detection (BFD).";
+  }
+
+  typedef key-chain-ref {
+    type leafref {
+      path
+      "/key-chain:key-chains/key-chain:key-chain/key-chain:name";
+    }
+    description
+      "This type is used by data models that need to reference
+       configured key chains.";
+  }
+
+  grouping lifetime {
+    description
+      "Key lifetime specification.";
+    choice lifetime {
+      default "always";
+      description
+        "Options for specifying key accept or send lifetimes";
+      case always {
+        leaf always {
+          type empty;
+          description
+            "Indicates key lifetime is always valid.";
+        }
+      }
+      case start-end-time {
+        leaf start-date-time {
+          type yang:date-and-time;
+          description
+            "Start time.";
+        }
+        choice end-time {
+          default "infinite";
+          description
+            "End-time setting.";
+          case infinite {
+            leaf no-end-time {
+              type empty;
+              description
+                "Indicates key lifetime end-time is infinite.";
+            }
+          }
+          case duration {
+            leaf duration {
+              type uint32 {
+                range "1..2147483646";
+              }
+              units "seconds";
+              description
+                "Key lifetime duration, in seconds";
+            }
+          }
+          case end-date-time {
+            leaf end-date-time {
+              type yang:date-and-time;
+              description
+                "End time.";
+            }
+          }
+        }
+      }
+    }
+  }
+
+  container key-chains {
+    description
+      "All configured key-chains on the device.";
+    list key-chain {
+      key "name";
+      description
+        "List of key-chains.";
+      leaf name {
+        type string;
+        description
+          "Name of the key-chain.";
+      }
+      leaf description {
+        type string;
+        description
+          "A description of the key-chain";
+      }
+      container accept-tolerance {
+        if-feature "accept-tolerance";
+        description
+          "Tolerance for key lifetime acceptance (seconds).";
+        leaf duration {
+          type uint32;
+          units "seconds";
+          default "0";
+          description
+            "Tolerance range, in seconds.";
+        }
+      }
+      leaf last-modified-timestamp {
+        type yang:date-and-time;
+        config false;
+        description
+          "Timestamp of the most recent update to the key-chain";
+      }
+      list key {
+        key "key-id";
+        description
+          "Single key in key chain.";
+        leaf key-id {
+          type uint64;
+          description
+            "Numeric value uniquely identifying the key";
+        }
+        container lifetime {
+          description
+            "Specify a key's lifetime.";
+          choice lifetime {
+            description
+              "Options for specification of send and accept
+               lifetimes.";
+            case send-and-accept-lifetime {
+              description
+                "Send and accept key have the same lifetime.";
+              container send-accept-lifetime {
+                description
+                  "Single lifetime specification for both
+                   send and accept lifetimes.";
+                uses lifetime;
+              }
+            }
+            case independent-send-accept-lifetime {
+              if-feature "independent-send-accept-lifetime";
+              description
+                "Independent send and accept key lifetimes.";
+              container send-lifetime {
+                description
+                  "Separate lifetime specification for send
+                   lifetime.";
+                uses lifetime;
+              }
+              container accept-lifetime {
+                description
+                  "Separate lifetime specification for accept
+                   lifetime.";
+                uses lifetime;
+              }
+            }
+          }
+        }
+        leaf crypto-algorithm {
+          type identityref {
+            base crypto-algorithm;
+          }
+          mandatory true;
+          description
+            "Cryptographic algorithm associated with key.";
+        }
+        container key-string {
+          description
+            "The key string.";
+          nacm:default-deny-all;
+          choice key-string-style {
+            description
+              "Key string styles";
+             case keystring {
+               leaf keystring {
+                type string;
+                description
+                  "Key string in ASCII format.";
+              }
+            }
+            case hexadecimal {
+              if-feature "hex-key-string";
+              leaf hexadecimal-string {
+                type yang:hex-string;
+                description
+                  "Key in hexadecimal string format.  When compared
+                   to ASCII, specification in hexadecimal affords
+                   greater key entropy with the same number of
+                   internal key-string octets.  Additionally, it
+                   discourages usage of well-known words or
+                   numbers.";
+              }
+            }
+          }
+        }
+        leaf send-lifetime-active {
+          type boolean;
+          config false;
+          description
+            "Indicates if the send lifetime of the
+             key-chain key is currently active.";
+           }
+        leaf accept-lifetime-active {
+          type boolean;
+          config false;
+          description
+            "Indicates if the accept lifetime of the
+             key-chain key is currently active.";
+        }
+      }
+    }
+    container aes-key-wrap {
+      if-feature "aes-key-wrap";
+      description
+        "AES Key Wrap encryption for key-chain key-strings.  The
+         encrypted key-strings are encoded as hexadecimal key
+         strings using the hex-key-string leaf.";
+      leaf enable {
+        type boolean;
+        default "false";
+        description
+          "Enable AES Key Wrap encryption.";
+      }
+    }
+  }
+}
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-netconf-acm@2018-02-14.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-netconf-acm@2018-02-14.yang
new file mode 100644
index 0000000000000000000000000000000000000000..bf4855faf0508a152471f6c6c8f756581b8ebb96
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-netconf-acm@2018-02-14.yang
@@ -0,0 +1,464 @@
+module ietf-netconf-acm {
+
+  namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-acm";
+
+  prefix nacm;
+
+  import ietf-yang-types {
+    prefix yang;
+  }
+
+  organization
+    "IETF NETCONF (Network Configuration) Working Group";
+
+  contact
+    "WG Web:   <https://datatracker.ietf.org/wg/netconf/>
+     WG List:  <mailto:netconf@ietf.org>
+
+     Author:   Andy Bierman
+               <mailto:andy@yumaworks.com>
+
+     Author:   Martin Bjorklund
+               <mailto:mbj@tail-f.com>";
+
+  description
+    "Network Configuration Access Control Model.
+
+     Copyright (c) 2012 - 2018 IETF Trust and the persons
+     identified as authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD
+     License set forth in Section 4.c of the IETF Trust's
+     Legal Provisions Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 8341; see
+     the RFC itself for full legal notices.";
+
+  revision "2018-02-14" {
+    description
+      "Added support for YANG 1.1 actions and notifications tied to
+       data nodes.  Clarified how NACM extensions can be used by
+       other data models.";
+    reference
+      "RFC 8341: Network Configuration Access Control Model";
+  }
+
+  revision "2012-02-22" {
+    description
+      "Initial version.";
+    reference
+      "RFC 6536: Network Configuration Protocol (NETCONF)
+                 Access Control Model";
+  }
+
+  /*
+   * Extension statements
+   */
+
+  extension default-deny-write {
+    description
+      "Used to indicate that the data model node
+       represents a sensitive security system parameter.
+
+       If present, the NETCONF server will only allow the designated
+       'recovery session' to have write access to the node.  An
+       explicit access control rule is required for all other users.
+
+       If the NACM module is used, then it must be enabled (i.e.,
+       /nacm/enable-nacm object equals 'true'), or this extension
+       is ignored.
+
+       The 'default-deny-write' extension MAY appear within a data
+       definition statement.  It is ignored otherwise.";
+  }
+
+  extension default-deny-all {
+    description
+      "Used to indicate that the data model node
+       controls a very sensitive security system parameter.
+
+       If present, the NETCONF server will only allow the designated
+       'recovery session' to have read, write, or execute access to
+       the node.  An explicit access control rule is required for all
+       other users.
+
+       If the NACM module is used, then it must be enabled (i.e.,
+       /nacm/enable-nacm object equals 'true'), or this extension
+       is ignored.
+
+       The 'default-deny-all' extension MAY appear within a data
+       definition statement, 'rpc' statement, or 'notification'
+       statement.  It is ignored otherwise.";
+  }
+
+  /*
+   * Derived types
+   */
+
+  typedef user-name-type {
+    type string {
+      length "1..max";
+    }
+    description
+      "General-purpose username string.";
+  }
+
+  typedef matchall-string-type {
+    type string {
+      pattern '\*';
+    }
+    description
+      "The string containing a single asterisk '*' is used
+       to conceptually represent all possible values
+       for the particular leaf using this data type.";
+  }
+
+  typedef access-operations-type {
+    type bits {
+      bit create {
+        description
+          "Any protocol operation that creates a
+           new data node.";
+      }
+      bit read {
+        description
+          "Any protocol operation or notification that
+           returns the value of a data node.";
+      }
+      bit update {
+        description
+          "Any protocol operation that alters an existing
+           data node.";
+      }
+      bit delete {
+        description
+          "Any protocol operation that removes a data node.";
+      }
+      bit exec {
+        description
+          "Execution access to the specified protocol operation.";
+      }
+    }
+    description
+      "Access operation.";
+  }
+
+  typedef group-name-type {
+    type string {
+      length "1..max";
+      pattern '[^\*].*';
+    }
+    description
+      "Name of administrative group to which
+       users can be assigned.";
+  }
+
+  typedef action-type {
+    type enumeration {
+      enum permit {
+        description
+          "Requested action is permitted.";
+      }
+      enum deny {
+        description
+          "Requested action is denied.";
+      }
+    }
+    description
+      "Action taken by the server when a particular
+       rule matches.";
+  }
+
+  typedef node-instance-identifier {
+    type yang:xpath1.0;
+    description
+      "Path expression used to represent a special
+       data node, action, or notification instance-identifier
+       string.
+
+       A node-instance-identifier value is an
+       unrestricted YANG instance-identifier expression.
+       All the same rules as an instance-identifier apply,
+       except that predicates for keys are optional.  If a key
+       predicate is missing, then the node-instance-identifier
+       represents all possible server instances for that key.
+
+       This XML Path Language (XPath) expression is evaluated in the
+       following context:
+
+          o  The set of namespace declarations are those in scope on
+             the leaf element where this type is used.
+
+          o  The set of variable bindings contains one variable,
+             'USER', which contains the name of the user of the
+             current session.
+
+          o  The function library is the core function library, but
+             note that due to the syntax restrictions of an
+             instance-identifier, no functions are allowed.
+
+          o  The context node is the root node in the data tree.
+
+       The accessible tree includes actions and notifications tied
+       to data nodes.";
+  }
+
+  /*
+   * Data definition statements
+   */
+
+  container nacm {
+    nacm:default-deny-all;
+
+    description
+      "Parameters for NETCONF access control model.";
+
+    leaf enable-nacm {
+      type boolean;
+      default "true";
+      description
+        "Enables or disables all NETCONF access control
+         enforcement.  If 'true', then enforcement
+         is enabled.  If 'false', then enforcement
+         is disabled.";
+    }
+
+    leaf read-default {
+      type action-type;
+      default "permit";
+      description
+        "Controls whether read access is granted if
+         no appropriate rule is found for a
+         particular read request.";
+    }
+
+    leaf write-default {
+      type action-type;
+      default "deny";
+      description
+        "Controls whether create, update, or delete access
+         is granted if no appropriate rule is found for a
+         particular write request.";
+    }
+
+    leaf exec-default {
+      type action-type;
+      default "permit";
+      description
+        "Controls whether exec access is granted if no appropriate
+         rule is found for a particular protocol operation request.";
+    }
+
+    leaf enable-external-groups {
+      type boolean;
+      default "true";
+      description
+        "Controls whether the server uses the groups reported by the
+         NETCONF transport layer when it assigns the user to a set of
+         NACM groups.  If this leaf has the value 'false', any group
+         names reported by the transport layer are ignored by the
+         server.";
+    }
+
+    leaf denied-operations {
+      type yang:zero-based-counter32;
+      config false;
+      mandatory true;
+      description
+        "Number of times since the server last restarted that a
+         protocol operation request was denied.";
+    }
+
+    leaf denied-data-writes {
+      type yang:zero-based-counter32;
+      config false;
+      mandatory true;
+      description
+        "Number of times since the server last restarted that a
+         protocol operation request to alter
+         a configuration datastore was denied.";
+    }
+
+    leaf denied-notifications {
+      type yang:zero-based-counter32;
+      config false;
+      mandatory true;
+      description
+        "Number of times since the server last restarted that
+         a notification was dropped for a subscription because
+         access to the event type was denied.";
+    }
+
+    container groups {
+      description
+        "NETCONF access control groups.";
+
+      list group {
+        key name;
+
+        description
+          "One NACM group entry.  This list will only contain
+           configured entries, not any entries learned from
+           any transport protocols.";
+
+        leaf name {
+          type group-name-type;
+          description
+            "Group name associated with this entry.";
+        }
+
+        leaf-list user-name {
+          type user-name-type;
+          description
+            "Each entry identifies the username of
+             a member of the group associated with
+             this entry.";
+        }
+      }
+    }
+
+    list rule-list {
+      key name;
+      ordered-by user;
+      description
+        "An ordered collection of access control rules.";
+
+      leaf name {
+        type string {
+          length "1..max";
+        }
+        description
+          "Arbitrary name assigned to the rule-list.";
+      }
+      leaf-list group {
+        type union {
+          type matchall-string-type;
+          type group-name-type;
+        }
+        description
+          "List of administrative groups that will be
+           assigned the associated access rights
+           defined by the 'rule' list.
+
+           The string '*' indicates that all groups apply to the
+           entry.";
+      }
+
+      list rule {
+        key name;
+        ordered-by user;
+        description
+          "One access control rule.
+
+           Rules are processed in user-defined order until a match is
+           found.  A rule matches if 'module-name', 'rule-type', and
+           'access-operations' match the request.  If a rule
+           matches, the 'action' leaf determines whether or not
+           access is granted.";
+
+        leaf name {
+          type string {
+            length "1..max";
+          }
+          description
+            "Arbitrary name assigned to the rule.";
+        }
+
+        leaf module-name {
+          type union {
+            type matchall-string-type;
+            type string;
+          }
+          default "*";
+          description
+            "Name of the module associated with this rule.
+
+             This leaf matches if it has the value '*' or if the
+             object being accessed is defined in the module with the
+             specified module name.";
+        }
+        choice rule-type {
+          description
+            "This choice matches if all leafs present in the rule
+             match the request.  If no leafs are present, the
+             choice matches all requests.";
+          case protocol-operation {
+            leaf rpc-name {
+              type union {
+                type matchall-string-type;
+                type string;
+              }
+              description
+                "This leaf matches if it has the value '*' or if
+                 its value equals the requested protocol operation
+                 name.";
+            }
+          }
+          case notification {
+            leaf notification-name {
+              type union {
+                type matchall-string-type;
+                type string;
+              }
+              description
+                "This leaf matches if it has the value '*' or if its
+                 value equals the requested notification name.";
+            }
+          }
+
+          case data-node {
+            leaf path {
+              type node-instance-identifier;
+              mandatory true;
+              description
+                "Data node instance-identifier associated with the
+                 data node, action, or notification controlled by
+                 this rule.
+
+                 Configuration data or state data
+                 instance-identifiers start with a top-level
+                 data node.  A complete instance-identifier is
+                 required for this type of path value.
+
+                 The special value '/' refers to all possible
+                 datastore contents.";
+            }
+          }
+        }
+
+        leaf access-operations {
+          type union {
+            type matchall-string-type;
+            type access-operations-type;
+          }
+          default "*";
+          description
+            "Access operations associated with this rule.
+
+             This leaf matches if it has the value '*' or if the
+             bit corresponding to the requested operation is set.";
+        }
+
+        leaf action {
+          type action-type;
+          mandatory true;
+          description
+            "The access control action associated with the
+             rule.  If a rule has been determined to match a
+             particular request, then this object is used
+             to determine whether to permit or deny the
+             request.";
+        }
+
+        leaf comment {
+          type string;
+          description
+            "A textual description of the access rule.";
+        }
+      }
+    }
+  }
+}
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/ietf-network-slice-service.txt b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-network-slice-service.txt
similarity index 100%
rename from src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/ietf-network-slice-service.txt
rename to src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-network-slice-service.txt
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-network-slice-service@2024-08-28.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-network-slice-service@2024-08-28.yang
new file mode 100644
index 0000000000000000000000000000000000000000..d72dd1ed38c6b098c70ab824f98e8029aef7d137
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-network-slice-service@2024-08-28.yang
@@ -0,0 +1,1375 @@
+module ietf-network-slice-service {
+  yang-version 1.1;
+  namespace
+    "urn:ietf:params:xml:ns:yang:ietf-network-slice-service";
+  prefix ietf-nss;
+
+  import ietf-inet-types {
+    prefix inet;
+    reference
+      "RFC 6991: Common YANG Types";
+  }
+  import ietf-yang-types {
+    prefix yang;
+    reference
+      "RFC 6991: Common YANG Data Types";
+  }
+  import ietf-geo-location {
+    prefix geo;
+    reference
+      "RFC 9179: A YANG Grouping for Geographic Locations";
+  }
+  import ietf-vpn-common {
+    prefix vpn-common;
+    reference
+      "RFC 9181: A Common YANG Data Model for Layer 2 and Layer 3
+                 VPNs";
+  }
+  import ietf-network {
+    prefix nw;
+    reference
+      "RFC 8345: A YANG Data Model for Network Topologies";
+  }
+  import ietf-network-topology {
+    prefix nt;
+    reference
+      "RFC 8345: A YANG Data Model for Network
+                 Topologies, Section 6.2";
+  }
+  import ietf-ac-common {
+    prefix ac-common;
+    reference
+      "RFC BBBB: A Common YANG Data Model for Attachment Circuits";
+  }
+  import ietf-ac-svc {
+    prefix ac-svc;
+    reference
+      "RFC CCCC: YANG Data Models for Bearers and 'Attachment
+                 Circuits'-as-a-Service (ACaaS)";
+  }
+  import ietf-te-types {
+    prefix te-types;
+    reference
+      "RFC DDDD: Common YANG Types for Traffic Engineering";
+  }
+  import ietf-te-packet-types {
+    prefix te-packet-types;
+    reference
+      "RFC DDDD: Common YANG Data Types for Traffic Engineering";
+  }
+
+  organization
+    "IETF Traffic Engineering Architecture and Signaling (TEAS)
+     Working Group";
+  contact
+    "WG Web:  <https://datatracker.ietf.org/wg/teas/>
+     WG List:  <mailto:teas@ietf.org>
+
+     Editor: Bo Wu
+             <lana.wubo@huawei.com>
+     Editor: Dhruv Dhody
+             <dhruv.ietf@gmail.com>
+     Editor: Reza Rokui
+             <rrokui@ciena.com>
+     Editor: Tarek Saad
+             <tsaad@cisco.com>
+     Editor: John Mullooly
+             <jmullool@cisco.com>";
+  description
+    "This YANG module defines a service model for the RFC 9543
+     Network Slice Service.
+
+     Copyright (c) 2024 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject to
+     the license terms contained in, the Revised BSD License set
+     forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC AAAA; see the
+     RFC itself for full legal notices.";
+
+  revision 2024-08-28 {
+    description
+      "Initial revision.";
+    reference
+      "RFC AAAA: A YANG Data Model for the RFC 9543 Network Slice
+       Service";
+  }
+
+  /* Identities */
+
+  identity service-tag-type {
+    description
+      "Base identity of Network Slice Service tag type, which is
+       used for management purposes, such as classification
+       (e.g., customer names) and policy constraints
+       (e.g., Layer 2 or Layer 3 technology realization).";
+  }
+
+  identity customer {
+    base service-tag-type;
+    description
+      "The Network Slice Service customer name tag type,
+       e.g., adding tags with 'customer name' when multiple actual
+       customers use the same Network Slice Service.";
+  }
+
+  identity service {
+    base service-tag-type;
+    description
+      "The Network Slice Service tag type, which can indicate the
+       technical constraints used during service realization,
+       for example, Layer 2 or Layer 3 technologies.";
+  }
+
+  identity opaque {
+    base service-tag-type;
+    description
+      "An opaque type, which can be used for future use,
+       such as filtering of services.";
+  }
+
+  identity attachment-circuit-tag-type {
+    description
+      "Base identity for the attachment circuit tag type.";
+  }
+
+  identity vlan-id {
+    base attachment-circuit-tag-type;
+    description
+      "Identity for VLAN ID tag type, 802.1Q dot1Q.";
+    reference
+      "IEEE Std 802.1Q: IEEE Standard for Local and Metropolitan
+                        Area Networks--Bridges and Bridged
+                        Networks";
+  }
+
+  identity cvlan-id {
+    base attachment-circuit-tag-type;
+    description
+      "Identity for C-VLAN ID tag type, 802.1ad QinQ VLAN IDs.";
+    reference
+      "IEEE Std 802.1ad: IEEE Standard for Local and Metropolitan
+                         Area Networks---Virtual Bridged Local
+                         Area Networks---Amendment 4: Provider
+                         Bridges";
+  }
+
+  identity svlan-id {
+    base attachment-circuit-tag-type;
+    description
+      "Identity for S-VLAN ID tag type, 802.1ad QinQ VLAN IDs.";
+    reference
+      "IEEE Std 802.1ad: IEEE Standard for Local and Metropolitan
+                         Area Networks---Virtual Bridged Local
+                         Area Networks---Amendment 4: Provider
+                         Bridges";
+  }
+
+  identity ip-address-mask {
+    base attachment-circuit-tag-type;
+    description
+      "Identity for IP address mask tag type.";
+  }
+
+  identity service-isolation-type {
+    description
+      "Base identity for Network Slice Service isolation type.";
+  }
+
+  identity traffic-isolation {
+    base service-isolation-type;
+    description
+      "Specify the requirement for separating the traffic of the
+       customer's Network Slice Service from other services,
+       which may be provided by the service provider using VPN
+       technologies, such as L3VPN, L2VPN, EVPN, etc.";
+  }
+
+  identity service-security-type {
+    description
+      "Base identity for Network Slice Service security type.";
+  }
+
+  identity authentication {
+    base service-security-type;
+    description
+      "Indicates that the Slice Service requires authentication.";
+  }
+
+  identity integrity {
+    base service-security-type;
+    description
+      "Indicates that the Slice Service requires data integrity.";
+  }
+
+  identity encryption {
+    base service-security-type;
+    description
+      "Indicates that the Slice Service requires data encryption.";
+  }
+
+  identity point-to-point {
+    base vpn-common:vpn-topology;
+    description
+      "Identity for point-to-point Network Slice
+       Service connectivity.";
+  }
+
+  identity point-to-multipoint {
+    base vpn-common:vpn-topology;
+    description
+      "Identity for point-to-multipoint Network Slice
+       Service connectivity.";
+  }
+
+  identity multipoint-to-multipoint {
+    base vpn-common:vpn-topology;
+    description
+      "Identity for multipoint-to-multipoint Network Slice
+       Service connectivity.";
+  }
+
+  identity multipoint-to-point {
+    base vpn-common:vpn-topology;
+    description
+      "Identity for multipoint-to-point Network Slice
+       Service connectivity.";
+  }
+
+  identity sender-role {
+    base vpn-common:role;
+    description
+      "Indicates that an SDP is acting as a sender.";
+  }
+
+  identity receiver-role {
+    base vpn-common:role;
+    description
+      "Indicates that an SDP is acting as a receiver.";
+  }
+
+  identity service-slo-metric-type {
+    description
+      "Base identity for Network Slice Service SLO metric type.";
+  }
+
+  identity one-way-bandwidth {
+    base service-slo-metric-type;
+    description
+      "SLO bandwidth metric. Minimum guaranteed bandwidth between
+       two SDPs at any time and is measured unidirectionally.";
+  }
+
+  identity two-way-bandwidth {
+    base service-slo-metric-type;
+    description
+      "SLO bandwidth metric. Minimum guaranteed bandwidth between
+       two SDPs at any time.";
+  }
+
+  identity shared-bandwidth {
+    base service-slo-metric-type;
+    description
+      "The shared SLO bandwidth bound. It is the limit on the
+       bandwidth that can be shared amongst a group of
+       connectivity constructs of a Slice Service.";
+  }
+
+  identity one-way-delay-maximum {
+    base service-slo-metric-type;
+    description
+      "The SLO objective of this metric is the upper bound of network
+       delay when transmitting between two SDPs.";
+    reference
+      "RFC 7679: A One-Way Delay Metric for IP Performance
+                 Metrics (IPPM)";
+  }
+
+  identity one-way-delay-percentile {
+    base service-slo-metric-type;
+    description
+      "The SLO objective of this metric is percentile objective of
+       network delay when transmitting between two SDPs.
+       The metric is defined in RFC7679.";
+    reference
+      "RFC 7679: A One-Way Delay Metric for IP Performance
+                 Metrics (IPPM)";
+  }
+
+  identity two-way-delay-maximum {
+    base service-slo-metric-type;
+    description
+      "SLO two-way delay is the upper bound of network delay when
+       transmitting between two SDPs";
+    reference
+      "RFC 2681: A Round-trip Delay Metric for IPPM";
+  }
+
+  identity two-way-delay-percentile {
+    base service-slo-metric-type;
+    description
+      "The SLO objective of this metric is the percentile
+       objective of network delay when the traffic transmitting
+       between two SDPs.";
+    reference
+      "RFC 2681: A Round-trip Delay Metric for IPPM";
+  }
+
+  identity one-way-delay-variation-maximum {
+    base service-slo-metric-type;
+    description
+      "The SLO objective of this metric is maximum bound of the
+       difference in the one-way delay between sequential packets
+       between two SDPs.";
+    reference
+      "RFC 3393: IP Packet Delay Variation Metric for IP Performance
+                 Metrics (IPPM)";
+  }
+
+  identity one-way-delay-variation-percentile {
+    base service-slo-metric-type;
+    description
+      "The SLO objective of this metric is the percentile objective
+       in the one-way delay between sequential packets between two
+       SDPs.";
+    reference
+      "RFC 3393: IP Packet Delay Variation Metric for IP Performance
+                 Metrics (IPPM)";
+  }
+
+  identity two-way-delay-variation-maximum {
+    base service-slo-metric-type;
+    description
+      "SLO two-way delay variation is the difference in the
+       round-trip delay between sequential packets between two
+       SDPs.";
+    reference
+      "RFC 5481: Packet Delay Variation Applicability Statement";
+  }
+
+  identity two-way-delay-variation-percentile {
+    base service-slo-metric-type;
+    description
+      "The SLO objective of this metric is the percentile objective
+       in the round-trip delay between sequential packets between
+       two SDPs.";
+    reference
+      "RFC 5481: Packet Delay Variation Applicability Statement";
+  }
+
+  identity one-way-packet-loss {
+    base service-slo-metric-type;
+    description
+      "This metric type refers to the ratio of packets dropped
+       to packets transmitted between two SDPs in one-way.";
+    reference
+      "RFC 7680: A One-Way Loss Metric for IP Performance
+                 Metrics (IPPM)";
+  }
+
+  identity two-way-packet-loss {
+    base service-slo-metric-type;
+    description
+      "This metric type refers to the ratio of packets dropped
+       to packets transmitted between two SDPs in two-way.";
+    reference
+      "RFC 7680: A One-Way Loss Metric for IP Performance
+                 Metrics (IPPM)";
+  }
+
+  identity availability-type {
+    description
+      "Base identity for availability.";
+  }
+
+  identity six-nines {
+    base availability-type;
+    description
+      "Specifies the availability level: 99.9999%";
+  }
+
+  identity five-nines {
+    base availability-type;
+    description
+      "Specifies the availability level: 99.999%";
+  }
+
+  identity four-nines {
+    base availability-type;
+    description
+      "Specifies the availability level: 99.99%";
+  }
+
+  identity three-nines {
+    base availability-type;
+    description
+      "Specifies the availability level: 99.9%";
+  }
+
+  identity two-nines {
+    base availability-type;
+    description
+      "Specifies the availability level: 99%";
+  }
+
+  identity service-match-type {
+    description
+      "Base identity for Network Slice Service traffic
+       match type.";
+  }
+  identity phy-interface {
+    base service-match-type;
+    description
+      "Uses the physical interface as match criteria for
+       Slice Service traffic.";
+  }
+
+  identity vlan {
+    base service-match-type;
+    description
+      "Uses the VLAN ID as match criteria for the Slice Service
+       traffic.";
+  }
+
+  identity label {
+    base service-match-type;
+    description
+      "Uses the MPLS label as match criteria for the Slice Service
+       traffic.";
+  }
+
+  identity source-ip-prefix {
+    base service-match-type;
+    description
+      "Uses source IP prefix as match criteria for the Slice Service
+       traffic. Examples of 'value' of this match type are
+       '192.0.2.0/24' and '2001:db8::1/64'.";
+  }
+
+  identity destination-ip-prefix {
+    base service-match-type;
+    description
+      "Uses destination IP prefix as match criteria for the Slice
+       Service traffic. Examples of 'value' of this match type are
+       '203.0.113.1/32' and '2001:db8::2/128'.";
+  }
+
+  identity dscp {
+    base service-match-type;
+    description
+      "Uses DSCP field in the IP packet header as match criteria
+       for the Slice Service traffic.";
+  }
+
+  identity acl {
+    base service-match-type;
+    description
+      "Uses Access Control List (ACL) as match criteria
+       for the Slice Service traffic.";
+    reference
+      "RFC 8519: YANG Data Model for Network Access Control
+                 Lists (ACLs)";
+  }
+
+  identity any {
+    base service-match-type;
+    description
+      "Matches any Slice Service traffic.";
+  }
+
+  identity source-tcp-port {
+    base service-match-type;
+    description
+      "Uses source TCP port as match criteria for the Slice Service
+      traffic. Examples of 'value' of this match type are
+      '8080' and '22'.";
+  }
+  
+  identity destination-tcp-port {
+    base service-match-type;
+    description
+      "Uses destination TCP port as match criteria for the Slice
+      Service traffic. Examples of 'value' of this match type are
+      '8080' and '22'.";
+  }
+  
+  identity source-udp-port {
+    base service-match-type;
+    description
+      "Uses source UDP port as match criteria for the Slice Service
+      traffic. Examples of 'value' of this match type are
+      '53', '67' and '68'.";
+  }
+ 
+identity destination-udp-port {
+  base service-match-type;
+  description
+    "Uses destination UDP port as match criteria for the Slice
+    Service traffic. Examples of 'value' of this match type are
+    '53', '67' and '68'.";
+}
+
+  identity slo-sle-policy-override {
+    description
+      "Base identity for SLO/SLE policy override options.";
+  }
+
+  identity full-override {
+    base slo-sle-policy-override;
+    description
+      "The SLO/SLE policy defined at the child level overrides a
+       parent SLO/SLE policy, which means that no SLO/SLEs are
+       inherited from parent if a child SLO/SLE policy exists.";
+  }
+
+  identity partial-override {
+    base slo-sle-policy-override;
+    description
+      "The SLO/SLE policy defined at the child level updates the
+       parent SLO/SLE policy. For example, if a specific SLO is
+       defined at the child level, that specific SLO overrides
+       the one inherited from a parent SLO/SLE policy, while all
+       other SLOs in the parent SLO-SLE policy still apply.";
+  }
+
+  /* Typedef */
+
+  typedef percentage {
+    type decimal64 {
+      fraction-digits 5;
+      range "0..100";
+    }
+    description
+      "Percentage to 5 decimal places.";
+  }
+
+  typedef percentile {
+    type decimal64 {
+      fraction-digits 3;
+      range "0..100";
+    }
+    description
+      "The percentile is a value between 0 and 100
+       to 3 decimal places, e.g., 10.000, 99.900,99.990, etc.
+       For example, for a given one-way delay measurement,
+       if the percentile is set to 95.000 and the 95th percentile
+       one-way delay is 2 milliseconds, then the 95 percent of
+       the sample value is less than or equal to 2 milliseconds.";
+  }
+
+  typedef slice-template-ref {
+    type leafref {
+      path "/ietf-nss:network-slice-services"
+         + "/ietf-nss:slo-sle-templates"
+         + "/ietf-nss:slo-sle-template"
+         + "/ietf-nss:id";
+    }
+    description
+      "This type is used by data models that need to reference
+       Network Slice templates.";
+  }
+
+  typedef slice-service-ref {
+    type leafref {
+      path
+        "/ietf-nss:network-slice-services/ietf-nss:slice-service"
+      + "/ietf-nss:id";
+    }
+    description
+      "Defines a reference to a slice service that can be used
+       by other modules.";
+  }
+
+  /* Groupings */
+
+  grouping service-slos {
+    description
+      "A reusable grouping for directly measurable objectives of
+       a Slice Service.";
+    container slo-policy {
+      description
+        "Contains the SLO policy.";
+      list metric-bound {
+        key "metric-type";
+        description
+          "List of Slice Service metric bounds.";
+        leaf metric-type {
+          type identityref {
+            base service-slo-metric-type;
+          }
+          description
+            "Identifies SLO metric type of the Slice Service.";
+        }
+        leaf metric-unit {
+          type string;
+          mandatory true;
+          description
+            "The metric unit of the parameter. For example,
+             for time units, where the options are hours, minutes,
+             seconds, milliseconds, microseconds, and nanoseconds;
+             for bandwidth units, where the options are bps, Kbps,
+             Mbps, Gbps; for the packet loss rate unit,
+             the options can be a percentage.";
+        }
+        leaf value-description {
+          type string;
+          description
+            "The description of the provided value.";
+        }
+        leaf percentile-value {
+          type percentile;
+          description
+            "The percentile value of the metric type.";
+        }
+        leaf bound {
+          type uint64;
+          description
+            "The bound on the Slice Service connection metric.
+             When set to zero, this indicates an unbounded
+             upper limit for the specific metric-type.";
+        }
+      }
+      leaf availability {
+        type identityref {
+          base availability-type;
+        }
+        description
+          "Service availability level";
+      }
+      leaf mtu {
+        type uint32;
+        units "bytes";
+        description
+          "Specifies the maximum length of Layer 2 data
+           packets of the Slice Service.
+           If the customer sends packets that are longer than the
+           requested service MTU, the network may discard them
+           (or for IPv4, fragment them).
+           This service MTU takes precedence over the MTUs of
+           all attachment circuits (ACs). The value needs to be
+           less than or equal to the minimum MTU value of
+           all ACs in the SDPs.";
+      }
+    }
+  }
+
+  grouping service-sles {
+    description
+      "A reusable grouping for indirectly measurable objectives of
+       a Slice Service.";
+    container sle-policy {
+      description
+        "Contains the SLE policy.";
+      leaf-list security {
+        type identityref {
+          base service-security-type;
+        }
+        description
+          "The security functions that the customer requests
+           the operator to apply to traffic between the two SDPs.";
+      }
+      leaf-list isolation {
+        type identityref {
+          base service-isolation-type;
+        }
+        description
+          "The Slice Service isolation requirement.";
+      }
+      leaf max-occupancy-level {
+        type uint8 {
+          range "1..100";
+        }
+        description
+          "The maximal occupancy level specifies the number of flows
+           to be admitted and optionally a maximum number of
+           countable resource units (e.g., IP or MAC addresses)
+           a Network Slice Service can consume.";
+      }
+      container path-constraints {
+        description
+          "Container for the policy of path constraints
+           applicable to the Slice Service.";
+        container service-functions {
+          description
+            "Container for the policy of service function
+             applicable to the Slice Service.";
+        }
+        container diversity {
+          description
+            "Container for the policy of disjointness
+             applicable to the Slice Service.";
+          leaf diversity-type {
+            type te-types:te-path-disjointness;
+            description
+              "The type of disjointness on Slice Service, i.e.,
+               across all connectivity constructs.";
+          }
+        }
+      }
+    }
+  }
+
+  grouping slice-service-template {
+    description
+      "A reusable grouping for Slice Service templates.";
+    container slo-sle-templates {
+      description
+        "Contains a set of Slice Service templates.";
+      list slo-sle-template {
+        key "id";
+        description
+          "List for SLO and SLE template identifiers.";
+        leaf id {
+          type string;
+          description
+            "Identification of the Service Level Objective (SLO)
+             and Service Level Expectation (SLE) template to be used.
+             Local administration meaning.";
+        }
+        leaf description {
+          type string;
+          description
+            "Describes the SLO and SLE policy template.";
+        }
+        leaf template-ref {
+          type slice-template-ref;
+          description
+            "The reference to a standard template. When set it
+              indicates the base template over which further
+              SLO/SLE policy changes are made.";
+        }
+        uses service-slos;
+        uses service-sles;
+      }
+    }
+  }
+
+  grouping service-slo-sle-policy {
+    description
+      "Slice service policy grouping.";
+    choice slo-sle-policy {
+      description
+        "Choice for SLO and SLE policy template.
+         Can be standard template or customized template.";
+      case standard {
+        description
+          "Standard SLO template.";
+        leaf slo-sle-template {
+          type slice-template-ref;
+          description
+            "Standard SLO and SLE template to be used.";
+        }
+      }
+      case custom {
+        description
+          "Customized SLO and SLE template.";
+        container service-slo-sle-policy {
+          description
+            "Contains the SLO and SLE policy.";
+          leaf description {
+            type string;
+            description
+              "Describes the SLO and SLE policy.";
+          }
+          uses service-slos;
+          uses service-sles;
+        }
+      }
+    }
+  }
+
+  grouping service-qos {
+    description
+      "Grouping for the Slice Service QoS policy.";
+    container incoming-qos-policy {
+      description
+        "The QoS policy imposed on ingress direction of the traffic,
+         from the customer network or from another provider's
+         network.";
+      leaf qos-policy-name {
+        type string;
+        description
+          "The name of the QoS policy that is applied to the
+           attachment circuit. The name can reference a QoS
+           profile that is pre-provisioned on the device.";
+      }
+      container rate-limits {
+        description
+          "Container for the asymmetric traffic control.";
+        uses ac-common:bandwidth-parameters;
+        container classes {
+          description
+            "Container for service class bandwidth control.";
+          list cos {
+            key "cos-id";
+            description
+              "List of Class of Services.";
+            leaf cos-id {
+              type uint8;
+              description
+                "Identifier of the CoS, indicated by
+                 a Differentiated Services Code Point
+                 (DSCP) or a CE-CLAN CoS (802.1p)
+                 value in the service frame.";
+              reference
+                "IEEE Std 802.1Q: Bridges and Bridged
+                                  Networks";
+            }
+            uses ac-common:bandwidth-parameters;
+          }
+        }
+      }
+    }
+    container outgoing-qos-policy {
+      description
+        "The QoS policy imposed on egress direction of the traffic,
+         towards the customer network or towards another
+         provider's network.";
+      leaf qos-policy-name {
+        type string;
+        description
+          "The name of the QoS policy that is applied to the
+           attachment circuit. The name can reference a QoS
+           profile that is pre-provisioned on the device.";
+      }
+      container rate-limits {
+        description
+          "The rate-limit imposed on outgoing traffic.";
+        uses ac-common:bandwidth-parameters;
+        container classes {
+          description
+            "Container for classes.";
+          list cos {
+            key "cos-id";
+            description
+              "List of Class of Services.";
+            leaf cos-id {
+              type uint8;
+              description
+                "Identifier of the CoS, indicated by
+                 a Differentiated Services Code Point
+                 (DSCP) or a CE-CLAN CoS (802.1p)
+                 value in the service frame.";
+              reference
+                "IEEE Std 802.1Q: Bridges and Bridged
+                                  Networks";
+            }
+            uses ac-common:bandwidth-parameters;
+          }
+        }
+      }
+    }
+  }
+
+  grouping service-slo-sle-policy-override {
+    description
+      "Slice Service policy override grouping.";
+    leaf service-slo-sle-policy-override {
+      type identityref {
+        base slo-sle-policy-override;
+      }
+      description
+        "SLO/SLE policy override option.";
+    }
+  }
+
+  grouping connectivity-construct-monitoring-metrics {
+    description
+      "Grouping for connectivity construct monitoring metrics.";
+    uses
+      te-packet-types:one-way-performance-metrics-gauge-packet;
+    uses
+      te-packet-types:two-way-performance-metrics-gauge-packet;
+  }
+  /* Main Network Slice Services Container */
+
+  container network-slice-services {
+    description
+      "Contains a list of Network Slice Services";
+    uses slice-service-template;
+    list slice-service {
+      key "id";
+      description
+        "A Slice Service is identified by a service id.";
+      leaf id {
+        type string;
+        description
+          "A unique Slice Service identifier within an NSC.";
+      }
+      leaf description {
+        type string;
+        description
+          "Textual description of the Slice Service.";
+      }
+      container service-tags {
+        description
+          "Container for a list of service tags for management
+           purposes, such as policy constraints
+           (e.g., Layer 2 or Layer 3 technology realization),
+           classification (e.g., customer names, opaque values).";
+        list tag-type {
+          key "tag-type";
+          description
+            "The service tag list.";
+          leaf tag-type {
+            type identityref {
+              base service-tag-type;
+            }
+            description
+              "Slice Service tag type, e.g., realization technology
+               constraints, customer name, or other customer-defined
+               opaque types.";
+          }
+          leaf-list value {
+            type string;
+            description
+              "The tag values, e.g., 5G customer names when multiple
+               customers share the same Slice Service in 5G scenario,
+               or Slice realization technology (such as Layer 2 or
+               Layer 3).";
+          }
+        }
+      }
+      uses service-slo-sle-policy;
+      leaf compute-only {
+        type empty;
+        description
+          "When present, this is a feasibility check. That is, no
+           resources are reserved in the network.";
+      }
+      uses ac-common:service-status;
+      container sdps {
+        description
+          "Slice Service SDPs.";
+        list sdp {
+          key "id";
+          min-elements 2;
+          description
+            "List of SDPs in this Slice Service.";
+          leaf id {
+            type string;
+            description
+              "The unique identifier of the SDP within the scope of
+               an NSC.";
+          }
+          leaf description {
+            type string;
+            description
+              "Provides a description of the SDP.";
+          }
+          uses geo:geo-location;
+          leaf node-id {
+            type string;
+            description
+              "A unique identifier of an edge node of the SDP
+               within the scope of the NSC.";
+          }
+          leaf-list sdp-ip-address {
+            type inet:ip-address;
+            description
+              "IPv4 or IPv6 address of the SDP.";
+          }
+          leaf tp-ref {
+            type leafref {
+              path
+                "/nw:networks/nw:network[nw:network-id="
+              + "current()/../../../custom-topology/network-ref]/"
+              + "nw:node/nt:termination-point/nt:tp-id";
+            }
+            description
+              "A reference to Termination Point (TP) in the custom
+               topology";
+            reference
+              "RFC 8345: A YANG Data Model for Network Topologies";
+          }
+          container service-match-criteria {
+            description
+              "Describes the Slice Service match criteria.";
+            list match-criterion {
+              key "index";
+              description
+                "List of the Slice Service traffic match criteria.";
+              leaf index {
+                type uint32;
+                description
+                  "The identifier of a match criteria.";
+              }
+              list match-type {
+                key "type";
+                description
+                  "List of the Slice Service traffic match types.";
+                leaf type {
+                  type identityref {
+                    base service-match-type;
+                  }
+                  mandatory true;
+                  description
+                    "Indicates the match type of the entry in the
+                     list of the Slice Service match criteria.";
+                }
+                leaf-list value {
+                  type string;
+                  description
+                    "Provides a value for the Slice Service match
+                     criteria, e.g., IP prefix, VLAN ID, or
+                     ACL name.";
+                }
+              }
+              leaf target-connection-group-id {
+                type leafref {
+                  path
+                    "../../../../../ietf-nss:connection-groups"
+                  + "/ietf-nss:connection-group"
+                  + "/ietf-nss:id";
+                }
+                mandatory true;
+                description
+                  "Reference to the Slice Service connection group.";
+              }
+              leaf connection-group-sdp-role {
+                type identityref {
+                  base vpn-common:role;
+                }
+                description
+                  "Specifies the role of SDP in the connection group
+                   When the service connection type is MP2MP,
+                   such as hub and spoke service connection type.
+                   In addition, this helps to create connectivity
+                   construct automatically, rather than explicitly
+                   specifying each one.";
+              }
+              leaf target-connectivity-construct-id {
+                type leafref {
+                  path
+                    "../../../../../ietf-nss:connection-groups"
+                  + "/ietf-nss:connection-group[ietf-nss:id="
+                  + "current()/../target-connection-group-id]"
+                  + "/ietf-nss:connectivity-construct/ietf-nss:id";
+                }
+                description
+                  "Reference to a Network Slice connection
+                   construct.";
+              }
+            }
+          }
+          uses service-qos;
+          container sdp-peering {
+            description
+              "Describes SDP peering attributes.";
+            leaf-list peer-sap-id {
+              type string;
+              description
+                "Indicates the reference to the remote endpoints of
+                 the attachment circuits. This information can be
+                 used for correlation purposes, such as identifying
+                 SAPs of provider equipments when requesting
+                 a service with CE based SDP attributes.";
+              reference
+                "RFC 9408: A YANG Network Data Model for Service
+                 Attachment Points (SAPs)";
+            }
+            container protocols {
+              description
+                "Serves as an augmentation target.
+                 Protocols can be augmented into this container,
+                 e.g., BGP, static routing.";
+            }
+          }
+          leaf-list ac-svc-ref {
+            type ac-svc:attachment-circuit-reference;
+            description
+              "A reference to the ACs that have been created before
+               the slice creation.";
+            reference
+              "RFC CCCC: YANG Data Models for Bearers and
+                'Attachment Circuits'-as-a-Service (ACaaS)";
+          }
+          leaf ce-mode {
+            type boolean;
+            description
+              "Indicates that SDP is on the CE.";
+          }
+          container attachment-circuits {
+            description
+              "List of attachment circuits.";
+            list attachment-circuit {
+              key "id";
+              description
+                "The Network Slice Service SDP attachment circuit
+                 related parameters.";
+              leaf id {
+                type string;
+                description
+                  "The identifier of attachment circuit.";
+              }
+              leaf description {
+                type string;
+                description
+                  "The attachment circuit's description.";
+              }
+              leaf ac-svc-ref {
+                type ac-svc:attachment-circuit-reference;
+                description
+                  "A reference to the AC service that has been
+                   created before the slice creation.";
+                reference
+                  "RFC CCCC: YANG Data Models for Bearers and
+                    'Attachment Circuits'-as-a-Service (ACaaS)";
+              }
+              leaf ac-node-id {
+                type string;
+                description
+                  "The attachment circuit node ID in the case of
+                   multi-homing.";
+              }
+              leaf ac-tp-id {
+                type string;
+                description
+                  "The termination port ID of the
+                   attachment circuit.";
+              }
+              leaf ac-ipv4-address {
+                type inet:ipv4-address;
+                description
+                  "The IPv4 address of the AC.";
+              }
+              leaf ac-ipv4-prefix-length {
+                type uint8;
+                description
+                  "The IPv4 subnet prefix length expressed in bits.";
+              }
+              leaf ac-ipv6-address {
+                type inet:ipv6-address;
+                description
+                  "The IPv6 address of the AC.";
+              }
+              leaf ac-ipv6-prefix-length {
+                type uint8;
+                description
+                  "The IPv6 subnet prefix length expressed in bits.";
+              }
+              leaf mtu {
+                type uint32;
+                units "bytes";
+                description
+                  "Maximum size of the Slice Service Layer 2 data
+                   packet that can traverse an SDP.";
+              }
+              container ac-tags {
+                description
+                  "Container for the attachment circuit tags.";
+                list ac-tag {
+                  key "tag-type";
+                  description
+                    "The attachment circuit tag list.";
+                  leaf tag-type {
+                    type identityref {
+                      base attachment-circuit-tag-type;
+                    }
+                    description
+                      "The attachment circuit tag type.";
+                  }
+                  leaf-list value {
+                    type string;
+                    description
+                      "The attachment circuit tag values.
+                       For example, the tag may indicate
+                       multiple VLAN identifiers.";
+                  }
+                }
+              }
+              uses service-qos;
+              container sdp-peering {
+                description
+                  "Describes SDP peering attributes.";
+                leaf peer-sap-id {
+                  type string;
+                  description
+                    "Indicates a reference to the remote endpoints
+                     of an attachment circuit. This information can
+                     be used for correlation purposes, such as
+                     identifying a service attachment point (SAP)
+                     of a provider equipment when requesting a
+                     service with CE based SDP attributes.";
+                  reference
+                    "RFC 9408: A YANG Network Data Model for
+                               Service Attachment Points (SAPs)";
+                }
+                container protocols {
+                  description
+                    "Serves as an augmentation target.
+                     Protocols can be augmented into this container,
+                     e.g., BGP or static routing.";
+                }
+              }
+              uses ac-common:service-status;
+            }
+          }
+          uses ac-common:service-status;
+          container sdp-monitoring {
+            config false;
+            description
+              "Container for SDP monitoring metrics.";
+            leaf incoming-bw-value {
+              type yang:gauge64;
+              units "bps";
+              description
+                "Indicates the absolute value of the incoming
+                 bandwidth at an SDP from the customer network or
+                 from another provider's network.";
+            }
+            leaf incoming-bw-percent {
+              type percentage;
+              units "percent";
+              description
+                "Indicates a percentage of the incoming bandwidth
+                 at an SDP from the customer network or
+                 from another provider's network.";
+            }
+            leaf outgoing-bw-value {
+              type yang:gauge64;
+              units "bps";
+              description
+                "Indicates the absolute value of the outgoing
+                 bandwidth at an SDP towards the customer network or
+                 towards another provider's network.";
+            }
+            leaf outgoing-bw-percent {
+              type percentage;
+              units "percent";
+              description
+                "Indicates a percentage of the outgoing bandwidth
+                 at an SDP towards the customer network or towards
+                 another provider's network.";
+            }
+          }
+        }
+      }
+      container connection-groups {
+        description
+          "Contains connection groups.";
+        list connection-group {
+          key "id";
+          description
+            "List of connection groups.";
+          leaf id {
+            type string;
+            description
+              "The connection group identifier.";
+          }
+          leaf connectivity-type {
+            type identityref {
+              base vpn-common:vpn-topology;
+            }
+            description
+              "Connection group connectivity type.";
+          }
+          uses service-slo-sle-policy;
+          /* Per connection group SLO/SLE policy
+           * overrides the per Slice SLO/SLE policy.
+           */
+          uses service-slo-sle-policy-override;
+          list connectivity-construct {
+            key "id";
+            description
+              "List of connectivity constructs.";
+            leaf id {
+              type string;
+              description
+                "The connectivity construct identifier.";
+            }
+            choice type {
+              default "p2p";
+              description
+                "Choice for connectivity construct type.";
+              case p2p {
+                description
+                  "P2P connectivity construct.";
+                leaf p2p-sender-sdp {
+                  type leafref {
+                    path "../../../../sdps/sdp/id";
+                  }
+                  description
+                    "Reference to a sender SDP.";
+                }
+                leaf p2p-receiver-sdp {
+                  type leafref {
+                    path "../../../../sdps/sdp/id";
+                  }
+                  description
+                    "Reference to a receiver SDP.";
+                }
+              }
+              case p2mp {
+                description
+                  "P2MP connectivity construct.";
+                leaf p2mp-sender-sdp {
+                  type leafref {
+                    path "../../../../sdps/sdp/id";
+                  }
+                  description
+                    "Reference to a sender SDP.";
+                }
+                leaf-list p2mp-receiver-sdp {
+                  type leafref {
+                    path "../../../../sdps/sdp/id";
+                  }
+                  description
+                    "Reference to a receiver SDP.";
+                }
+              }
+              case a2a {
+                description
+                  "A2A connectivity construct.";
+                list a2a-sdp {
+                  key "sdp-id";
+                  description
+                    "List of included A2A SDPs.";
+                  leaf sdp-id {
+                    type leafref {
+                      path "../../../../../sdps/sdp/id";
+                    }
+                    description
+                      "Reference to an SDP.";
+                  }
+                  uses service-slo-sle-policy;
+                }
+              }
+            }
+            uses service-slo-sle-policy;
+            /* Per connectivity construct SLO/SLE policy
+             * overrides the per slice SLO/SLE policy.
+             */
+            uses service-slo-sle-policy-override;
+            uses ac-common:service-status;
+            container connectivity-construct-monitoring {
+              config false;
+              description
+                "SLO status per connectivity construct.";
+              uses connectivity-construct-monitoring-metrics;
+            }
+          }
+          container connection-group-monitoring {
+            config false;
+            description
+              "SLO status per connection group.";
+            uses connectivity-construct-monitoring-metrics;
+          }
+        }
+      }
+      container custom-topology {
+        description
+          "Serves as an augmentation target.
+           Container for custom topology, which is indicated by the
+           referenced topology predefined, e.g., an abstract RFC8345
+           topology.";
+        uses nw:network-ref;
+      }
+    }
+  }
+}
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-network-slice@2022-03-04.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-network-slice@2022-03-04.yang
new file mode 100644
index 0000000000000000000000000000000000000000..b1ead4bf025c59065d01172f309af188c0ee2f75
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-network-slice@2022-03-04.yang
@@ -0,0 +1,1130 @@
+module ietf-network-slice {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-network-slice";
+  prefix ietf-ns;
+
+  import ietf-inet-types {
+    prefix inet;
+    reference
+      "RFC 6991: Common YANG Types.";
+  }
+  import ietf-te-types {
+    prefix te-types;
+    reference
+      "RFC 8776: Common YANG Data Types for Traffic Engineering.";
+  }
+  import ietf-te-packet-types {
+    prefix te-packet-types;
+    reference
+      "RFC 8776: Common YANG Data Types for Traffic Engineering.";
+  }
+
+  organization
+    "IETF Traffic Engineering Architecture and Signaling (TEAS)
+     Working Group";
+  contact
+    "WG Web:  <https://tools.ietf.org/wg/teas/>
+     WG List:  <mailto:teas@ietf.org>
+
+     Editor: Bo Wu
+          <lana.wubo@huawei.com>
+     Editor: Dhruv Dhody
+          <dhruv.ietf@gmail.com>
+     Editor: Reza Rokui
+          <reza.rokui@nokia.com>
+     Editor: Tarek Saad
+          <tsaad@juniper.net>
+     Author: Liuyan Han
+          <hanliuyan@chinamobile.com>";
+  description
+    "This module contains a YANG module for the IETF Network Slice.
+
+        Copyright (c) 2022 IETF Trust and the persons identified as
+        authors of the code.  All rights reserved.
+
+        Redistribution and use in source and binary forms, with or
+        without modification, is permitted pursuant to, and subject
+        to the license terms contained in, the Revised BSD License
+        set forth in Section 4.c of the IETF Trust's Legal Provisions
+        Relating to IETF Documents
+        (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC XXXX; see the
+     RFC itself for full legal notices.";
+
+  revision 2022-03-04 {
+    description
+      "initial version.";
+    reference
+      "RFC XXXX: A Yang Data Model for IETF Network Slice Operation";
+  }
+
+  /* Features */
+  /* Identities */
+
+  identity ns-tag-type {
+    description
+      "Base identity for IETF Network Slice tag type.";
+  }
+
+  identity ns-tag-customer {
+    base ns-tag-type;
+    description
+      "The IETF Network Slice customer ID tag type.";
+  }
+
+  identity ns-tag-service {
+    base ns-tag-type;
+    description
+      "The IETF Network Slice service tag type.";
+  }
+
+  identity ns-tag-opaque {
+    base ns-tag-type;
+    description
+      "The IETF Network Slice opaque tag type.";
+  }
+
+  identity network-access-tag-type {
+    description
+      "Base identity for the network access tag type.";
+  }
+
+  identity network-access-tag-vlan-id {
+    base network-access-tag-type;
+    description
+      "The network access interface VLAN ID tag type.";
+  }
+
+  identity network-access-tag-ip-mask {
+    base network-access-tag-type;
+    description
+      "The network access tag IP mask.";
+  }
+
+  identity network-access-tag-opaque {
+    base network-access-tag-type;
+    description
+      "The network access opaque tag type.";
+  }
+
+  identity ns-isolation-type {
+    description
+      "Base identity for IETF Network slice isolation level.";
+  }
+
+  identity ns-isolation-shared {
+    base ns-isolation-type;
+    description
+      "Shared resources (e.g. queues) are associated with the Network
+       Slice traffic. Hence, the IETF network slice traffic can be
+       impacted by effects of other services traffic sharing
+       the same resources.";
+  }
+
+  identity ns-isolation-dedicated {
+    base ns-isolation-type;
+    description
+      "Dedicated resources (e.g. queues) are associated with the
+       Network Slice traffic. Hence, the IETF network slice traffic
+       is isolated from other servceis traffic sharing the same
+       resources.";
+  }
+
+  identity ns-security-type {
+    description
+      "Base identity for for IETF Network security level.";
+  }
+
+  identity ns-security-authenticate {
+    base ns-security-type;
+    description
+      "IETF Network Slice requires authentication.";
+  }
+
+  identity ns-security-integrity {
+    base ns-security-type;
+    description
+      "IETF Network Slice requires data integrity.";
+  }
+
+  identity ns-security-encryption {
+    base ns-security-type;
+    description
+      "IETF Network Slice requires data encryption.";
+  }
+
+  identity ns-connectivity-type {
+    description
+      "Base identity for IETF Network Slice connectivity.";
+  }
+
+  identity point-to-point {
+    base ns-connectivity-type;
+    description
+      "Identity for point-to-point IETF Network Slice connectivity.";
+  }
+
+  identity point-to-multipoint {
+    base ns-connectivity-type;
+    description
+      "Identity for point-to-multipoint IETF Network Slice
+       connectivity.";
+  }
+
+  identity multipoint-to-multipoint {
+    base ns-connectivity-type;
+    description
+      "Identity for multipoint-to-multipoint IETF Network Slice
+       connectivity.";
+  }
+
+  identity any-to-any {
+    base ns-connectivity-type;
+    description
+      "Identity for any-to-any IETF Network Slice connectivity.";
+  }
+
+  identity hub-spoke {
+    base ns-connectivity-type;
+    description
+      "Identity for Hub-and-Spoke IETF Network Slice connectivity.";
+  }
+
+  identity custom {
+    base ns-connectivity-type;
+    description
+      "Identity of a custom NS topology where Hubs can act as
+       Spoke for certain parts of the network or Spokes as Hubs.";
+  }
+
+  identity endpoint-role {
+    description
+      "Base identity of a NSE role in an IETF Network Slice topology.";
+  }
+
+  identity any-to-any-role {
+    base endpoint-role;
+    description
+      "Identity of any-to-any NS.";
+  }
+
+  identity spoke-role {
+    base endpoint-role;
+    description
+      "A NSE is acting as a Spoke.";
+  }
+
+  identity hub-role {
+    base endpoint-role;
+    description
+      "A NSE is acting as a Hub.";
+  }
+
+  identity ns-slo-metric-type {
+    description
+      "Base identity for IETF Network Slice SLO metric type.";
+  }
+
+  identity ns-slo-one-way-bandwidth {
+    base ns-slo-metric-type;
+    description
+      "SLO bandwidth metric. Minimum guaranteed bandwidth between
+       two endpoints at any time and is measured unidirectionally.";
+  }
+
+  identity ns-slo-two-way-bandwidth {
+    base ns-slo-metric-type;
+    description
+      "SLO bandwidth metric. Minimum guaranteed bandwidth between
+       two endpoints at any time.";
+  }
+
+  identity ns-slo-shared-bandwidth {
+    base ns-slo-metric-type;
+    description
+      "The shared SLO bandwidth bound. It is the limit on the
+       bandwidth that can be shared amongst a group of connections
+       of an IETF Network Slice.";
+  }
+
+  identity ns-slo-one-way-delay {
+    base ns-slo-metric-type;
+    description
+      "SLO one-way-delay is the upper bound of network delay when
+       transmitting between two endpoints. The metric is defined in
+       RFC7679.";
+  }
+
+  identity ns-slo-two-way-delay {
+    base ns-slo-metric-type;
+    description
+      "SLO two-way delay is the upper bound of network delay when
+       transmitting between two endpoints. The metric is defined in
+       RFC2681.";
+  }
+  identity ns-slo-one-way-delay-variation {
+    base ns-slo-metric-type;
+    description
+      "SLO one-way delay variation is defined by RFC3393, is the
+       difference in the one-way delay between sequential packets
+       between two endpoints.";
+  }
+
+  identity ns-slo-two-way-delay-variation {
+    base ns-slo-metric-type;
+    description
+      "SLO two-way delay variation is defined by RFC5481, is the
+       difference in the round-trip delay between sequential packets
+       between two endpoints.";
+  }
+
+  identity ns-slo-one-way-packet-loss {
+    base ns-slo-metric-type;
+    description
+      "SLO loss metric. The ratio of packets dropped to packets
+       transmitted between two endpoints in one-way
+       over a period of time as specified in RFC7680.";
+  }
+
+  identity ns-slo-two-way-packet-loss {
+    base ns-slo-metric-type;
+    description
+      "SLO loss metric. The ratio of packets dropped to packets
+       transmitted between two endpoints in two-way
+       over a period of time as specified in RFC7680.";
+  }
+
+  identity ns-slo-availability {
+    base ns-slo-metric-type;
+    description
+      "SLO availability level.";
+  }
+
+  identity ns-match-type {
+    description
+      "Base identity for IETF Network Slice traffic match type.";
+  }
+
+  identity ns-phy-interface-match {
+    base ns-match-type;
+    description
+      "Use the physical interface as match criteria for the IETF
+       Network Slice traffic.";
+  }
+
+  identity ns-vlan-match {
+    base ns-match-type;
+    description
+      "Use the VLAN ID as match criteria for the IETF Network Slice
+       traffic.";
+  }
+
+  identity ns-label-match {
+    base ns-match-type;
+    description
+      "Use the MPLS label as match criteria for the IETF Network
+       Slice traffic.";
+  }
+
+  identity peering-protocol-type {
+    description
+      "Base identity for NSE peering protocol type.";
+  }
+
+  identity peering-protocol-bgp {
+    base peering-protocol-type;
+    description
+      "Use BGP as protocol for NSE peering with customer device.";
+  }
+
+  identity peering-static-routing {
+    base peering-protocol-type;
+    description
+      "Use static routing for NSE peering with customer device.";
+  }
+
+  /*
+   * Identity for availability-type
+   */
+
+  identity availability-type {
+    description
+      "Base identity from which specific availability types are
+       derived.";
+  }
+
+  identity level-1 {
+    base availability-type;
+    description
+      "level 1: 99.9999%";
+  }
+  identity level-2 {
+    base availability-type;
+    description
+      "level 2: 99.999%";
+  }
+
+  identity level-3 {
+    base availability-type;
+    description
+      "level 3: 99.99%";
+  }
+
+  identity level-4 {
+    base availability-type;
+    description
+      "level 4: 99.9%";
+  }
+
+  identity level-5 {
+    base availability-type;
+    description
+      "level 5: 99%";
+  }
+
+  /* typedef */
+
+  typedef operational-type {
+    type enumeration {
+      enum up {
+        value 0;
+        description
+          "Operational status UP.";
+      }
+      enum down {
+        value 1;
+        description
+          "Operational status DOWN.";
+      }
+      enum unknown {
+        value 2;
+        description
+          "Operational status UNKNOWN.";
+      }
+    }
+    description
+      "This is a read-only attribute used to determine the
+       status of a particular element.";
+  }
+  typedef ns-monitoring-type {
+    type enumeration {
+      enum one-way {
+        description
+          "Represents one-way measurments monitoring type.";
+      }
+      enum two-way {
+        description
+          "represents two-way measurements monitoring type.";
+      }
+    }
+    description
+      "An enumerated type for monitoring on a IETF Network Slice
+       connection.";
+  }
+
+  /* Groupings */
+
+  grouping status-params {
+    description
+      "A grouping used to join operational and administrative status.";
+    container status {
+      description
+        "A container for the administrative and operational state.";
+      leaf admin-enabled {
+        type boolean;
+        description
+          "The administrative status.";
+      }
+      leaf oper-status {
+        type operational-type;
+        config false;
+        description
+          "The operational status.";
+      }
+    }
+  }
+
+  grouping ns-match-criteria {
+    description
+      "A grouping for the IETF Network Slice match definition.";
+    container ns-match-criteria {
+      description
+        "Describes the IETF Network Slice match criteria.";
+      list ns-match-criterion {
+        key "index";
+        description
+          "List of the IETF Network Slice traffic match criteria.";
+        leaf index {
+          type uint32;
+          description
+            "The entry index.";
+        }
+        leaf match-type {
+          type identityref {
+            base ns-match-type;
+          }
+          description
+            "Identifies an entry in the list of the IETF Network Slice
+             match criteria.";
+        }
+        list values {
+          key "index";
+          description
+            "List of match criteria values.";
+          leaf index {
+            type uint8;
+            description
+              "Index of an entry in the list.";
+          }
+          leaf value {
+            type string;
+            description
+              "Describes the IETF Network Slice match criteria, e.g.
+               IP address, VLAN, etc.";
+          }
+        }
+        leaf target-ns-connection-group-id {
+          type leafref {
+            path "/network-slices/network-slice"
+               + "/ns-connection-groups/ns-connection-group"
+               + "/ns-connection-group-id";
+          }
+          description
+            "reference to a Network Slice connection group.";
+        }
+      }
+    }
+  }
+
+  grouping ns-sles {
+    description
+      "Indirectly Measurable Objectives of a IETF Network
+       Slice.";
+    leaf-list security {
+      type identityref {
+        base ns-security-type;
+      }
+      description
+        "The IETF Network Slice security SLE(s)";
+    }
+    leaf isolation {
+      type identityref {
+        base ns-isolation-type;
+      }
+      default "ns-isolation-shared";
+      description
+        "The IETF Network Slice isolation SLE requirement.";
+    }
+    leaf max-occupancy-level {
+      type uint8 {
+        range "1..100";
+      }
+      description
+        "The maximal occupancy level specifies the number of flows to
+         be admitted.";
+    }
+    leaf mtu {
+      type uint16;
+      units "bytes";
+      mandatory true;
+      description
+        "The MTU specifies the maximum length in octets of data
+         packets that can be transmitted by the NS. The value needs
+         to be less than or equal to the minimum MTU value of
+         all 'ep-network-access-points' in the NSEs of the NS.";
+    }
+    container steering-constraints {
+      description
+        "Container for the policy of steering constraints
+         applicable to IETF Network Slice.";
+      container path-constraints {
+        description
+          "Container for the policy of path constraints
+           applicable to IETF Network Slice.";
+      }
+      container service-function {
+        description
+          "Container for the policy of service function
+           applicable to IETF Network Slice.";
+      }
+    }
+  }
+
+  grouping ns-metric-bounds {
+    description
+      "IETF Network Slice metric bounds grouping.";
+    container ns-metric-bounds {
+      description
+        "IETF Network Slice metric bounds container.";
+      list ns-metric-bound {
+        key "metric-type";
+        description
+          "List of IETF Network Slice metric bounds.";
+        leaf metric-type {
+          type identityref {
+            base ns-slo-metric-type;
+          }
+          description
+            "Identifies an entry in the list of metric type
+             bounds for the IETF Network Slice.";
+        }
+        leaf metric-unit {
+          type string;
+          mandatory true;
+          description
+            "The metric unit of the parameter. For example,
+             s, ms, ns, and so on.";
+        }
+        leaf value-description {
+          type string;
+          description
+            "The description of previous value.";
+        }
+        leaf bound {
+          type uint64;
+          default "0";
+          description
+            "The Bound on the Network Slice connection metric. A
+             zero indicate an unbounded upper limit for the
+             specific metric-type.";
+        }
+      }
+    }
+  }
+
+  grouping ep-peering {
+    description
+      "A grouping for the IETF Network Slice Endpoint peering.";
+    container ep-peering {
+      description
+        "Describes NSE peering attributes.";
+      list protocol {
+        key "protocol-type";
+        description
+          "List of the NSE peering protocol.";
+        leaf protocol-type {
+          type identityref {
+            base peering-protocol-type;
+          }
+          description
+            "Identifies an entry in the list of NSE peering
+             protocol type.";
+        }
+        list attribute {
+          key "index";
+          description
+            "List of protocol attribute.";
+          leaf index {
+            type uint8;
+            description
+              "Index of an entry in the list.";
+          }
+          leaf attribute-description {
+            type string;
+            description
+              "The description of the attribute.";
+          }
+          leaf value {
+            type string;
+            description
+              "Describes the value of protocol attribute, e.g.
+               nexthop address, peer address, etc.";
+          }
+        }
+      }
+    }
+  }
+
+  grouping ep-network-access-points {
+    description
+      "Grouping for the endpoint network access definition.";
+    container ep-network-access-points {
+      description
+        "List of network access points.";
+      list ep-network-access-point {
+        key "network-access-id";
+        description
+          "The IETF Network Slice network access points
+           related parameters.";
+        leaf network-access-id {
+          type string;
+          description
+            "Uniquely identifier a network access point.";
+        }
+        leaf network-access-description {
+          type string;
+          description
+            "The network access point description.";
+        }
+        leaf network-access-node-id {
+          type string;
+          description
+            "The network access point node ID in the case of
+             multi-homing.";
+        }
+        leaf network-access-tp-id {
+          type string;
+          description
+            "The termination port ID of the EP network access
+             point.";
+        }
+        leaf network-access-tp-ip-address {
+          type inet:ip-address;
+          description
+            "The IP address of the EP network access point.";
+        }
+        leaf network-access-tp-ip-prefix-length {
+          type uint8;
+          description
+            "The subnet prefix length expressed in bits.";
+        }
+        leaf network-access-qos-policy-name {
+          type string;
+          description
+            "The name of the QoS policy that is applied to the
+             network access point. The name can reference a QoS
+             profile that is pre-provisioned on the device.";
+        }
+        leaf mtu {
+          type uint16;
+          units "bytes";
+          mandatory true;
+          description
+            "Maximum size in octets of a data packet that
+             can traverse a NSE network access point.";
+        }
+        container network-access-tags {
+          description
+            "Container for the network access tags.";
+          list network-access-tag {
+            key "index";
+            description
+              "The network access point tags list.";
+            leaf index {
+              type uint32;
+              description
+                "The entry index.";
+            }
+            leaf network-access-tag-type {
+              type identityref {
+                base network-access-tag-type;
+              }
+              description
+                "The network access point tag type.";
+            }
+            leaf network-access-tag-value {
+              type string;
+              description
+                "The network access point tag value.";
+            }
+          }
+        }
+        /* Per ep-network-access-point rate limits */
+        uses ns-match-criteria;
+        uses ep-peering;
+        uses ns-rate-limit;
+      }
+    }
+  }
+
+  grouping ep-monitoring-metrics {
+    description
+      "Grouping for the NS endpoint monitoring metrics.";
+    container ep-monitoring {
+      config false;
+      description
+        "Container for NS endpoint monitoring metrics.";
+      leaf incoming-utilized-bandwidth {
+        type te-types:te-bandwidth;
+        description
+          "Incoming bandwidth utilization at an endpoint.";
+      }
+      leaf incoming-bw-utilization {
+        type decimal64 {
+          fraction-digits 5;
+          range "0..100";
+        }
+        units "percent";
+        mandatory true;
+        description
+          "To be used to define the bandwidth utilization
+           as a percentage of the available bandwidth.";
+      }
+      leaf outgoing-utilized-bandwidth {
+        type te-types:te-bandwidth;
+        description
+          "Outoing bandwidth utilization at an endpoint.";
+      }
+      leaf outgoing-bw-utilization {
+        type decimal64 {
+          fraction-digits 5;
+          range "0..100";
+        }
+        units "percent";
+        mandatory true;
+        description
+          "To be used to define the bandwidth utilization
+           as a percentage of the available bandwidth.";
+      }
+    }
+  }
+
+  grouping ns-connection-monitoring-metrics {
+    description
+      "Grouping for NS connection monitoring metrics.";
+    uses te-packet-types:one-way-performance-metrics-packet;
+    uses te-packet-types:two-way-performance-metrics-packet;
+  }
+
+  grouping geolocation-container {
+    description
+      "A grouping containing a GPS location.";
+    container location {
+      description
+        "A container containing a GPS location.";
+      leaf altitude {
+        type int64;
+        units "millimeter";
+        description
+          "Distance above the sea level.";
+      }
+      leaf latitude {
+        type decimal64 {
+          fraction-digits 8;
+          range "-90..90";
+        }
+        description
+          "Relative position north or south on the Earth's surface.";
+      }
+      leaf longitude {
+        type decimal64 {
+          fraction-digits 8;
+          range "-180..180";
+        }
+        description
+          "Angular distance east or west on the Earth's surface.";
+      }
+    }
+    // gps-location
+  }
+
+  // geolocation-container
+
+  grouping bw-rate-limits {
+    description
+      "Bandwidth rate limits grouping.";
+    reference
+      "RFC 7640: Traffic Management Benchmarking";
+    leaf cir {
+      type uint64;
+      units "bps";
+      description
+        "Committed Information Rate. The maximum number of bits
+         that a port can receive or send during one-second over an
+         interface.";
+    }
+    leaf cbs {
+      type uint64;
+      units "bytes";
+      description
+        "Committed Burst Size. CBS controls the bursty nature
+         of the traffic. Traffic that does not use the configured
+         CIR accumulates credits until the credits reach the
+         configured CBS.";
+    }
+    leaf eir {
+      type uint64;
+      units "bps";
+      description
+        "Excess Information Rate, i.e., excess frame delivery
+         allowed not subject to SLA. The traffic rate can be
+         limited by EIR.";
+    }
+    leaf ebs {
+      type uint64;
+      units "bytes";
+      description
+        "Excess Burst Size. The bandwidth available for burst
+         traffic from the EBS is subject to the amount of
+         bandwidth that is accumulated during periods when
+         traffic allocated by the EIR policy is not used.";
+    }
+    leaf pir {
+      type uint64;
+      units "bps";
+      description
+        "Peak Information Rate, i.e., maximum frame delivery
+         allowed. It is equal to or less than sum of CIR and EIR.";
+    }
+    leaf pbs {
+      type uint64;
+      units "bytes";
+      description
+        "Peak Burst Size.";
+    }
+  }
+
+  grouping ns-rate-limit {
+    description
+      "The rate limits grouping.";
+    container incoming-rate-limits {
+      description
+        "Container for the asymmetric traffic control.";
+      uses bw-rate-limits;
+    }
+    container outgoing-rate-limits {
+      description
+        "The rate-limit imposed on outgoing traffic.";
+      uses bw-rate-limits;
+    }
+  }
+
+  grouping endpoint {
+    description
+      "IETF Network Slice endpoint related information";
+    leaf ep-id {
+      type string;
+      description
+        "Unique identifier for the referred IETF Network
+         Slice endpoint.";
+    }
+    leaf ep-description {
+      type string;
+      description
+        "Give more description of the Network Slice endpoint.";
+    }
+    uses geolocation-container;
+    leaf node-id {
+      type string;
+      description
+        "Uniquely identifies an edge node within the IETF slice
+         network.";
+    }
+    leaf ep-ip {
+      type inet:ip-address;
+      description
+        "The IP address of the endpoint.";
+    }
+    uses ns-match-criteria;
+    uses ep-peering;
+    uses ep-network-access-points;
+    uses ns-rate-limit;
+    /* Per NSE rate limits */
+    uses status-params;
+    uses ep-monitoring-metrics;
+  }
+
+  //ns-endpoint
+
+  grouping ns-connection {
+    description
+      "The network slice connection grouping.";
+    list ns-connection {
+      key "ns-connection-id";
+      description
+        "List of Network Slice connections.";
+      leaf ns-connection-id {
+        type uint32;
+        description
+          "The Network Slice connection identifier.";
+      }
+      leaf ns-connectivity-type {
+        type identityref {
+          base ns-connectivity-type;
+        }
+        default "point-to-point";
+        description
+          "Network Slice connection construct type.";
+      }
+      leaf-list src-nse {
+        type leafref {
+          path "/network-slices/network-slice"
+             + "/ns-endpoints/ns-endpoint/ep-id";
+        }
+        description
+          "reference to source Network Slice endpoint.";
+      }
+      leaf-list dest-nse {
+        type leafref {
+          path "/network-slices/network-slice"
+             + "/ns-endpoints/ns-endpoint/ep-id";
+        }
+        description
+          "reference to source Network Slice endpoint.";
+      }
+      uses ns-slo-sle-policy;
+      /* Per connection ns-slo-sle-policy overrides
+       * the per network slice ns-slo-sle-policy.
+       */
+      container ns-connection-monitoring {
+        config false;
+        description
+          "SLO status Per NS connection.";
+        uses ns-connection-monitoring-metrics;
+      }
+    }
+  }
+
+  //ns-connection
+
+  grouping ns-connection-group {
+    description
+      "The Network Slice connection group is described in this
+       container.";
+    leaf ns-connection-group-id {
+      type string;
+      description
+        "The Network Slice connection group identifier.";
+    }
+    uses ns-slo-sle-policy;
+    uses ns-connection;
+    /* Per connection ns-slo-sle-policy overrides
+     * the per network slice ns-slo-sle-policy.
+     */
+    container ns-connection-group-monitoring {
+      config false;
+      description
+        "SLO status Per NS connection.";
+      uses ns-connection-monitoring-metrics;
+    }
+  }
+
+  //ns-connection-group
+
+  grouping slice-template {
+    description
+      "Grouping for slice-templates.";
+    container ns-slo-sle-templates {
+      description
+        "Contains a set of network slice templates to
+         reference in the IETF network slice.";
+      list ns-slo-sle-template {
+        key "id";
+        leaf id {
+          type string;
+          description
+            "Identification of the Service Level Objective (SLO)
+             and Service Level Expectation (SLE) template to be used.
+             Local administration meaning.";
+        }
+        leaf template-description {
+          type string;
+          description
+            "Description of the SLO &amp; SLE policy template.";
+        }
+        description
+          "List for SLO and SLE template identifiers.";
+      }
+    }
+  }
+
+  /* Configuration data nodes */
+
+  grouping ns-slo-sle-policy {
+    description
+      "Network Slice policy grouping.";
+    choice ns-slo-sle-policy {
+      description
+        "Choice for SLO and SLE policy template.
+         Can be standard template or customized template.";
+      case standard {
+        description
+          "Standard SLO template.";
+        leaf slo-sle-template {
+          type leafref {
+            path "/network-slices"
+               + "/ns-slo-sle-templates/ns-slo-sle-template/id";
+          }
+          description
+            "Standard SLO and SLE template to be used.";
+        }
+      }
+      case custom {
+        description
+          "Customized SLO template.";
+        container slo-sle-policy {
+          description
+            "Contains the SLO policy.";
+          leaf policy-description {
+            type string;
+            description
+              "Description of the SLO policy.";
+          }
+          uses ns-metric-bounds;
+          uses ns-sles;
+        }
+      }
+    }
+  }
+
+  container network-slices {
+    description
+      "Containes a list of IETF network slice";
+    uses slice-template;
+    list network-slice {
+      key "ns-id";
+      description
+        "A network-slice is identified by a ns-id.";
+      leaf ns-id {
+        type string;
+        description
+          "A unique network-slice identifier across an IETF NSC.";
+      }
+      leaf ns-description {
+        type string;
+        description
+          "Give more description of the network slice.";
+      }
+      container ns-tags {
+        description
+          "Container for the list of IETF Network Slice tags.";
+        list ns-tag {
+          key "index";
+          description
+            "IETF Network Slice tag list.";
+          leaf index {
+            type uint32;
+            description
+              "The entry index.";
+          }
+          leaf ns-tag-type {
+            type identityref {
+              base ns-tag-type;
+            }
+            description
+              "The IETF Network Slice tag type.";
+          }
+          leaf ns-tag-value {
+            type string;
+            description
+              "The IETF Network Slice tag value.";
+          }
+        }
+      }
+      uses ns-slo-sle-policy;
+      uses status-params;
+      container ns-endpoints {
+        description
+          "NS Endpoints.";
+        list ns-endpoint {
+          key "ep-id";
+          uses endpoint;
+          description
+            "List of endpoints in this slice.";
+        }
+      }
+      container ns-connection-groups {
+        description
+          "Contains NS connections group.";
+        list ns-connection-group {
+          key "ns-connection-group-id";
+          description
+            "List of Network Slice connections.";
+          uses ns-connection-group;
+        }
+      }
+    }
+    //ietf-network-slice list
+  }
+}
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-network-topology@2018-02-26.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-network-topology@2018-02-26.yang
new file mode 100644
index 0000000000000000000000000000000000000000..1ec944d791db1da1b8236c6069f10d65b1b6f97f
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-network-topology@2018-02-26.yang
@@ -0,0 +1,294 @@
+module ietf-network-topology {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-network-topology";
+  prefix nt;
+
+  import ietf-inet-types {
+    prefix inet;
+    reference
+      "RFC 6991: Common YANG Data Types";
+  }
+  import ietf-network {
+    prefix nw;
+    reference
+      "RFC 8345: A YANG Data Model for Network Topologies";
+  }
+
+  organization
+    "IETF I2RS (Interface to the Routing System) Working Group";
+
+  contact
+    "WG Web:    <https://datatracker.ietf.org/wg/i2rs/>
+     WG List:   <mailto:i2rs@ietf.org>
+
+     Editor:    Alexander Clemm
+                <mailto:ludwig@clemm.org>
+
+     Editor:    Jan Medved
+                <mailto:jmedved@cisco.com>
+
+     Editor:    Robert Varga
+                <mailto:robert.varga@pantheon.tech>
+
+     Editor:    Nitin Bahadur
+                <mailto:nitin_bahadur@yahoo.com>
+
+     Editor:    Hariharan Ananthakrishnan
+                <mailto:hari@packetdesign.com>
+
+     Editor:    Xufeng Liu
+                <mailto:xufeng.liu.ietf@gmail.com>";
+
+  description
+    "This module defines a common base model for a network topology,
+     augmenting the base network data model with links to connect
+     nodes, as well as termination points to terminate links
+     on nodes.
+
+     Copyright (c) 2018 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 8345;
+     see the RFC itself for full legal notices.";
+
+  revision 2018-02-26 {
+    description
+      "Initial revision.";
+    reference
+      "RFC 8345: A YANG Data Model for Network Topologies";
+  }
+
+  typedef link-id {
+    type inet:uri;
+    description
+      "An identifier for a link in a topology.  The precise
+       structure of the link-id will be up to the implementation.
+       The identifier SHOULD be chosen such that the same link in a
+       real network topology will always be identified through the
+       same identifier, even if the data model is instantiated in
+       separate datastores.  An implementation MAY choose to capture
+       semantics in the identifier -- for example, to indicate the
+       type of link and/or the type of topology of which the link is
+       a part.";
+  }
+
+  typedef tp-id {
+    type inet:uri;
+    description
+      "An identifier for termination points on a node.  The precise
+       structure of the tp-id will be up to the implementation.
+       The identifier SHOULD be chosen such that the same termination
+       point in a real network topology will always be identified
+       through the same identifier, even if the data model is
+       instantiated in separate datastores.  An implementation MAY
+       choose to capture semantics in the identifier -- for example,
+       to indicate the type of termination point and/or the type of
+       node that contains the termination point.";
+  }
+
+  grouping link-ref {
+    description
+      "This grouping can be used to reference a link in a specific
+       network.  Although it is not used in this module, it is
+       defined here for the convenience of augmenting modules.";
+    leaf link-ref {
+      type leafref {
+        path "/nw:networks/nw:network[nw:network-id=current()/../"+
+          "network-ref]/nt:link/nt:link-id";
+        require-instance false;
+      }
+      description
+        "A type for an absolute reference to a link instance.
+         (This type should not be used for relative references.
+         In such a case, a relative path should be used instead.)";
+    }
+    uses nw:network-ref;
+  }
+
+  grouping tp-ref {
+    description
+      "This grouping can be used to reference a termination point
+       in a specific node.  Although it is not used in this module,
+       it is defined here for the convenience of augmenting
+       modules.";
+    leaf tp-ref {
+      type leafref {
+        path "/nw:networks/nw:network[nw:network-id=current()/../"+
+          "network-ref]/nw:node[nw:node-id=current()/../"+
+          "node-ref]/nt:termination-point/nt:tp-id";
+        require-instance false;
+      }
+      description
+        "A type for an absolute reference to a termination point.
+         (This type should not be used for relative references.
+         In such a case, a relative path should be used instead.)";
+    }
+    uses nw:node-ref;
+  }
+
+  augment "/nw:networks/nw:network" {
+    description
+      "Add links to the network data model.";
+    list link {
+      key "link-id";
+      description
+        "A network link connects a local (source) node and
+         a remote (destination) node via a set of the respective
+         node's termination points.  It is possible to have several
+         links between the same source and destination nodes.
+         Likewise, a link could potentially be re-homed between
+         termination points.  Therefore, in order to ensure that we
+         would always know to distinguish between links, every link
+         is identified by a dedicated link identifier.  Note that a
+         link models a point-to-point link, not a multipoint link.";
+      leaf link-id {
+        type link-id;
+        description
+          "The identifier of a link in the topology.
+           A link is specific to a topology to which it belongs.";
+      }
+      container source {
+        description
+          "This container holds the logical source of a particular
+           link.";
+        leaf source-node {
+          type leafref {
+            path "../../../nw:node/nw:node-id";
+            require-instance false;
+          }
+          description
+            "Source node identifier.  Must be in the same topology.";
+        }
+        leaf source-tp {
+          type leafref {
+            path "../../../nw:node[nw:node-id=current()/../"+
+              "source-node]/termination-point/tp-id";
+            require-instance false;
+          }
+          description
+            "This termination point is located within the source node
+             and terminates the link.";
+        }
+      }
+
+      container destination {
+        description
+          "This container holds the logical destination of a
+           particular link.";
+        leaf dest-node {
+          type leafref {
+            path "../../../nw:node/nw:node-id";
+          require-instance false;
+          }
+          description
+            "Destination node identifier.  Must be in the same
+             network.";
+        }
+        leaf dest-tp {
+          type leafref {
+            path "../../../nw:node[nw:node-id=current()/../"+
+              "dest-node]/termination-point/tp-id";
+            require-instance false;
+          }
+          description
+            "This termination point is located within the
+             destination node and terminates the link.";
+        }
+      }
+      list supporting-link {
+        key "network-ref link-ref";
+        description
+          "Identifies the link or links on which this link depends.";
+        leaf network-ref {
+          type leafref {
+            path "../../../nw:supporting-network/nw:network-ref";
+          require-instance false;
+          }
+          description
+            "This leaf identifies in which underlay topology
+             the supporting link is present.";
+        }
+
+        leaf link-ref {
+          type leafref {
+            path "/nw:networks/nw:network[nw:network-id=current()/"+
+              "../network-ref]/link/link-id";
+            require-instance false;
+          }
+          description
+            "This leaf identifies a link that is a part
+             of this link's underlay.  Reference loops in which
+             a link identifies itself as its underlay, either
+             directly or transitively, are not allowed.";
+        }
+      }
+    }
+  }
+  augment "/nw:networks/nw:network/nw:node" {
+    description
+      "Augments termination points that terminate links.
+       Termination points can ultimately be mapped to interfaces.";
+    list termination-point {
+      key "tp-id";
+      description
+        "A termination point can terminate a link.
+         Depending on the type of topology, a termination point
+         could, for example, refer to a port or an interface.";
+      leaf tp-id {
+        type tp-id;
+        description
+          "Termination point identifier.";
+      }
+      list supporting-termination-point {
+        key "network-ref node-ref tp-ref";
+        description
+          "This list identifies any termination points on which a
+           given termination point depends or onto which it maps.
+           Those termination points will themselves be contained
+           in a supporting node.  This dependency information can be
+           inferred from the dependencies between links.  Therefore,
+           this item is not separately configurable.  Hence, no
+           corresponding constraint needs to be articulated.
+           The corresponding information is simply provided by the
+           implementing system.";
+
+        leaf network-ref {
+          type leafref {
+            path "../../../nw:supporting-node/nw:network-ref";
+          require-instance false;
+          }
+          description
+            "This leaf identifies in which topology the
+             supporting termination point is present.";
+        }
+        leaf node-ref {
+          type leafref {
+            path "../../../nw:supporting-node/nw:node-ref";
+          require-instance false;
+          }
+          description
+            "This leaf identifies in which node the supporting
+             termination point is present.";
+        }
+        leaf tp-ref {
+          type leafref {
+            path "/nw:networks/nw:network[nw:network-id=current()/"+
+              "../network-ref]/nw:node[nw:node-id=current()/../"+
+              "node-ref]/termination-point/tp-id";
+            require-instance false;
+          }
+          description
+            "Reference to the underlay node (the underlay node must
+             be in a different topology).";
+        }
+      }
+    }
+  }
+}
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-network@2018-02-26.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-network@2018-02-26.yang
new file mode 100644
index 0000000000000000000000000000000000000000..6a03d7e41614cc8dc017cfb4d5aacfb4ca60bc2c
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-network@2018-02-26.yang
@@ -0,0 +1,192 @@
+module ietf-network {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-network";
+  prefix nw;
+
+  import ietf-inet-types {
+    prefix inet;
+    reference
+      "RFC 6991: Common YANG Data Types";
+  }
+
+  organization
+    "IETF I2RS (Interface to the Routing System) Working Group";
+
+  contact
+    "WG Web:    <https://datatracker.ietf.org/wg/i2rs/>
+     WG List:   <mailto:i2rs@ietf.org>
+
+     Editor:    Alexander Clemm
+                <mailto:ludwig@clemm.org>
+
+     Editor:    Jan Medved
+                <mailto:jmedved@cisco.com>
+
+     Editor:    Robert Varga
+                <mailto:robert.varga@pantheon.tech>
+
+     Editor:    Nitin Bahadur
+                <mailto:nitin_bahadur@yahoo.com>
+
+     Editor:    Hariharan Ananthakrishnan
+                <mailto:hari@packetdesign.com>
+
+     Editor:    Xufeng Liu
+                <mailto:xufeng.liu.ietf@gmail.com>";
+  description
+    "This module defines a common base data model for a collection
+     of nodes in a network.  Node definitions are further used
+     in network topologies and inventories.
+
+     Copyright (c) 2018 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 8345;
+     see the RFC itself for full legal notices.";
+
+  revision 2018-02-26 {
+    description
+      "Initial revision.";
+    reference
+      "RFC 8345: A YANG Data Model for Network Topologies";
+  }
+
+  typedef node-id {
+    type inet:uri;
+    description
+      "Identifier for a node.  The precise structure of the node-id
+       will be up to the implementation.  For example, some
+       implementations MAY pick a URI that includes the network-id
+       as part of the path.  The identifier SHOULD be chosen
+       such that the same node in a real network topology will
+       always be identified through the same identifier, even if
+       the data model is instantiated in separate datastores.  An
+       implementation MAY choose to capture semantics in the
+       identifier -- for example, to indicate the type of node.";
+  }
+
+  typedef network-id {
+    type inet:uri;
+    description
+      "Identifier for a network.  The precise structure of the
+       network-id will be up to the implementation.  The identifier
+       SHOULD be chosen such that the same network will always be
+       identified through the same identifier, even if the data model
+       is instantiated in separate datastores.  An implementation MAY
+       choose to capture semantics in the identifier -- for example,
+       to indicate the type of network.";
+  }
+
+  grouping network-ref {
+    description
+      "Contains the information necessary to reference a network --
+       for example, an underlay network.";
+    leaf network-ref {
+      type leafref {
+        path "/nw:networks/nw:network/nw:network-id";
+      require-instance false;
+      }
+      description
+        "Used to reference a network -- for example, an underlay
+         network.";
+    }
+  }
+
+  grouping node-ref {
+    description
+      "Contains the information necessary to reference a node.";
+    leaf node-ref {
+      type leafref {
+        path "/nw:networks/nw:network[nw:network-id=current()/../"+
+          "network-ref]/nw:node/nw:node-id";
+        require-instance false;
+      }
+      description
+        "Used to reference a node.
+         Nodes are identified relative to the network that
+         contains them.";
+    }
+    uses network-ref;
+  }
+
+  container networks {
+    description
+      "Serves as a top-level container for a list of networks.";
+    list network {
+      key "network-id";
+      description
+        "Describes a network.
+         A network typically contains an inventory of nodes,
+         topological information (augmented through the
+         network-topology data model), and layering information.";
+      leaf network-id {
+        type network-id;
+        description
+          "Identifies a network.";
+      }
+      container network-types {
+        description
+          "Serves as an augmentation target.
+           The network type is indicated through corresponding
+           presence containers augmented into this container.";
+      }
+      list supporting-network {
+        key "network-ref";
+        description
+          "An underlay network, used to represent layered network
+           topologies.";
+        leaf network-ref {
+          type leafref {
+            path "/nw:networks/nw:network/nw:network-id";
+          require-instance false;
+          }
+          description
+            "References the underlay network.";
+        }
+      }
+
+      list node {
+        key "node-id";
+        description
+          "The inventory of nodes of this network.";
+        leaf node-id {
+          type node-id;
+          description
+            "Uniquely identifies a node within the containing
+             network.";
+        }
+        list supporting-node {
+          key "network-ref node-ref";
+          description
+            "Represents another node that is in an underlay network
+             and that supports this node.  Used to represent layering
+             structure.";
+          leaf network-ref {
+            type leafref {
+              path "../../../nw:supporting-network/nw:network-ref";
+            require-instance false;
+            }
+            description
+              "References the underlay network of which the
+               underlay node is a part.";
+          }
+          leaf node-ref {
+            type leafref {
+              path "/nw:networks/nw:network/nw:node/nw:node-id";
+            require-instance false;
+            }
+            description
+              "References the underlay node itself.";
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-packet-fields@2019-03-04.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-packet-fields@2019-03-04.yang
new file mode 100644
index 0000000000000000000000000000000000000000..2fb797bd87bf4ed825f83ec788df707b94c5f68b
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-packet-fields@2019-03-04.yang
@@ -0,0 +1,576 @@
+module ietf-packet-fields {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-packet-fields";
+  prefix packet-fields;
+
+  import ietf-inet-types {
+    prefix inet;
+    reference
+      "RFC 6991 - Common YANG Data Types.";
+  }
+
+  import ietf-yang-types {
+    prefix yang;
+    reference
+      "RFC 6991 - Common YANG Data Types.";
+  }
+
+  import ietf-ethertypes {
+    prefix eth;
+    reference
+      "RFC 8519 - YANG Data Model for Network Access Control
+                  Lists (ACLs).";
+  }
+
+  organization
+    "IETF NETMOD (Network Modeling) Working Group.";
+
+  contact
+    "WG Web:  <https://datatracker.ietf.org/wg/netmod/>
+     WG List: netmod@ietf.org
+
+     Editor: Mahesh Jethanandani
+             mjethanandani@gmail.com
+     Editor: Lisa Huang
+             huangyi_99@yahoo.com
+     Editor: Sonal Agarwal
+             sagarwal12@gmail.com
+     Editor: Dana Blair
+             dana@blairhome.com";
+
+  description
+    "This YANG module defines groupings that are used by
+     the ietf-access-control-list YANG module.  Their usage
+     is not limited to ietf-access-control-list and can be
+     used anywhere as applicable.
+
+     Copyright (c) 2019 IETF Trust and the persons identified as
+     the document authors.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD
+     License set forth in Section 4.c of the IETF Trust's Legal
+     Provisions Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 8519; see
+     the RFC itself for full legal notices.";
+
+  revision 2019-03-04 {
+    description
+      "Initial version.";
+    reference
+      "RFC 8519: YANG Data Model for Network Access Control
+                 Lists (ACLs).";
+  }
+
+  /*
+   * Typedefs
+   */
+  typedef operator {
+    type enumeration {
+      enum lte {
+        description
+          "Less than or equal to.";
+      }
+      enum gte {
+        description
+          "Greater than or equal to.";
+      }
+      enum eq {
+        description
+          "Equal to.";
+      }
+      enum neq {
+        description
+          "Not equal to.";
+      }
+    }
+    description
+      "The source and destination port range definitions
+       can be further qualified using an operator.  An
+       operator is needed only if the lower-port is specified
+       and the upper-port is not specified.  The operator
+       therefore further qualifies the lower-port only.";
+  }
+
+  /*
+   * Groupings
+   */
+  grouping port-range-or-operator {
+    choice port-range-or-operator {
+      case range {
+        leaf lower-port {
+          type inet:port-number;
+          must '. <= ../upper-port' {
+            error-message
+              "The lower-port must be less than or equal to
+               the upper-port.";
+          }
+          mandatory true;
+          description
+            "Lower boundary for a port.";
+        }
+        leaf upper-port {
+          type inet:port-number;
+          mandatory true;
+          description
+            "Upper boundary for a port.";
+        }
+      }
+      case operator {
+        leaf operator {
+          type operator;
+          default "eq";
+          description
+            "Operator to be applied on the port below.";
+        }
+        leaf port {
+          type inet:port-number;
+          mandatory true;
+          description
+            "Port number along with the operator on which to
+             match.";
+        }
+      }
+      description
+        "Choice of specifying a port range or a single
+         port along with an operator.";
+    }
+    description
+      "Grouping for port definitions in the form of a
+       choice statement.";
+  }
+
+  grouping acl-ip-header-fields {
+    description
+      "IP header fields common to IPv4 and IPv6";
+    reference
+      "RFC 791: Internet Protocol.";
+
+    leaf dscp {
+      type inet:dscp;
+      description
+        "Differentiated Services Code Point.";
+      reference
+        "RFC 2474: Definition of the Differentiated Services
+                   Field (DS Field) in the IPv4 and IPv6
+                   Headers.";
+    }
+
+    leaf ecn {
+      type uint8 {
+        range "0..3";
+      }
+      description
+        "Explicit Congestion Notification.";
+      reference
+        "RFC 3168: The Addition of Explicit Congestion
+                   Notification (ECN) to IP.";
+    }
+
+    leaf length {
+      type uint16;
+      description
+        "In the IPv4 header field, this field is known as the Total
+         Length.  Total Length is the length of the datagram, measured
+         in octets, including internet header and data.
+
+         In the IPv6 header field, this field is known as the Payload
+         Length, which is the length of the IPv6 payload, i.e., the rest
+         of the packet following the IPv6 header, in octets.";
+      reference
+        "RFC 791: Internet Protocol
+         RFC 8200: Internet Protocol, Version 6 (IPv6) Specification.";
+    }
+    leaf ttl {
+      type uint8;
+      description
+        "This field indicates the maximum time the datagram is allowed
+         to remain in the internet system.  If this field contains the
+         value zero, then the datagram must be dropped.
+
+         In IPv6, this field is known as the Hop Limit.";
+      reference
+        "RFC 791: Internet Protocol
+         RFC 8200: Internet Protocol, Version 6 (IPv6) Specification.";
+    }
+    leaf protocol {
+      type uint8;
+      description
+        "Internet Protocol number.  Refers to the protocol of the
+         payload.  In IPv6, this field is known as 'next-header',
+         and if extension headers are present, the protocol is
+         present in the 'upper-layer' header.";
+      reference
+        "RFC 791: Internet Protocol
+         RFC 8200: Internet Protocol, Version 6 (IPv6) Specification.";
+    }
+  }
+
+  grouping acl-ipv4-header-fields {
+    description
+      "Fields in the IPv4 header.";
+    leaf ihl {
+      type uint8 {
+        range "5..60";
+      }
+      description
+        "In an IPv4 header field, the Internet Header Length (IHL) is
+         the length of the internet header in 32-bit words and
+         thus points to the beginning of the data.  Note that the
+         minimum value for a correct header is 5.";
+    }
+    leaf flags {
+      type bits {
+        bit reserved {
+          position 0;
+          description
+            "Reserved.  Must be zero.";
+        }
+        bit fragment {
+          position 1;
+          description
+            "Setting the value to 0 indicates may fragment, while
+             setting the value to 1 indicates do not fragment.";
+        }
+        bit more {
+          position 2;
+          description
+            "Setting the value to 0 indicates this is the last fragment,
+             and setting the value to 1 indicates more fragments are
+             coming.";
+        }
+      }
+      description
+        "Bit definitions for the Flags field in the IPv4 header.";
+    }
+    leaf offset {
+      type uint16 {
+        range "20..65535";
+      }
+      description
+        "The fragment offset is measured in units of 8 octets (64 bits).
+         The first fragment has offset zero.  The length is 13 bits";
+    }
+    leaf identification {
+      type uint16;
+      description
+        "An identifying value assigned by the sender to aid in
+         assembling the fragments of a datagram.";
+    }
+
+    choice destination-network {
+      case destination-ipv4-network {
+        leaf destination-ipv4-network {
+          type inet:ipv4-prefix;
+          description
+            "Destination IPv4 address prefix.";
+        }
+      }
+      description
+        "Choice of specifying a destination IPv4 address or
+         referring to a group of IPv4 destination addresses.";
+    }
+
+    choice source-network {
+      case source-ipv4-network {
+        leaf source-ipv4-network {
+          type inet:ipv4-prefix;
+          description
+            "Source IPv4 address prefix.";
+        }
+      }
+      description
+        "Choice of specifying a source IPv4 address or
+         referring to a group of IPv4 source addresses.";
+    }
+  }
+
+  grouping acl-ipv6-header-fields {
+    description
+      "Fields in the IPv6 header.";
+
+    choice destination-network {
+      case destination-ipv6-network {
+        leaf destination-ipv6-network {
+          type inet:ipv6-prefix;
+          description
+            "Destination IPv6 address prefix.";
+        }
+      }
+      description
+        "Choice of specifying a destination IPv6 address
+         or referring to a group of IPv6 destination
+         addresses.";
+    }
+
+    choice source-network {
+      case source-ipv6-network {
+        leaf source-ipv6-network {
+          type inet:ipv6-prefix;
+          description
+            "Source IPv6 address prefix.";
+        }
+      }
+      description
+        "Choice of specifying a source IPv6 address or
+         referring to a group of IPv6 source addresses.";
+    }
+
+    leaf flow-label {
+      type inet:ipv6-flow-label;
+      description
+        "IPv6 Flow label.";
+    }
+    reference
+      "RFC 4291: IP Version 6 Addressing Architecture
+       RFC 4007: IPv6 Scoped Address Architecture
+       RFC 5952: A Recommendation for IPv6 Address Text
+                 Representation.";
+  }
+
+  grouping acl-eth-header-fields {
+    description
+      "Fields in the Ethernet header.";
+    leaf destination-mac-address {
+      type yang:mac-address;
+      description
+        "Destination IEEE 802 Media Access Control (MAC)
+         address.";
+    }
+    leaf destination-mac-address-mask {
+      type yang:mac-address;
+      description
+        "Destination IEEE 802 MAC address mask.";
+    }
+    leaf source-mac-address {
+      type yang:mac-address;
+      description
+        "Source IEEE 802 MAC address.";
+    }
+    leaf source-mac-address-mask {
+      type yang:mac-address;
+      description
+        "Source IEEE 802 MAC address mask.";
+    }
+    leaf ethertype {
+      type eth:ethertype;
+      description
+        "The Ethernet Type (or Length) value represented
+         in the canonical order defined by IEEE 802.
+         The canonical representation uses lowercase
+         characters.";
+      reference
+        "IEEE 802-2014, Clause 9.2.";
+    }
+    reference
+      "IEEE 802: IEEE Standard for Local and Metropolitan
+       Area Networks: Overview and Architecture.";
+  }
+
+  grouping acl-tcp-header-fields {
+    description
+      "Collection of TCP header fields that can be used to
+       set up a match filter.";
+    leaf sequence-number {
+      type uint32;
+      description
+        "Sequence number that appears in the packet.";
+    }
+    leaf acknowledgement-number {
+      type uint32;
+      description
+        "The acknowledgement number that appears in the
+         packet.";
+    }
+    leaf data-offset {
+      type uint8 {
+        range "5..15";
+      }
+      description
+        "Specifies the size of the TCP header in 32-bit
+         words.  The minimum size header is 5 words and
+         the maximum is 15 words; thus, this gives a
+         minimum size of 20 bytes and a maximum of 60
+         bytes, allowing for up to 40 bytes of options
+         in the header.";
+    }
+    leaf reserved {
+      type uint8;
+      description
+        "Reserved for future use.";
+    }
+    leaf flags {
+      type bits {
+        bit cwr {
+          position 1;
+          description
+            "The Congestion Window Reduced (CWR) flag is set
+             by the sending host to indicate that it received
+             a TCP segment with the ECN-Echo (ECE) flag set
+             and had responded in the congestion control
+             mechanism.";
+          reference
+            "RFC 3168: The Addition of Explicit Congestion
+                       Notification (ECN) to IP.";
+        }
+        bit ece {
+          position 2;
+          description
+            "ECN-Echo has a dual role, depending on the value
+             of the SYN flag.  It indicates the following: if
+             the SYN flag is set (1), the TCP peer is ECN
+             capable, and if the SYN flag is clear (0), a packet
+             with the Congestion Experienced flag set (ECN=11)
+             in the IP header was received during normal
+             transmission (added to the header by RFC 3168).
+             This serves as an indication of network congestion
+             (or impending congestion) to the TCP sender.";
+          reference
+            "RFC 3168: The Addition of Explicit Congestion
+                       Notification (ECN) to IP.";
+        }
+        bit urg {
+          position 3;
+          description
+            "Indicates that the Urgent Pointer field is significant.";
+        }
+        bit ack {
+          position 4;
+          description
+            "Indicates that the Acknowledgement field is significant.
+             All packets after the initial SYN packet sent by the
+             client should have this flag set.";
+        }
+        bit psh {
+          position 5;
+          description
+            "Push function.  Asks to push the buffered data to the
+             receiving application.";
+        }
+        bit rst {
+          position 6;
+          description
+            "Reset the connection.";
+        }
+        bit syn {
+          position 7;
+          description
+            "Synchronize sequence numbers.  Only the first packet
+             sent from each end should have this flag set.  Some
+             other flags and fields change meaning based on this
+             flag, and some are only valid for when it is set,
+             and others when it is clear.";
+        }
+        bit fin {
+          position 8;
+          description
+            "Last package from the sender.";
+        }
+      }
+      description
+        "Also known as Control Bits.  Contains nine 1-bit flags.";
+      reference
+        "RFC 793: Transmission Control Protocol.";
+    }
+    leaf window-size {
+      type uint16;
+      units "bytes";
+      description
+        "The size of the receive window, which specifies
+         the number of window size units beyond the segment
+         identified by the sequence number in the Acknowledgement
+         field that the sender of this segment is currently
+         willing to receive.";
+    }
+    leaf urgent-pointer {
+      type uint16;
+      description
+        "This field is an offset from the sequence number
+         indicating the last urgent data byte.";
+    }
+    leaf options {
+      type binary {
+        length "1..40";
+      }
+      description
+        "The length of this field is determined by the
+         Data Offset field.  Options have up to three
+         fields: Option-Kind (1 byte), Option-Length
+         (1 byte), and Option-Data (variable).  The Option-Kind
+         field indicates the type of option and is the
+         only field that is not optional.  Depending on
+         what kind of option we are dealing with,
+         the next two fields may be set: the Option-Length
+         field indicates the total length of the option,
+         and the Option-Data field contains the value of
+         the option, if applicable.";
+    }
+  }
+
+  grouping acl-udp-header-fields {
+    description
+      "Collection of UDP header fields that can be used
+       to set up a match filter.";
+    leaf length {
+      type uint16;
+      description
+        "A field that specifies the length in bytes of
+         the UDP header and UDP data.  The minimum
+         length is 8 bytes because that is the length of
+         the header.  The field size sets a theoretical
+         limit of 65,535 bytes (8-byte header plus 65,527
+         bytes of data) for a UDP datagram.  However, the
+         actual limit for the data length, which is
+         imposed by the underlying IPv4 protocol, is
+         65,507 bytes (65,535 minus 8-byte UDP header
+         minus 20-byte IP header).
+
+         In IPv6 jumbograms, it is possible to have
+         UDP packets of a size greater than 65,535 bytes.
+         RFC 2675 specifies that the Length field is set
+         to zero if the length of the UDP header plus
+         UDP data is greater than 65,535.";
+    }
+  }
+
+  grouping acl-icmp-header-fields {
+    description
+      "Collection of ICMP header fields that can be
+       used to set up a match filter.";
+    leaf type {
+      type uint8;
+      description
+        "Also known as control messages.";
+      reference
+        "RFC 792: Internet Control Message Protocol
+         RFC 4443: Internet Control Message Protocol (ICMPv6)
+                   for Internet Protocol Version 6 (IPv6)
+                   Specification.";
+    }
+    leaf code {
+      type uint8;
+      description
+        "ICMP subtype.  Also known as control messages.";
+      reference
+        "RFC 792: Internet Control Message Protocol
+         RFC 4443: Internet Control Message Protocol (ICMPv6)
+                   for Internet Protocol Version 6 (IPv6)
+                   Specification.";
+    }
+    leaf rest-of-header {
+      type binary;
+      description
+        "Unbounded in length, the contents vary based on the
+         ICMP type and code.  Also referred to as 'Message Body'
+         in ICMPv6.";
+      reference
+        "RFC 792: Internet Control Message Protocol
+         RFC 4443: Internet Control Message Protocol (ICMPv6)
+                   for Internet Protocol Version 6 (IPv6)
+                   Specification.";
+    }
+  }
+}
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-routing-types@2017-12-04.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-routing-types@2017-12-04.yang
new file mode 100644
index 0000000000000000000000000000000000000000..24319c155fb104e20bee79e5b257317b01323197
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-routing-types@2017-12-04.yang
@@ -0,0 +1,771 @@
+module ietf-routing-types {
+  namespace "urn:ietf:params:xml:ns:yang:ietf-routing-types";
+  prefix rt-types;
+
+  import ietf-yang-types {
+    prefix yang;
+  }
+  import ietf-inet-types {
+    prefix inet;
+  }
+
+  organization
+    "IETF RTGWG - Routing Area Working Group";
+  contact
+    "WG Web:   <https://datatracker.ietf.org/wg/rtgwg/>
+     WG List:  <mailto:rtgwg@ietf.org>
+
+     Editors:  Xufeng Liu
+               <mailto:Xufeng_Liu@jabail.com>
+               Yingzhen Qu
+               <mailto:yingzhen.qu@huawei.com>
+               Acee Lindem
+               <mailto:acee@cisco.com>
+               Christian Hopps
+               <mailto:chopps@chopps.org>
+               Lou Berger
+               <mailto:lberger@labn.com>";
+
+  description
+    "This module contains a collection of YANG data types
+     considered generally useful for routing protocols.
+
+     Copyright (c) 2017 IETF Trust and the persons
+     identified as authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 8294; see
+     the RFC itself for full legal notices.";
+   revision 2017-12-04 {
+     description "Initial revision.";
+     reference
+       "RFC 8294: Common YANG Data Types for the Routing Area.
+        Section 3.";
+  }
+
+  /*** Identities related to MPLS/GMPLS ***/
+
+  identity mpls-label-special-purpose-value {
+    description
+      "Base identity for deriving identities describing
+       special-purpose Multiprotocol Label Switching (MPLS) label
+       values.";
+    reference
+      "RFC 7274: Allocating and Retiring Special-Purpose MPLS
+       Labels.";
+  }
+
+  identity ipv4-explicit-null-label {
+    base mpls-label-special-purpose-value;
+    description
+      "This identity represents the IPv4 Explicit NULL Label.";
+    reference
+      "RFC 3032: MPLS Label Stack Encoding.  Section 2.1.";
+  }
+
+  identity router-alert-label {
+    base mpls-label-special-purpose-value;
+    description
+      "This identity represents the Router Alert Label.";
+    reference
+      "RFC 3032: MPLS Label Stack Encoding.  Section 2.1.";
+  }
+
+  identity ipv6-explicit-null-label {
+    base mpls-label-special-purpose-value;
+    description
+      "This identity represents the IPv6 Explicit NULL Label.";
+    reference
+      "RFC 3032: MPLS Label Stack Encoding.  Section 2.1.";
+  }
+
+  identity implicit-null-label {
+    base mpls-label-special-purpose-value;
+    description
+      "This identity represents the Implicit NULL Label.";
+    reference
+      "RFC 3032: MPLS Label Stack Encoding.  Section 2.1.";
+  }
+
+  identity entropy-label-indicator {
+    base mpls-label-special-purpose-value;
+    description
+      "This identity represents the Entropy Label Indicator.";
+    reference
+      "RFC 6790: The Use of Entropy Labels in MPLS Forwarding.
+       Sections 3 and 10.1.";
+  }
+
+  identity gal-label {
+    base mpls-label-special-purpose-value;
+    description
+      "This identity represents the Generic Associated Channel
+       (G-ACh) Label (GAL).";
+    reference
+      "RFC 5586: MPLS Generic Associated Channel.
+       Sections 4 and 10.";
+  }
+
+  identity oam-alert-label {
+    base mpls-label-special-purpose-value;
+    description
+      "This identity represents the OAM Alert Label.";
+    reference
+      "RFC 3429: Assignment of the 'OAM Alert Label' for
+       Multiprotocol Label Switching Architecture (MPLS)
+       Operation and Maintenance (OAM) Functions.
+       Sections 3 and 6.";
+  }
+
+  identity extension-label {
+    base mpls-label-special-purpose-value;
+    description
+      "This identity represents the Extension Label.";
+    reference
+      "RFC 7274: Allocating and Retiring Special-Purpose MPLS
+       Labels.  Sections 3.1 and 5.";
+  }
+
+  /*** Collection of types related to routing ***/
+
+  typedef router-id {
+    type yang:dotted-quad;
+    description
+      "A 32-bit number in the dotted-quad format assigned to each
+       router.  This number uniquely identifies the router within
+       an Autonomous System.";
+  }
+
+  /*** Collection of types related to VPNs ***/
+
+  typedef route-target {
+    type string {
+      pattern
+        '(0:(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|'
+      +     '6[0-4][0-9]{3}|'
+      +     '[1-5][0-9]{4}|[1-9][0-9]{0,3}|0):(429496729[0-5]|'
+      +     '42949672[0-8][0-9]|'
+      +     '4294967[01][0-9]{2}|429496[0-6][0-9]{3}|'
+      +     '42949[0-5][0-9]{4}|'
+      +     '4294[0-8][0-9]{5}|429[0-3][0-9]{6}|'
+      +     '42[0-8][0-9]{7}|4[01][0-9]{8}|'
+      +     '[1-3][0-9]{9}|[1-9][0-9]{0,8}|0))|'
+      + '(1:((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|'
+      +     '25[0-5])\.){3}([0-9]|[1-9][0-9]|'
+      +     '1[0-9]{2}|2[0-4][0-9]|25[0-5])):(6553[0-5]|'
+      +     '655[0-2][0-9]|'
+      +     '65[0-4][0-9]{2}|6[0-4][0-9]{3}|'
+      +     '[1-5][0-9]{4}|[1-9][0-9]{0,3}|0))|'
+      + '(2:(429496729[0-5]|42949672[0-8][0-9]|'
+      +     '4294967[01][0-9]{2}|'
+      +     '429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|'
+      +     '4294[0-8][0-9]{5}|'
+      +     '429[0-3][0-9]{6}|42[0-8][0-9]{7}|4[01][0-9]{8}|'
+      +     '[1-3][0-9]{9}|[1-9][0-9]{0,8}|0):'
+      +     '(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|'
+      +     '6[0-4][0-9]{3}|'
+      +     '[1-5][0-9]{4}|[1-9][0-9]{0,3}|0))|'
+      + '(6(:[a-fA-F0-9]{2}){6})|'
+      + '(([3-57-9a-fA-F]|[1-9a-fA-F][0-9a-fA-F]{1,3}):'
+      +     '[0-9a-fA-F]{1,12})';
+    }
+
+    description
+      "A Route Target is an 8-octet BGP extended community
+       initially identifying a set of sites in a BGP VPN
+       (RFC 4364).  However, it has since taken on a more general
+       role in BGP route filtering.  A Route Target consists of two
+       or three fields: a 2-octet Type field, an administrator
+       field, and, optionally, an assigned number field.
+
+       According to the data formats for types 0, 1, 2, and 6 as
+       defined in RFC 4360, RFC 5668, and RFC 7432, the encoding
+       pattern is defined as:
+
+       0:2-octet-asn:4-octet-number
+       1:4-octet-ipv4addr:2-octet-number
+       2:4-octet-asn:2-octet-number
+       6:6-octet-mac-address
+
+       Additionally, a generic pattern is defined for future
+       Route Target types:
+
+       2-octet-other-hex-number:6-octet-hex-number
+
+       Some valid examples are 0:100:100, 1:1.1.1.1:100,
+       2:1234567890:203, and 6:26:00:08:92:78:00.";
+    reference
+      "RFC 4360: BGP Extended Communities Attribute.
+       RFC 4364: BGP/MPLS IP Virtual Private Networks (VPNs).
+       RFC 5668: 4-Octet AS Specific BGP Extended Community.
+       RFC 7432: BGP MPLS-Based Ethernet VPN.";
+  }
+
+  typedef ipv6-route-target {
+    type string {
+      pattern
+          '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+          + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+          + '(((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}'
+          + '(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])))'
+          + ':'
+          + '(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|'
+          + '6[0-4][0-9]{3}|'
+          + '[1-5][0-9]{4}|[1-9][0-9]{0,3}|0)';
+      pattern '((([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+          + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?))'
+          + ':'
+          + '(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|'
+          + '6[0-4][0-9]{3}|'
+          + '[1-5][0-9]{4}|[1-9][0-9]{0,3}|0)';
+    }
+    description
+      "An IPv6 Route Target is a 20-octet BGP IPv6 Address
+       Specific Extended Community serving the same function
+       as a standard 8-octet Route Target, except that it only
+       allows an IPv6 address as the global administrator.
+       The format is <ipv6-address:2-octet-number>.
+
+       Two valid examples are 2001:db8::1:6544 and
+       2001:db8::5eb1:791:6b37:17958.";
+    reference
+      "RFC 5701: IPv6 Address Specific BGP Extended Community
+       Attribute.";
+  }
+
+  typedef route-target-type {
+    type enumeration {
+      enum import {
+        value 0;
+        description
+          "The Route Target applies to route import.";
+      }
+      enum export {
+        value 1;
+        description
+          "The Route Target applies to route export.";
+      }
+
+      enum both {
+        value 2;
+        description
+          "The Route Target applies to both route import and
+           route export.";
+      }
+    }
+    description
+      "Indicates the role a Route Target takes in route filtering.";
+    reference
+      "RFC 4364: BGP/MPLS IP Virtual Private Networks (VPNs).";
+  }
+
+  typedef route-distinguisher {
+    type string {
+      pattern
+        '(0:(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|'
+      +     '6[0-4][0-9]{3}|'
+      +     '[1-5][0-9]{4}|[1-9][0-9]{0,3}|0):(429496729[0-5]|'
+      +     '42949672[0-8][0-9]|'
+      +     '4294967[01][0-9]{2}|429496[0-6][0-9]{3}|'
+      +     '42949[0-5][0-9]{4}|'
+      +     '4294[0-8][0-9]{5}|429[0-3][0-9]{6}|'
+      +     '42[0-8][0-9]{7}|4[01][0-9]{8}|'
+      +     '[1-3][0-9]{9}|[1-9][0-9]{0,8}|0))|'
+      + '(1:((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|'
+      +     '25[0-5])\.){3}([0-9]|[1-9][0-9]|'
+      +     '1[0-9]{2}|2[0-4][0-9]|25[0-5])):(6553[0-5]|'
+      +     '655[0-2][0-9]|'
+      +     '65[0-4][0-9]{2}|6[0-4][0-9]{3}|'
+      +     '[1-5][0-9]{4}|[1-9][0-9]{0,3}|0))|'
+      + '(2:(429496729[0-5]|42949672[0-8][0-9]|'
+      +     '4294967[01][0-9]{2}|'
+      +     '429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|'
+      +     '4294[0-8][0-9]{5}|'
+      +     '429[0-3][0-9]{6}|42[0-8][0-9]{7}|4[01][0-9]{8}|'
+      +     '[1-3][0-9]{9}|[1-9][0-9]{0,8}|0):'
+      +     '(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|'
+      +     '6[0-4][0-9]{3}|'
+      +     '[1-5][0-9]{4}|[1-9][0-9]{0,3}|0))|'
+      + '(6(:[a-fA-F0-9]{2}){6})|'
+      + '(([3-57-9a-fA-F]|[1-9a-fA-F][0-9a-fA-F]{1,3}):'
+      +     '[0-9a-fA-F]{1,12})';
+    }
+
+    description
+      "A Route Distinguisher is an 8-octet value used to
+       distinguish routes from different BGP VPNs (RFC 4364).
+       A Route Distinguisher will have the same format as a
+       Route Target as per RFC 4360 and will consist of
+       two or three fields: a 2-octet Type field, an administrator
+       field, and, optionally, an assigned number field.
+
+       According to the data formats for types 0, 1, 2, and 6 as
+       defined in RFC 4360, RFC 5668, and RFC 7432, the encoding
+       pattern is defined as:
+
+       0:2-octet-asn:4-octet-number
+       1:4-octet-ipv4addr:2-octet-number
+       2:4-octet-asn:2-octet-number
+       6:6-octet-mac-address
+
+       Additionally, a generic pattern is defined for future
+       route discriminator types:
+
+       2-octet-other-hex-number:6-octet-hex-number
+
+       Some valid examples are 0:100:100, 1:1.1.1.1:100,
+       2:1234567890:203, and 6:26:00:08:92:78:00.";
+    reference
+      "RFC 4360: BGP Extended Communities Attribute.
+       RFC 4364: BGP/MPLS IP Virtual Private Networks (VPNs).
+       RFC 5668: 4-Octet AS Specific BGP Extended Community.
+       RFC 7432: BGP MPLS-Based Ethernet VPN.";
+  }
+
+  typedef route-origin {
+    type string {
+      pattern
+        '(0:(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|'
+      +     '6[0-4][0-9]{3}|'
+      +     '[1-5][0-9]{4}|[1-9][0-9]{0,3}|0):(429496729[0-5]|'
+      +     '42949672[0-8][0-9]|'
+      +     '4294967[01][0-9]{2}|429496[0-6][0-9]{3}|'
+      +     '42949[0-5][0-9]{4}|'
+      +     '4294[0-8][0-9]{5}|429[0-3][0-9]{6}|'
+      +     '42[0-8][0-9]{7}|4[01][0-9]{8}|'
+      +     '[1-3][0-9]{9}|[1-9][0-9]{0,8}|0))|'
+      + '(1:((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|'
+      +     '25[0-5])\.){3}([0-9]|[1-9][0-9]|'
+      +     '1[0-9]{2}|2[0-4][0-9]|25[0-5])):(6553[0-5]|'
+      +     '655[0-2][0-9]|'
+      +     '65[0-4][0-9]{2}|6[0-4][0-9]{3}|'
+      +     '[1-5][0-9]{4}|[1-9][0-9]{0,3}|0))|'
+      + '(2:(429496729[0-5]|42949672[0-8][0-9]|'
+      +     '4294967[01][0-9]{2}|'
+      +     '429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|'
+      +     '4294[0-8][0-9]{5}|'
+      +     '429[0-3][0-9]{6}|42[0-8][0-9]{7}|4[01][0-9]{8}|'
+      +     '[1-3][0-9]{9}|[1-9][0-9]{0,8}|0):'
+      +     '(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|'
+      +     '6[0-4][0-9]{3}|'
+      +     '[1-5][0-9]{4}|[1-9][0-9]{0,3}|0))|'
+      + '(6(:[a-fA-F0-9]{2}){6})|'
+      + '(([3-57-9a-fA-F]|[1-9a-fA-F][0-9a-fA-F]{1,3}):'
+      +    '[0-9a-fA-F]{1,12})';
+    }
+    description
+      "A Route Origin is an 8-octet BGP extended community
+       identifying the set of sites where the BGP route
+       originated (RFC 4364).  A Route Origin will have the same
+       format as a Route Target as per RFC 4360 and will consist
+       of two or three fields: a 2-octet Type field, an
+       administrator field, and, optionally, an assigned number
+       field.
+
+       According to the data formats for types 0, 1, 2, and 6 as
+       defined in RFC 4360, RFC 5668, and RFC 7432, the encoding
+       pattern is defined as:
+
+       0:2-octet-asn:4-octet-number
+       1:4-octet-ipv4addr:2-octet-number
+       2:4-octet-asn:2-octet-number
+       6:6-octet-mac-address
+       Additionally, a generic pattern is defined for future
+       Route Origin types:
+
+       2-octet-other-hex-number:6-octet-hex-number
+
+       Some valid examples are 0:100:100, 1:1.1.1.1:100,
+       2:1234567890:203, and 6:26:00:08:92:78:00.";
+    reference
+      "RFC 4360: BGP Extended Communities Attribute.
+       RFC 4364: BGP/MPLS IP Virtual Private Networks (VPNs).
+       RFC 5668: 4-Octet AS Specific BGP Extended Community.
+       RFC 7432: BGP MPLS-Based Ethernet VPN.";
+  }
+
+  typedef ipv6-route-origin {
+    type string {
+      pattern
+          '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+          + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+          + '(((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}'
+          + '(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])))'
+          + ':'
+          + '(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|'
+          + '6[0-4][0-9]{3}|'
+          + '[1-5][0-9]{4}|[1-9][0-9]{0,3}|0)';
+      pattern '((([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+          + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?))'
+          + ':'
+          + '(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|'
+          + '6[0-4][0-9]{3}|'
+          + '[1-5][0-9]{4}|[1-9][0-9]{0,3}|0)';
+    }
+    description
+      "An IPv6 Route Origin is a 20-octet BGP IPv6 Address
+       Specific Extended Community serving the same function
+       as a standard 8-octet route, except that it only allows
+       an IPv6 address as the global administrator.  The format
+       is <ipv6-address:2-octet-number>.
+
+       Two valid examples are 2001:db8::1:6544 and
+       2001:db8::5eb1:791:6b37:17958.";
+    reference
+      "RFC 5701: IPv6 Address Specific BGP Extended Community
+       Attribute.";
+  }
+
+  /*** Collection of types common to multicast ***/
+
+  typedef ipv4-multicast-group-address {
+    type inet:ipv4-address {
+      pattern '(2((2[4-9])|(3[0-9]))\.).*';
+    }
+    description
+      "This type represents an IPv4 multicast group address,
+       which is in the range of 224.0.0.0 to 239.255.255.255.";
+    reference
+      "RFC 1112: Host Extensions for IP Multicasting.";
+  }
+
+  typedef ipv6-multicast-group-address {
+    type inet:ipv6-address {
+      pattern '(([fF]{2}[0-9a-fA-F]{2}):).*';
+    }
+    description
+      "This type represents an IPv6 multicast group address,
+       which is in the range of ff00::/8.";
+    reference
+      "RFC 4291: IP Version 6 Addressing Architecture.  Section 2.7.
+       RFC 7346: IPv6 Multicast Address Scopes.";
+  }
+
+  typedef ip-multicast-group-address {
+    type union {
+      type ipv4-multicast-group-address;
+      type ipv6-multicast-group-address;
+    }
+    description
+      "This type represents a version-neutral IP multicast group
+       address.  The format of the textual representation implies
+       the IP version.";
+  }
+
+  typedef ipv4-multicast-source-address {
+    type union {
+      type enumeration {
+        enum * {
+          description
+            "Any source address.";
+        }
+      }
+      type inet:ipv4-address;
+    }
+    description
+      "Multicast source IPv4 address type.";
+  }
+
+  typedef ipv6-multicast-source-address {
+    type union {
+      type enumeration {
+        enum * {
+          description
+            "Any source address.";
+        }
+      }
+      type inet:ipv6-address;
+    }
+    description
+      "Multicast source IPv6 address type.";
+  }
+
+  /*** Collection of types common to protocols ***/
+
+  typedef bandwidth-ieee-float32 {
+    type string {
+      pattern
+        '0[xX](0((\.0?)?[pP](\+)?0?|(\.0?))|'
+      + '1(\.([0-9a-fA-F]{0,5}[02468aAcCeE]?)?)?[pP](\+)?(12[0-7]|'
+      + '1[01][0-9]|0?[0-9]?[0-9])?)';
+    }
+    description
+      "Bandwidth in IEEE 754 floating-point 32-bit binary format:
+       (-1)**(S) * 2**(Exponent-127) * (1 + Fraction),
+       where Exponent uses 8 bits and Fraction uses 23 bits.
+       The units are octets per second.
+       The encoding format is the external hexadecimal-significant
+       character sequences specified in IEEE 754 and ISO/IEC C99.
+       The format is restricted to be normalized, non-negative, and
+       non-fraction: 0x1.hhhhhhp{+}d, 0X1.HHHHHHP{+}D, or 0x0p0,
+       where 'h' and 'H' are hexadecimal digits and 'd' and 'D' are
+       integers in the range of [0..127].
+       When six hexadecimal digits are used for 'hhhhhh' or
+       'HHHHHH', the least significant digit must be an even
+       number.  'x' and 'X' indicate hexadecimal; 'p' and 'P'
+       indicate a power of two.  Some examples are 0x0p0, 0x1p10,
+       and 0x1.abcde2p+20.";
+    reference
+      "IEEE Std 754-2008: IEEE Standard for Floating-Point
+       Arithmetic.
+       ISO/IEC C99: Information technology - Programming
+       Languages - C.";
+  }
+
+  typedef link-access-type {
+    type enumeration {
+      enum broadcast {
+        description
+          "Specify broadcast multi-access network.";
+      }
+      enum non-broadcast-multiaccess {
+        description
+          "Specify Non-Broadcast Multi-Access (NBMA) network.";
+      }
+      enum point-to-multipoint {
+        description
+          "Specify point-to-multipoint network.";
+      }
+      enum point-to-point {
+        description
+          "Specify point-to-point network.";
+      }
+    }
+    description
+      "Link access type.";
+  }
+
+  typedef timer-multiplier {
+    type uint8;
+    description
+      "The number of timer value intervals that should be
+       interpreted as a failure.";
+  }
+
+  typedef timer-value-seconds16 {
+    type union {
+      type uint16 {
+        range "1..65535";
+      }
+      type enumeration {
+        enum infinity {
+          description
+            "The timer is set to infinity.";
+        }
+        enum not-set {
+          description
+            "The timer is not set.";
+        }
+      }
+    }
+    units "seconds";
+    description
+      "Timer value type, in seconds (16-bit range).";
+  }
+
+  typedef timer-value-seconds32 {
+    type union {
+      type uint32 {
+        range "1..4294967295";
+      }
+      type enumeration {
+        enum infinity {
+          description
+            "The timer is set to infinity.";
+        }
+        enum not-set {
+          description
+            "The timer is not set.";
+        }
+      }
+    }
+    units "seconds";
+    description
+      "Timer value type, in seconds (32-bit range).";
+  }
+
+  typedef timer-value-milliseconds {
+    type union {
+      type uint32 {
+        range "1..4294967295";
+      }
+      type enumeration {
+        enum infinity {
+          description
+            "The timer is set to infinity.";
+        }
+        enum not-set {
+          description
+            "The timer is not set.";
+        }
+      }
+    }
+    units "milliseconds";
+    description
+      "Timer value type, in milliseconds.";
+  }
+
+  typedef percentage {
+    type uint8 {
+      range "0..100";
+    }
+    description
+      "Integer indicating a percentage value.";
+  }
+
+  typedef timeticks64 {
+    type uint64;
+    description
+      "This type is based on the timeticks type defined in
+       RFC 6991, but with 64-bit width.  It represents the time,
+       modulo 2^64, in hundredths of a second between two epochs.";
+    reference
+      "RFC 6991: Common YANG Data Types.";
+  }
+
+  typedef uint24 {
+    type uint32 {
+      range "0..16777215";
+    }
+    description
+      "24-bit unsigned integer.";
+  }
+
+  /*** Collection of types related to MPLS/GMPLS ***/
+
+  typedef generalized-label {
+    type binary;
+    description
+      "Generalized Label.  Nodes sending and receiving the
+       Generalized Label are aware of the link-specific
+       label context and type.";
+    reference
+      "RFC 3471: Generalized Multi-Protocol Label Switching (GMPLS)
+       Signaling Functional Description.  Section 3.2.";
+  }
+
+  typedef mpls-label-special-purpose {
+    type identityref {
+      base mpls-label-special-purpose-value;
+    }
+    description
+      "This type represents the special-purpose MPLS label values.";
+    reference
+      "RFC 3032: MPLS Label Stack Encoding.
+       RFC 7274: Allocating and Retiring Special-Purpose MPLS
+       Labels.";
+  }
+
+  typedef mpls-label-general-use {
+    type uint32 {
+      range "16..1048575";
+    }
+    description
+      "The 20-bit label value in an MPLS label stack as specified
+       in RFC 3032.  This label value does not include the
+       encodings of Traffic Class and TTL (Time to Live).
+       The label range specified by this type is for general use,
+       with special-purpose MPLS label values excluded.";
+    reference
+      "RFC 3032: MPLS Label Stack Encoding.";
+  }
+
+  typedef mpls-label {
+    type union {
+      type mpls-label-special-purpose;
+      type mpls-label-general-use;
+    }
+    description
+      "The 20-bit label value in an MPLS label stack as specified
+       in RFC 3032.  This label value does not include the
+       encodings of Traffic Class and TTL.";
+    reference
+      "RFC 3032: MPLS Label Stack Encoding.";
+  }
+
+  /*** Groupings **/
+
+  grouping mpls-label-stack {
+    description
+      "This grouping specifies an MPLS label stack.  The label
+       stack is encoded as a list of label stack entries.  The
+       list key is an identifier that indicates the relative
+       ordering of each entry, with the lowest-value identifier
+       corresponding to the top of the label stack.";
+    container mpls-label-stack {
+      description
+        "Container for a list of MPLS label stack entries.";
+      list entry {
+        key "id";
+        description
+          "List of MPLS label stack entries.";
+        leaf id {
+          type uint8;
+          description
+            "Identifies the entry in a sequence of MPLS label
+             stack entries.  An entry with a smaller identifier
+             value precedes an entry with a larger identifier
+             value in the label stack.  The value of this ID has
+             no semantic meaning other than relative ordering
+             and referencing the entry.";
+        }
+        leaf label {
+          type rt-types:mpls-label;
+          description
+            "Label value.";
+        }
+
+        leaf ttl {
+          type uint8;
+          description
+            "Time to Live (TTL).";
+          reference
+            "RFC 3032: MPLS Label Stack Encoding.";
+        }
+        leaf traffic-class {
+          type uint8 {
+            range "0..7";
+          }
+          description
+            "Traffic Class (TC).";
+          reference
+            "RFC 5462: Multiprotocol Label Switching (MPLS) Label
+             Stack Entry: 'EXP' Field Renamed to 'Traffic Class'
+             Field.";
+        }
+      }
+    }
+  }
+
+  grouping vpn-route-targets {
+    description
+      "A grouping that specifies Route Target import-export rules
+       used in BGP-enabled VPNs.";
+    reference
+      "RFC 4364: BGP/MPLS IP Virtual Private Networks (VPNs).
+       RFC 4664: Framework for Layer 2 Virtual Private Networks
+       (L2VPNs).";
+    list vpn-target {
+      key "route-target";
+      description
+        "List of Route Targets.";
+      leaf route-target {
+        type rt-types:route-target;
+        description
+          "Route Target value.";
+      }
+      leaf route-target-type {
+        type rt-types:route-target-type;
+        mandatory true;
+        description
+          "Import/export type of the Route Target.";
+      }
+    }
+  }
+}
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-te-packet-types@2024-10-30.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-te-packet-types@2024-10-30.yang
new file mode 100644
index 0000000000000000000000000000000000000000..70bead463820694c7f88c977f8ef28df0bb3db7a
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-te-packet-types@2024-10-30.yang
@@ -0,0 +1,806 @@
+module ietf-te-packet-types {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-te-packet-types";
+  prefix te-packet-types;
+
+  import ietf-yang-types {
+    prefix yang;
+    reference
+      "RFC 6991: Common YANG Data Types";
+  }
+
+  import ietf-te-types {
+    prefix te-types;
+    reference
+      "RFC XXXX: Common YANG Data Types for Traffic Engineering";
+  }
+  // RFC Editor: replace XXXX with actual RFC number
+  // and remove this note
+
+  organization
+    "IETF Traffic Engineering Architecture and Signaling (TEAS)
+     Working Group";
+  contact
+    "WG Web:   <https://datatracker.ietf.org/wg/teas/>
+     WG List:  <mailto:teas@ietf.org>
+
+     Editor:   Tarek Saad
+               <mailto:tsaad.net@gmail.com>
+
+     Editor:   Rakesh Gandhi
+               <mailto:rgandhi@cisco.com>
+
+     Editor:   Vishnu Pavan Beeram
+               <mailto:vbeeram@juniper.net>
+
+     Editor:   Xufeng Liu
+               <mailto:xufeng.liu.ietf@gmail.com>
+
+     Editor:   Igor Bryskin
+               <mailto:i_bryskin@yahoo.com>";
+  description
+    "This YANG module contains a collection of generally useful YANG
+     data type definitions specific to Packet Traffic Enginnering
+     (TE).
+
+     The model fully conforms to the Network Management Datastore
+     Architecture (NMDA).
+
+     The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL
+     NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED',
+     'MAY', and 'OPTIONAL' in this document are to be interpreted as
+     described in BCP 14 (RFC 2119) (RFC 8174) when, and only when,
+     they appear in all capitals, as shown here.
+
+     Copyright (c) 2024 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject to
+     the license terms contained in, the Revised BSD License set
+     forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC XXXX
+     (https://www.rfc-editor.org/info/rfcXXXX); see the RFC itself
+     for full legal notices.";
+  revision 2024-10-30 {
+    description
+      "This revision adds the following new identities:
+       - bandwidth-profile-type;
+       - link-metric-delay-variation;
+       - link-metric-loss;
+       - path-metric-delay-variation;
+       - path-metric-loss.
+
+      This revision adds the following new groupings:
+       - bandwidth-profile-parameters;
+       - te-packet-path-bandwidth;
+       - te-packet-link-bandwidth.
+
+      This revision provides also few editorial changes.";
+    reference
+      "RFC XXXX: Common YANG Data Types for Traffic Engineering";
+  }
+  // RFC Editor: replace XXXX with actual RFC number, update date
+  // information and remove this note
+
+  revision 2020-06-10 {
+    description
+      "Latest revision of TE MPLS types.";
+    reference
+      "RFC 8776: Common YANG Data Types for Traffic Engineering";
+  }
+
+  /*
+   * Identities
+   */
+
+  identity bandwidth-profile-type {
+    description
+      "Bandwidth Profile Types";
+  }
+
+    identity mef-10 {
+      base bandwidth-profile-type;
+      description
+        "MEF 10 Bandwidth Profile";
+      reference
+        "MEF 10.3: Ethernet Services Attributes Phase 3";
+    }
+
+    identity rfc-2697 {
+      base bandwidth-profile-type;
+      description
+        "RFC 2697 Bandwidth Profile";
+      reference
+        "RFC 2697: A Single Rate Three Color Marker";
+    }
+
+    identity rfc-2698 {
+      base bandwidth-profile-type;
+      description
+        "RFC 2698 Bandwidth Profile";
+      reference
+        "RFC 2698: A Two Rate Three Color Marker";
+    }
+
+  // Derived identities from te-types:link-metric-type
+
+    identity link-metric-delay-variation {
+      base te-types:link-metric-type;
+      description
+        "The Unidirectional Delay Variation Metric,
+         measured in units of microseconds.";
+      reference
+        "RFC 7471: OSPF Traffic Engineering (TE) Metric Extensions,
+                   Section 4.3
+         RFC 8570: IS-IS Traffic Engineering (TE) Metric Extensions,
+                   Section 4.3";
+    }
+
+    identity link-metric-loss {
+      base te-types:link-metric-type;
+      description
+        "The Unidirectional Link Loss Metric,
+         measured in units of 0.000003%.";
+      reference
+        "RFC 7471: OSPF Traffic Engineering (TE) Metric Extensions,
+                   Section 4.4
+         RFC 8570: IS-IS Traffic Engineering (TE) Metric Extensions,
+                   Section 4.4";
+    }
+
+  // Derived identities from te-types:link-metric-type
+
+    identity path-metric-delay-variation {
+      base te-types:path-metric-type;
+      description
+        "The Path Delay Variation Metric,
+         measured in units of microseconds.";
+      reference
+        "RFC 8233: Extensions to the Path Computation Element
+                   Communication Protocol (PCEP) to Compute
+                   Service-Aware Label Switched Paths (LSPs),
+                   Section 3.1.2";
+    }
+
+    identity path-metric-loss {
+      base te-types:path-metric-type;
+      description
+        "The Path Loss Metric, measured in units of 0.000003%.";
+      reference
+        "RFC 8233: Extensions to the Path Computation Element
+                   Communication Protocol (PCEP) to Compute
+                   Service-Aware Label Switched Paths (LSPs),
+                   Section 3.1.3";
+    }
+
+  /*
+   * Typedefs
+   */
+
+  typedef te-bandwidth-requested-type {
+    type enumeration {
+      enum specified-value {
+        description
+          "Bandwidth value is explicitly specified.";
+      }
+      enum specified-profile {
+        description
+          "Bandwidth profile is explicitly specified.";
+      }
+      enum auto {
+        description
+          "Bandwidth is automatically computed.";
+      }
+    }
+    description
+      "Enumerated type for specifying whether bandwidth is
+       explicitly specified or automatically computed.";
+  }
+
+  typedef te-class-type {
+    type uint8;
+    description
+      "Diffserv-TE Class-Type.  Defines a set of Traffic Trunks
+       crossing a link that is governed by a specific set of
+       bandwidth constraints.  Class-Type is used for the purposes
+       of link bandwidth allocation, constraint-based routing, and
+       admission control.";
+    reference
+      "RFC 4124: Protocol Extensions for Support of Diffserv-aware
+                 MPLS Traffic Engineering";
+  }
+
+  typedef bc-type {
+    type uint8 {
+      range "0..7";
+    }
+    description
+      "Diffserv-TE bandwidth constraints as defined in RFC 4124.";
+    reference
+      "RFC 4124: Protocol Extensions for Support of Diffserv-aware
+                 MPLS Traffic Engineering";
+  }
+
+  typedef bandwidth-kbps {
+    type uint64;
+    units "Kbps";
+    description
+      "Bandwidth values, expressed in kilobits per second.";
+  }
+
+  typedef bandwidth-mbps {
+    type uint64;
+    units "Mbps";
+    description
+      "Bandwidth values, expressed in megabits per second.";
+  }
+
+  typedef bandwidth-gbps {
+    type uint64;
+    units "Gbps";
+    description
+      "Bandwidth values, expressed in gigabits per second.";
+  }
+
+  identity backup-protection-type {
+    description
+      "Base identity for the backup protection type.";
+  }
+
+  identity backup-protection-link {
+    base backup-protection-type;
+    description
+      "Backup provides link protection only.";
+  }
+
+  identity backup-protection-node-link {
+    base backup-protection-type;
+    description
+      "Backup offers node (preferred) or link protection.";
+  }
+
+  identity bc-model-type {
+    description
+      "Base identity for the Diffserv-TE Bandwidth Constraints
+       Model type.";
+    reference
+      "RFC 4124: Protocol Extensions for Support of Diffserv-aware
+                 MPLS Traffic Engineering";
+  }
+
+  identity bc-model-rdm {
+    base bc-model-type;
+    description
+      "Russian Dolls Bandwidth Constraints Model type.";
+    reference
+      "RFC 4127: Russian Dolls Bandwidth Constraints Model for
+                 Diffserv-aware MPLS Traffic Engineering";
+  }
+
+  identity bc-model-mam {
+    base bc-model-type;
+    description
+      "Maximum Allocation Bandwidth Constraints Model type.";
+    reference
+      "RFC 4125: Maximum Allocation Bandwidth Constraints Model for
+                 Diffserv-aware MPLS Traffic Engineering";
+  }
+
+  identity bc-model-mar {
+    base bc-model-type;
+    description
+      "Maximum Allocation with Reservation Bandwidth Constraints
+       Model type.";
+    reference
+      "RFC 4126: Max Allocation with Reservation Bandwidth
+                 Constraints Model for Diffserv-aware MPLS Traffic
+                 Engineering & Performance Comparisons";
+  }
+
+  /*
+   * Groupings
+   */
+
+  grouping performance-metrics-attributes-packet {
+    description
+      "Contains PM attributes.";
+    uses te-types:performance-metrics-attributes {
+      augment "performance-metrics-one-way" {
+        leaf one-way-min-delay {
+          type uint32 {
+            range "0..16777215";
+          }
+          description
+            "One-way minimum delay or latency in microseconds.";
+        }
+        leaf one-way-min-delay-normality {
+          type te-types:performance-metrics-normality;
+          default "normal";
+          description
+            "One-way minimum delay or latency normality.";
+        }
+        leaf one-way-max-delay {
+          type uint32 {
+            range "0..16777215";
+          }
+          description
+            "One-way maximum delay or latency in microseconds.";
+        }
+        leaf one-way-max-delay-normality {
+          type te-types:performance-metrics-normality;
+          default "normal";
+          description
+            "One-way maximum delay or latency normality.";
+        }
+        leaf one-way-delay-variation {
+          type uint32 {
+            range "0..16777215";
+          }
+          description
+            "One-way delay variation in microseconds.";
+          reference
+            "RFC 5481: Packet Delay Variation Applicability
+                       Statement, Section 4.2";
+        }
+        leaf one-way-delay-variation-normality {
+          type te-types:performance-metrics-normality;
+          default "normal";
+          description
+            "One-way delay variation normality.";
+          reference
+            "RFC 7471: OSPF Traffic Engineering (TE) Metric
+                       Extensions
+             RFC 8570: IS-IS Traffic Engineering (TE) Metric
+                       Extensions
+             RFC 7823: Performance-Based Path Selection for
+                       Explicitly Routed Label Switched Paths (LSPs)
+                       Using TE Metric Extensions";
+        }
+        leaf one-way-packet-loss {
+          type decimal64 {
+            fraction-digits 6;
+            range "0..50.331642";
+          }
+          description
+            "One-way packet loss as a percentage of the total traffic
+             sent over a configurable interval.  The finest precision
+             is 0.000003%, where the maximum is 50.331642%.";
+          reference
+            "RFC 8570: IS-IS Traffic Engineering (TE) Metric
+                       Extensions, Section 4.4";
+        }
+        leaf one-way-packet-loss-normality {
+          type te-types:performance-metrics-normality;
+          default "normal";
+          description
+            "Packet loss normality.";
+          reference
+            "RFC 7471: OSPF Traffic Engineering (TE) Metric
+                       Extensions
+             RFC 8570: IS-IS Traffic Engineering (TE) Metric
+                       Extensions
+             RFC 7823: Performance-Based Path Selection for
+                       Explicitly Routed Label Switched Paths (LSPs)
+                       Using TE Metric Extensions";
+        }
+        description
+          "PM one-way packet-specific augmentation for a generic PM
+           grouping.";
+      }
+      augment "performance-metrics-two-way" {
+        leaf two-way-min-delay {
+          type uint32 {
+            range "0..16777215";
+          }
+          default "0";
+          description
+            "Two-way minimum delay or latency in microseconds.";
+        }
+        leaf two-way-min-delay-normality {
+          type te-types:performance-metrics-normality;
+          default "normal";
+          description
+            "Two-way minimum delay or latency normality.";
+          reference
+            "RFC 7471: OSPF Traffic Engineering (TE) Metric
+                       Extensions
+             RFC 8570: IS-IS Traffic Engineering (TE) Metric
+                       Extensions
+             RFC 7823: Performance-Based Path Selection for
+                       Explicitly Routed Label Switched Paths (LSPs)
+                       Using TE Metric Extensions";
+        }
+        leaf two-way-max-delay {
+          type uint32 {
+            range "0..16777215";
+          }
+          default "0";
+          description
+            "Two-way maximum delay or latency in microseconds.";
+        }
+        leaf two-way-max-delay-normality {
+          type te-types:performance-metrics-normality;
+          default "normal";
+          description
+            "Two-way maximum delay or latency normality.";
+          reference
+            "RFC 7471: OSPF Traffic Engineering (TE) Metric
+                       Extensions
+             RFC 8570: IS-IS Traffic Engineering (TE) Metric
+                       Extensions
+             RFC 7823: Performance-Based Path Selection for
+                       Explicitly Routed Label Switched Paths (LSPs)
+                       Using TE Metric Extensions";
+        }
+        leaf two-way-delay-variation {
+          type uint32 {
+            range "0..16777215";
+          }
+          default "0";
+          description
+            "Two-way delay variation in microseconds.";
+          reference
+            "RFC 5481: Packet Delay Variation Applicability
+                       Statement, Section 4.2";
+        }
+        leaf two-way-delay-variation-normality {
+          type te-types:performance-metrics-normality;
+          default "normal";
+          description
+            "Two-way delay variation normality.";
+          reference
+            "RFC 7471: OSPF Traffic Engineering (TE) Metric
+                       Extensions
+             RFC 8570: IS-IS Traffic Engineering (TE) Metric
+                       Extensions
+             RFC 7823: Performance-Based Path Selection for
+                       Explicitly Routed Label Switched Paths (LSPs)
+                       Using TE Metric Extensions";
+        }
+        leaf two-way-packet-loss {
+          type decimal64 {
+            fraction-digits 6;
+            range "0..50.331642";
+          }
+          default "0";
+          description
+            "Two-way packet loss as a percentage of the total traffic
+             sent over a configurable interval.  The finest precision
+             is 0.000003%.";
+        }
+        leaf two-way-packet-loss-normality {
+          type te-types:performance-metrics-normality;
+          default "normal";
+          description
+            "Two-way packet loss normality.";
+        }
+        description
+          "PM two-way packet-specific augmentation for a generic PM
+           grouping.";
+        reference
+          "RFC 7471: OSPF Traffic Engineering (TE) Metric Extensions
+           RFC 8570: IS-IS Traffic Engineering (TE) Metric Extensions
+           RFC 7823: Performance-Based Path Selection for Explicitly
+                     Routed Label Switched Paths (LSPs) Using TE
+                     Metric Extensions";
+      }
+    }
+  }
+
+  grouping one-way-performance-metrics-packet {
+    description
+      "One-way packet PM throttle grouping.";
+    leaf one-way-min-delay {
+      type uint32 {
+        range "0..16777215";
+      }
+      default "0";
+      description
+        "One-way minimum delay or latency in microseconds.";
+    }
+    leaf one-way-max-delay {
+      type uint32 {
+        range "0..16777215";
+      }
+      default "0";
+      description
+        "One-way maximum delay or latency in microseconds.";
+    }
+    leaf one-way-delay-variation {
+      type uint32 {
+        range "0..16777215";
+      }
+      default "0";
+      description
+        "One-way delay variation in microseconds.";
+    }
+    leaf one-way-packet-loss {
+      type decimal64 {
+        fraction-digits 6;
+        range "0..50.331642";
+      }
+      default "0";
+      description
+        "One-way packet loss as a percentage of the total traffic
+         sent over a configurable interval.  The finest precision is
+         0.000003%.";
+    }
+  }
+
+  grouping one-way-performance-metrics-gauge-packet {
+    description
+      "One-way packet PM throttle grouping.
+
+       This grouping is used to report the same metrics defined in
+       the one-way-performance-metrics-packet grouping, using gauges
+       instead of uint32 data types and referencing IPPM RFCs
+       instead of IGP-TE RFCs.";
+    leaf one-way-min-delay {
+      type yang:gauge64;
+      description
+        "One-way minimum delay or latency in microseconds.";
+    }
+    leaf one-way-max-delay {
+      type yang:gauge64;
+      description
+        "One-way maximum delay or latency in microseconds.";
+      reference
+        "RFC 7679: A One-Way Delay Metric for IP Performance
+                   Metrics (IPPM)";
+    }
+    leaf one-way-delay-variation {
+      type yang:gauge64;
+      description
+        "One-way delay variation in microseconds.";
+      reference
+        "RFC 3393: IP Packet Delay Variation Metric for IP
+                   Performance Metrics (IPPM)";
+    }
+    leaf one-way-packet-loss {
+      type decimal64 {
+        fraction-digits 5;
+        range "0..100";
+      }
+      description
+        "The ratio of packets dropped to packets transmitted between
+         two endpoints.";
+      reference
+        "RFC 7680: A One-Way Loss Metric for IP Performance
+                   Metrics (IPPM)";
+    }
+  }
+
+  grouping two-way-performance-metrics-packet {
+    description
+      "Two-way packet PM throttle grouping.";
+    leaf two-way-min-delay {
+      type uint32 {
+        range "0..16777215";
+      }
+      default "0";
+      description
+        "Two-way minimum delay or latency in microseconds.";
+    }
+    leaf two-way-max-delay {
+      type uint32 {
+        range "0..16777215";
+      }
+      default "0";
+      description
+        "Two-way maximum delay or latency in microseconds.";
+    }
+    leaf two-way-delay-variation {
+      type uint32 {
+        range "0..16777215";
+      }
+      default "0";
+      description
+        "Two-way delay variation in microseconds.";
+    }
+    leaf two-way-packet-loss {
+      type decimal64 {
+        fraction-digits 6;
+        range "0..50.331642";
+      }
+      default "0";
+      description
+        "Two-way packet loss as a percentage of the total traffic
+         sent over a configurable interval.  The finest precision is
+         0.000003%.";
+    }
+  }
+
+  grouping two-way-performance-metrics-gauge-packet {
+    description
+      "Two-way packet PM throttle grouping.
+
+       This grouping is used to report the same metrics defined in
+       the two-way-performance-metrics-packet grouping, using gauges
+       instead of uint32 data types and referencing IPPM RFCs
+       instead of IGP-TE RFCs.";
+    leaf two-way-min-delay {
+      type yang:gauge64;
+      description
+        "Two-way minimum delay or latency in microseconds.";
+      reference
+        "RFC 2681: A Round-trip Delay Metric for IPPM";
+    }
+    leaf two-way-max-delay {
+      type yang:gauge64;
+      description
+        "Two-way maximum delay or latency in microseconds.";
+      reference
+        "RFC 2681: A Round-trip Delay Metric for IPPM";
+    }
+    leaf two-way-delay-variation {
+      type yang:gauge64;
+      description
+        "Two-way delay variation in microseconds.";
+      reference
+        "RFC 5481: Packet Delay Variation Applicability Statement";
+    }
+    leaf two-way-packet-loss {
+      type decimal64 {
+        fraction-digits 5;
+        range "0..100";
+      }
+      description
+        "The ratio of packets dropped to packets transmitted between
+         two endpoints.";
+    }
+  }
+
+  grouping performance-metrics-throttle-container-packet {
+    description
+      "Packet PM threshold grouping.";
+    uses te-types:performance-metrics-throttle-container {
+      augment "throttle/threshold-out" {
+        uses one-way-performance-metrics-packet;
+        uses two-way-performance-metrics-packet;
+        description
+          "PM threshold-out packet augmentation for a
+           generic grouping.";
+      }
+      augment "throttle/threshold-in" {
+        uses one-way-performance-metrics-packet;
+        uses two-way-performance-metrics-packet;
+        description
+          "PM threshold-in packet augmentation for a
+           generic grouping.";
+      }
+      augment "throttle/threshold-accelerated-advertisement" {
+        uses one-way-performance-metrics-packet;
+        uses two-way-performance-metrics-packet;
+        description
+          "PM accelerated advertisement packet augmentation for a
+           generic grouping.";
+      }
+    }
+  }
+
+  grouping bandwidth-profile-parameters {
+    description
+      "Common parameters to define bandwidth profiles in packet
+       networks.";
+    leaf cir {
+      type uint64;
+      units "bits/second";
+      description
+        "Committed Information Rate (CIR).";
+    }
+    leaf cbs {
+      type uint64;
+      units "bytes";
+      description
+        "Committed Burst Size (CBS).";
+    }
+    leaf eir {
+      type uint64;
+      units "bits/second";
+      description
+        "Excess Information Rate (EIR).";
+    }
+    leaf ebs {
+      type uint64;
+      units "bytes";
+      description
+        "Excess Burst Size (EBS).";
+    }
+    leaf pir {
+      type uint64;
+      units "bits/second";
+      description
+        "Peak Information Rate (PIR).";
+    }
+    leaf pbs {
+      type uint64;
+      units "bytes";
+      description
+        "Peak Burst Size (PBS).";
+    }
+  }
+
+  grouping te-packet-path-bandwidth {
+    description
+      "Bandwidth attributes for TE Packet paths.";
+    container packet-bandwidth {
+      description
+        "Bandwidth attributes for TE Packet paths.";
+      leaf specification-type {
+        type te-bandwidth-requested-type;
+        description
+          "The bandwidth specification type, either explicitly
+           specified or automatically computed.";
+      }
+      leaf set-bandwidth {
+        when "../specification-type = 'specified-value'" {
+          description
+            "When the bandwidth value is explicitly specified.";
+        }
+        type bandwidth-kbps;
+        description
+          "Set the bandwidth value explicitly, e.g., using offline
+           calculation.";
+      }
+      container bandwidth-profile {
+        when "../specification-type = 'specified-profile'" {
+          description
+            "When the bandwidth profile is explicitly specified.";
+        }
+        description
+          "Set the bandwidth profile attributes explicitly.";
+        leaf bandwidth-profile-name {
+          type string;
+          description
+            "Name of Bandwidth Profile.";
+        }
+        leaf bandwidth-profile-type {
+          type identityref {
+            base bandwidth-profile-type;
+          }
+          description
+            "Type of Bandwidth Profile.";
+        }
+        uses bandwidth-profile-parameters;
+      }
+      leaf class-type {
+        type te-types:te-ds-class;
+        description
+          "The Class-Type of traffic transported by the LSP.";
+        reference
+          "RFC 4124: Protocol Extensions for Support of
+                     Diffserv-aware MPLS Traffic Engineering,
+                     Section 4.3.1";
+      }
+      leaf signaled-bandwidth {
+        type te-packet-types:bandwidth-kbps;
+        config false;
+        description
+          "The currently signaled bandwidth of the LSP.
+
+           In the case where the bandwidth is specified
+           explicitly, then this will match the value of the
+           set-bandwidth leaf.
+
+           In the cases where the bandwidth is dynamically
+           computed by the system, the current value of the
+           bandwidth should be reflected.";
+      }
+    }
+  }
+
+  grouping te-packet-link-bandwidth {
+    description
+      "Bandwidth attributes for Packet TE links.";
+    leaf packet-bandwidth {
+      type uint64;
+      units "bits/second";
+      description
+        "Bandwidth value for Packet TE links.";
+    }
+  }
+}
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-te-types@2024-10-30.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-te-types@2024-10-30.yang
new file mode 100644
index 0000000000000000000000000000000000000000..5d9ae16f4bb43b5389217771a9b3f83d177449ca
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-te-types@2024-10-30.yang
@@ -0,0 +1,4399 @@
+module ietf-te-types {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-te-types";
+  prefix te-types;
+
+  import ietf-inet-types {
+    prefix inet;
+    reference
+      "RFC 6991: Common YANG Data Types";
+  }
+  import ietf-yang-types {
+    prefix yang;
+    reference
+      "RFC 6991: Common YANG Data Types";
+  }
+  import ietf-routing-types {
+    prefix rt-types;
+    reference
+      "RFC 8294: Common YANG Data Types for the Routing Area";
+  }
+
+  import ietf-network {
+    prefix "nw";
+    reference
+      "RFC 8345: A YANG Data Model for Network Topologies";
+  }
+
+  import ietf-network-topology {
+    prefix "nt";
+    reference
+      "RFC 8345: A YANG Data Model for Network Topologies";
+  }
+
+  organization
+    "IETF Traffic Engineering Architecture and Signaling (TEAS)
+     Working Group";
+  contact
+    "WG Web:   <https://datatracker.ietf.org/wg/teas/>
+     WG List:  <mailto:teas@ietf.org>
+
+     Editor:   Tarek Saad
+               <mailto:tsaad.net@gmail.com>
+
+     Editor:   Rakesh Gandhi
+               <mailto:rgandhi@cisco.com>
+
+     Editor:   Vishnu Pavan Beeram
+               <mailto:vbeeram@juniper.net>
+
+     Editor:   Xufeng Liu
+               <mailto:xufeng.liu.ietf@gmail.com>
+
+     Editor:   Igor Bryskin
+               <mailto:i_bryskin@yahoo.com>";
+  description
+    "This YANG module contains a collection of generally useful
+     YANG data type definitions specific to TE.  The model fully
+     conforms to the Network Management Datastore Architecture
+     (NMDA).
+
+     The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL
+     NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED',
+     'MAY', and 'OPTIONAL' in this document are to be interpreted as
+     described in BCP 14 (RFC 2119) (RFC 8174) when, and only when,
+     they appear in all capitals, as shown here.
+
+     Copyright (c) 2024 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject to
+     the license terms contained in, the Revised BSD License set
+     forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC XXXX
+     (https://www.rfc-editor.org/info/rfcXXXX); see the RFC itself
+     for full legal notices.";
+  revision 2024-10-30 {
+    description
+      "This revision adds the following new identities:
+      - lsp-provisioning-error-reason;
+      - association-type-diversity;
+      - tunnel-admin-state-auto;
+      - lsp-restoration-restore-none;
+      - restoration-scheme-rerouting;
+      - path-metric-optimization-type;
+      - link-path-metric-type;
+      - link-metric-type and its derived identities;
+      - path-computation-error-reason and its derived identities;
+      - protocol-origin-type and its derived identities;
+      - svec-objective-function-type and its derived identities;
+      - svec-metric-type and its derived identities.
+
+      This revision adds the following new data types:
+      - path-type.
+
+      This revision adds the following new groupings:
+      - encoding-and-switching-type;
+      - te-generic-node-id.
+
+      This revision updates the following identities:
+      - objective-function-type;
+      - action-exercise;
+      - path-metric-type;
+      - path-metric-te;
+      - path-metric-igp;
+      - path-metric-hop;
+      - path-metric-delay-average;
+      - path-metric-delay-minimum;
+      - path-metric-residual-bandwidth;
+      - path-metric-optimize-includes;
+      - path-metric-optimize-excludes;
+      - te-optimization-criterion.
+
+      This revision updates the following data types:
+      - te-node-id.
+
+      This revision updates the following groupings:
+      - explicit-route-hop:
+        - adds the following leaves:
+          - node-id-uri;
+          - link-tp-id-uri;
+        - updates the following leaves:
+          - node-id;
+          - link-tp-id;
+      - record-route-state:
+        - adds the following leaves:
+          - node-id-uri;
+          - link-tp-id-uri;
+        - updates the following leaves:
+          - node-id;
+          - link-tp-id;
+      - optimization-metric-entry:
+        - updates the following leaves:
+          - metric-type;
+      - tunnel-constraints;
+        - adds the following leaves:
+          - network-id;
+      - path-constraints-route-objects:
+        - updates the following containers:
+          - explicit-route-objects-always;
+      - generic-path-metric-bounds:
+        - updates the following leaves:
+          - metric-type;
+      - generic-path-optimization
+        - adds the following leaves:
+          - tiebreaker;
+        - deprecate the following containers:
+          - tiebreakers.
+
+      This revision obsoletes the following identities:
+      - of-minimize-agg-bandwidth-consumption;
+      - of-minimize-load-most-loaded-link;
+      - of-minimize-cost-path-set;
+      - lsp-protection-reroute-extra;
+      - lsp-protection-reroute.
+
+      This revision provides also few editorial changes.";
+    reference
+      "RFC XXXX: Common YANG Data Types for Traffic Engineering";
+  }
+  // RFC Editor: replace XXXX with actual RFC number, update date
+  // information and remove this note
+
+  revision 2020-06-10 {
+    description
+      "Initial Version of TE types.";
+    reference
+      "RFC 8776: Common YANG Data Types for Traffic Engineering";
+  }
+
+  /**
+   * Typedefs
+   */
+
+  typedef admin-group {
+    type yang:hex-string {
+      /* 01:02:03:04 */
+      length "1..11";
+    }
+    description
+      "Administrative group / resource class / color representation
+       in 'hex-string' type.
+
+       The most significant byte in the hex-string is the farthest
+       to the left in the byte sequence.  Leading zero bytes in the
+       configured value may be omitted for brevity.";
+    reference
+      "RFC 3630: Traffic Engineering (TE) Extensions to OSPF
+                 Version 2
+       RFC 5305: IS-IS Extensions for Traffic Engineering
+       RFC 7308: Extended Administrative Groups in MPLS Traffic
+                 Engineering (MPLS-TE)";
+  }
+
+  typedef admin-groups {
+    type union {
+      type admin-group;
+      type extended-admin-group;
+    }
+    description
+      "Derived types for TE administrative groups.";
+  }
+
+  typedef extended-admin-group {
+    type yang:hex-string;
+    description
+      "Extended administrative group / resource class / color
+       representation in 'hex-string' type.
+
+       The most significant byte in the hex-string is the farthest
+       to the left in the byte sequence.  Leading zero bytes in the
+       configured value may be omitted for brevity.";
+    reference
+      "RFC 7308: Extended Administrative Groups in MPLS Traffic
+                 Engineering (MPLS-TE)";
+  }
+
+  typedef path-attribute-flags {
+    type union {
+      type identityref {
+        base session-attributes-flags;
+      }
+      type identityref {
+        base lsp-attributes-flags;
+      }
+    }
+    description
+      "Path attributes flags type.";
+  }
+
+  typedef performance-metrics-normality {
+    type enumeration {
+      enum unknown {
+        value 0;
+        description
+          "Unknown.";
+      }
+      enum normal {
+        value 1;
+        description
+          "Normal.  Indicates that the anomalous bit is not set.";
+      }
+      enum abnormal {
+        value 2;
+        description
+          "Abnormal.  Indicates that the anomalous bit is set.";
+      }
+    }
+    description
+      "Indicates whether a performance metric is normal (anomalous
+       bit not set), abnormal (anomalous bit set), or unknown.";
+    reference
+      "RFC 7471: OSPF Traffic Engineering (TE) Metric Extensions
+       RFC 7823: Performance-Based Path Selection for Explicitly
+                 Routed Label Switched Paths (LSPs) Using TE Metric
+                 Extensions
+       RFC 8570: IS-IS Traffic Engineering (TE) Metric Extensions";
+  }
+
+  typedef srlg {
+    type uint32;
+    description
+      "SRLG type.";
+    reference
+      "RFC 4203: OSPF Extensions in Support of Generalized
+                 Multi-Protocol Label Switching (GMPLS)
+       RFC 5307: IS-IS Extensions in Support of Generalized
+                 Multi-Protocol Label Switching (GMPLS)";
+  }
+
+  typedef te-common-status {
+    type enumeration {
+      enum up {
+        description
+          "Enabled.";
+      }
+      enum down {
+        description
+          "Disabled.";
+      }
+      enum testing {
+        description
+          "In some test mode.";
+      }
+      enum preparing-maintenance {
+        description
+          "The resource is disabled in the control plane to prepare
+           for a graceful shutdown for maintenance purposes.";
+        reference
+          "RFC 5817: Graceful Shutdown in MPLS and Generalized MPLS
+                     Traffic Engineering Networks";
+      }
+      enum maintenance {
+        description
+          "The resource is disabled in the data plane for maintenance
+           purposes.";
+      }
+      enum unknown {
+        description
+          "Status is unknown.";
+      }
+    }
+    description
+      "Defines a type representing the common states of a TE
+       resource.";
+  }
+
+  typedef te-bandwidth {
+    type string {
+      pattern '0[xX](0((\.0?)?[pP](\+)?0?|(\.0?))|'
+            + '1(\.([\da-fA-F]{0,5}[02468aAcCeE]?)?)?'
+            + '[pP](\+)?(12[0-7]|'
+            + '1[01]\d|0?\d?\d)?)|0[xX][\da-fA-F]{1,8}|\d+'
+            + '(,(0[xX](0((\.0?)?[pP](\+)?0?|(\.0?))|'
+            + '1(\.([\da-fA-F]{0,5}[02468aAcCeE]?)?)?'
+            + '[pP](\+)?(12[0-7]|'
+            + '1[01]\d|0?\d?\d)?)|0[xX][\da-fA-F]{1,8}|\d+))*';
+    }
+    description
+      "This is the generic bandwidth type.  It is a string containing
+       a list of numbers separated by commas, where each of these
+       numbers can be non-negative decimal, hex integer, or
+       hex float:
+
+       (dec | hex | float)[*(','(dec | hex | float))]
+
+       For the packet-switching type, the string encoding follows
+       the type 'bandwidth-ieee-float32' as defined in RFC 8294
+       (e.g., 0x1p10), where the units are in bytes per second.
+
+       For the Optical Transport Network (OTN) switching type,
+       a list of integers can be used, such as '0,2,3,1', indicating
+       two ODU0s and one ODU3.  ('ODU' stands for 'Optical Data
+       Unit'.)  For Dense Wavelength Division Multiplexing (DWDM),
+       a list of pairs of slot numbers and widths can be used,
+       such as '0,2,3,3', indicating a frequency slot 0 with
+       slot width 2 and a frequency slot 3 with slot width 3.
+       Canonically, the string is represented as all lowercase and in
+       hex, where the prefix '0x' precedes the hex number.";
+    reference
+      "RFC 8294: Common YANG Data Types for the Routing Area
+       ITU-T G.709: Interfaces for the optical transport network -
+                    Edition 6.0 (06/2020)";
+  }
+
+  typedef te-ds-class {
+    type uint8 {
+      range "0..7";
+    }
+    description
+      "The Differentiated Services Class-Type of traffic.";
+    reference
+      "RFC 4124: Protocol Extensions for Support of Diffserv-aware
+                 MPLS Traffic Engineering, Section 4.3.1";
+  }
+
+  typedef te-global-id {
+    type uint32;
+    description
+      "An identifier to uniquely identify an operator, which can be
+       either a provider or a client.
+
+       The definition of this type is taken from RFCs 6370 and 5003.
+
+       This attribute type is used solely to provide a globally
+       unique context for TE topologies.";
+    reference
+      "RFC 5003: Attachment Individual Identifier (AII) Types for
+                 Aggregation
+       RFC 6370: MPLS Transport Profile (MPLS-TP) Identifiers";
+  }
+
+  typedef te-hop-type {
+    type enumeration {
+      enum loose {
+        description
+          "A loose hop in an explicit path.";
+      }
+      enum strict {
+        description
+          "A strict hop in an explicit path.";
+      }
+    }
+    description
+      "Enumerated type for specifying loose or strict paths.";
+    reference
+      "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels,
+                 Section 4.3.3";
+  }
+
+  typedef te-link-access-type {
+    type enumeration {
+      enum point-to-point {
+        description
+          "The link is point-to-point.";
+      }
+      enum multi-access {
+        description
+          "The link is multi-access, including broadcast and NBMA.";
+      }
+    }
+    description
+      "Defines a type representing the access type of a TE link.";
+    reference
+      "RFC 3630: Traffic Engineering (TE) Extensions to OSPF
+                 Version 2";
+  }
+
+  typedef te-label-direction {
+    type enumeration {
+      enum forward {
+        description
+          "Label allocated for the forward LSP direction.";
+      }
+      enum reverse {
+        description
+          "Label allocated for the reverse LSP direction.";
+      }
+    }
+    description
+      "Enumerated type for specifying the forward or reverse
+       label.";
+  }
+
+  typedef te-link-direction {
+    type enumeration {
+      enum incoming {
+        description
+          "The explicit route represents an incoming link on
+           a node.";
+      }
+      enum outgoing {
+        description
+          "The explicit route represents an outgoing link on
+           a node.";
+      }
+    }
+    description
+      "Enumerated type for specifying the direction of a link on
+       a node.";
+  }
+
+  typedef te-metric {
+    type uint32;
+    description
+      "TE metric.";
+    reference
+      "RFC 3785: Use of Interior Gateway Protocol (IGP) Metric as a
+                 second MPLS Traffic Engineering (TE) Metric";
+  }
+
+  typedef te-node-id {
+    type union {
+      type yang:dotted-quad;
+      type inet:ipv6-address-no-zone;
+    }
+    description
+      "A type representing the identifier for a node in a TE
+       topology.
+
+       The identifier is represented either as 4 octets in
+       dotted-quad notation, or as 16 octets in full, mixed,
+       shortened, or shortened-mixed IPv6 address notation.
+
+       This attribute MAY be mapped to the Router Address TLV
+       described in Section 2.4.1 of RFC 3630, the TE Router ID
+       described in Section 3 of RFC 6827, the Traffic Engineering
+       Router ID TLV described in Section 4.3 of RFC 5305, the TE
+       Router ID TLV described in Section 3.2.1 of RFC 6119, or the
+       IPv6 TE Router ID TLV described in Section 4.1 of RFC 6119.
+
+       The reachability of such a TE node MAY be achieved by a
+       mechanism such as that described in Section 6.2 of RFC 6827.";
+    reference
+      "RFC 3630: Traffic Engineering (TE) Extensions to OSPF
+                 Version 2, Section 2.4.1
+       RFC 5305: IS-IS Extensions for Traffic Engineering,
+                 Section 4.3
+       RFC 6119: IPv6 Traffic Engineering in IS-IS, Section 3.2.1
+       RFC 6827: Automatically Switched Optical Network (ASON)
+                 Routing for OSPFv2 Protocols, Section 3";
+  }
+
+  typedef te-oper-status {
+    type te-common-status;
+    description
+      "Defines a type representing the operational status of
+       a TE resource.";
+  }
+
+  typedef te-admin-status {
+    type te-common-status;
+    description
+      "Defines a type representing the administrative status of
+       a TE resource.";
+  }
+
+  typedef te-path-disjointness {
+    type bits {
+      bit node {
+        position 0;
+        description
+          "Node disjoint.";
+      }
+      bit link {
+        position 1;
+        description
+          "Link disjoint.";
+      }
+      bit srlg {
+        position 2;
+        description
+          "SRLG (Shared Risk Link Group) disjoint.";
+      }
+    }
+    description
+      "Type of the resource disjointness for a TE tunnel path.";
+    reference
+      "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                 Generalized Multi-Protocol Label Switching (GMPLS)
+                 Recovery";
+  }
+
+  typedef te-recovery-status {
+    type enumeration {
+      enum normal {
+        description
+          "Both the recovery span and the working span are fully
+           allocated and active, data traffic is being
+           transported over (or selected from) the working
+           span, and no trigger events are reported.";
+      }
+      enum recovery-started {
+        description
+          "The recovery action has been started but not completed.";
+      }
+      enum recovery-succeeded {
+        description
+          "The recovery action has succeeded.  The working span has
+           reported a failure/degrade condition, and the user traffic
+           is being transported (or selected) on the recovery span.";
+      }
+      enum recovery-failed {
+        description
+          "The recovery action has failed.";
+      }
+      enum reversion-started {
+        description
+          "The reversion has started.";
+      }
+      enum reversion-succeeded {
+        description
+          "The reversion action has succeeded.";
+      }
+      enum reversion-failed {
+        description
+          "The reversion has failed.";
+      }
+      enum recovery-unavailable {
+        description
+          "The recovery is unavailable, as a result of either an
+           operator's lockout command or a failure condition
+           detected on the recovery span.";
+      }
+      enum recovery-admin {
+        description
+          "The operator has issued a command to switch the user
+           traffic to the recovery span.";
+      }
+      enum wait-to-restore {
+        description
+          "The recovery domain is recovering from a failure/degrade
+           condition on the working span that is being controlled by
+           the Wait-to-Restore (WTR) timer.";
+      }
+    }
+    description
+      "Defines the status of a recovery action.";
+    reference
+      "RFC 6378: MPLS Transport Profile (MPLS-TP) Linear Protection
+       RFC 4427: Recovery (Protection and Restoration) Terminology
+                 for Generalized Multi-Protocol Label Switching
+                 (GMPLS)";
+  }
+
+  typedef te-template-name {
+    type string {
+      pattern '/?([a-zA-Z0-9\-_.]+)(/[a-zA-Z0-9\-_.]+)*';
+    }
+    description
+      "A type for the name of a TE node template or TE link
+       template.";
+  }
+
+  typedef te-topology-event-type {
+    type enumeration {
+      enum add {
+        value 0;
+        description
+          "A TE node or TE link has been added.";
+      }
+      enum remove {
+        value 1;
+        description
+          "A TE node or TE link has been removed.";
+      }
+      enum update {
+        value 2;
+        description
+          "A TE node or TE link has been updated.";
+      }
+    }
+    description
+      "TE event type for notifications.";
+  }
+
+  typedef te-topology-id {
+    type union {
+      type string {
+        length "0";
+        // empty string
+      }
+      type string {
+        pattern '([a-zA-Z0-9\-_.]+:)*'
+              + '/?([a-zA-Z0-9\-_.]+)(/[a-zA-Z0-9\-_.]+)*';
+      }
+    }
+    description
+      "An identifier for a topology.
+
+       It is optional to have one or more prefixes at the beginning,
+       separated by colons.  The prefixes can be 'network-types' as
+       defined in the 'ietf-network' module in RFC 8345, to help the
+       user better understand the topology before further inquiry
+       is made.";
+    reference
+      "RFC 8345: A YANG Data Model for Network Topologies";
+  }
+
+  typedef te-tp-id {
+    type union {
+      type uint32;
+      // Unnumbered
+      type inet:ip-address;
+      // IPv4 or IPv6 address
+    }
+    description
+      "An identifier for a TE link endpoint on a node.
+
+       This attribute is mapped to a local or remote link identifier
+       as defined in RFCs 3630 and 5305.";
+    reference
+      "RFC 3630: Traffic Engineering (TE) Extensions to OSPF
+                 Version 2
+       RFC 5305: IS-IS Extensions for Traffic Engineering";
+  }
+
+  typedef path-type {
+    type enumeration {
+      enum primary-path {
+        description
+          "Indicates that the TE path is a primary path.";
+      }
+      enum secondary-path {
+        description
+          "Indicates that the TE path is a secondary path.";
+      }
+      enum primary-reverse-path {
+        description
+          "Indicates that the TE path is a primary reverse path.";
+      }
+      enum secondary-reverse-path {
+        description
+          "Indicates that the TE path is a secondary reverse path.";
+      }
+    }
+    description
+      "The type of TE path, indicating whether a path is a primary, 
+       or a reverse primary, or a secondary, or a reverse secondary 
+       path.";
+  }
+
+  /* TE features */
+
+  feature p2mp-te {
+    description
+      "Indicates support for Point-to-Multipoint TE (P2MP-TE).";
+    reference
+      "RFC 4875: Extensions to Resource Reservation Protocol -
+                 Traffic Engineering (RSVP-TE) for
+                 Point-to-Multipoint TE Label Switched Paths (LSPs)";
+  }
+
+  feature frr-te {
+    description
+      "Indicates support for TE Fast Reroute (FRR).";
+    reference
+      "RFC 4090: Fast Reroute Extensions to RSVP-TE for LSP Tunnels";
+  }
+
+  feature extended-admin-groups {
+    description
+      "Indicates support for TE link extended administrative
+       groups.";
+    reference
+      "RFC 7308: Extended Administrative Groups in MPLS Traffic
+                 Engineering (MPLS-TE)";
+  }
+
+  feature named-path-affinities {
+    description
+      "Indicates support for named path affinities.";
+  }
+
+  feature named-extended-admin-groups {
+    description
+      "Indicates support for named extended administrative groups.";
+  }
+
+  feature named-srlg-groups {
+    description
+      "Indicates support for named SRLG groups.";
+  }
+
+  feature named-path-constraints {
+    description
+      "Indicates support for named path constraints.";
+  }
+
+  feature path-optimization-metric {
+    description
+      "Indicates support for path optimization metrics.";
+  }
+
+  feature path-optimization-objective-function {
+    description
+      "Indicates support for path optimization objective functions.";
+  }
+
+  /*
+   * Identities
+   */
+
+  identity lsp-provisioning-error-reason {
+    description
+      "Base identity for LSP provisioning errors.";
+  }
+
+  identity session-attributes-flags {
+    description
+      "Base identity for the RSVP-TE session attributes flags.";
+  }
+
+    identity local-protection-desired {
+      base session-attributes-flags;
+      description
+        "Local protection is desired.";
+      reference
+        "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels,
+                  Section 4.7.1";
+    }
+
+    identity se-style-desired {
+      base session-attributes-flags;
+      description
+        "Shared explicit style, to allow the LSP to be established
+         and share resources with the old LSP.";
+      reference
+        "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels";
+    }
+
+    identity local-recording-desired {
+      base session-attributes-flags;
+      description
+        "Label recording is desired.";
+      reference
+        "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels,
+                  Section 4.7.1";
+    }
+
+    identity bandwidth-protection-desired {
+      base session-attributes-flags;
+      description
+        "Requests FRR bandwidth protection on LSRs, if present.";
+      reference
+        "RFC 4090: Fast Reroute Extensions to RSVP-TE for LSP
+                   Tunnels";
+    }
+
+    identity node-protection-desired {
+      base session-attributes-flags;
+      description
+        "Requests FRR node protection on LSRs, if present.";
+      reference
+        "RFC 4090: Fast Reroute Extensions to RSVP-TE for LSP
+                   Tunnels";
+    }
+
+    identity path-reevaluation-request {
+      base session-attributes-flags;
+      description
+        "This flag indicates that a path re-evaluation (of the
+         current path in use) is requested.  Note that this does
+         not trigger any LSP reroutes but instead just signals a
+         request to evaluate whether a preferable path exists.";
+      reference
+        "RFC 4736: Reoptimization of Multiprotocol Label Switching
+                  (MPLS) Traffic Engineering (TE) Loosely Routed
+                  Label Switched Path (LSP)";
+    }
+
+    identity soft-preemption-desired {
+      base session-attributes-flags;
+      description
+        "Soft preemption of LSP resources is desired.";
+      reference
+        "RFC 5712: MPLS Traffic Engineering Soft Preemption";
+    }
+
+  identity lsp-attributes-flags {
+    description
+      "Base identity for LSP attributes flags.";
+  }
+
+    identity end-to-end-rerouting-desired {
+      base lsp-attributes-flags;
+      description
+        "Indicates end-to-end rerouting behavior for an LSP
+         undergoing establishment.  This MAY also be used to
+         specify the behavior of end-to-end LSP recovery for
+         established LSPs.";
+      reference
+        "RFC 4920: Crankback Signaling Extensions for MPLS and GMPLS
+                   RSVP-TE
+         RFC 5420: Encoding of Attributes for MPLS LSP Establishment
+                   Using Resource Reservation Protocol Traffic
+                   Engineering (RSVP-TE)
+         RFC 7570: Label Switched Path (LSP) Attribute in the
+                   Explicit Route Object (ERO)";
+    }
+
+    identity boundary-rerouting-desired {
+      base lsp-attributes-flags;
+      description
+        "Indicates boundary rerouting behavior for an LSP undergoing
+         establishment.  This MAY also be used to specify
+         segment-based LSP recovery through nested crankback for
+         established LSPs.  The boundary Area Border Router (ABR) /
+         Autonomous System Border Router (ASBR) can decide to forward
+         the PathErr message upstream to either an upstream boundary
+         ABR/ASBR or the ingress LSR.  Alternatively, it can try to
+         select another egress boundary LSR.";
+      reference
+        "RFC 4920: Crankback Signaling Extensions for MPLS and GMPLS
+                   RSVP-TE
+         RFC 5420: Encoding of Attributes for MPLS LSP Establishment
+                   Using Resource Reservation Protocol Traffic
+                   Engineering (RSVP-TE)
+         RFC 7570: Label Switched Path (LSP) Attribute in the
+                   Explicit Route Object (ERO)";
+    }
+
+    identity segment-based-rerouting-desired {
+      base lsp-attributes-flags;
+      description
+        "Indicates segment-based rerouting behavior for an LSP
+         undergoing establishment.  This MAY also be used to specify
+         segment-based LSP recovery for established LSPs.";
+      reference
+        "RFC 4920: Crankback Signaling Extensions for MPLS and GMPLS
+                   RSVP-TE
+         RFC 5420: Encoding of Attributes for MPLS LSP Establishment
+                   Using Resource Reservation Protocol
+                   Traffic Engineering (RSVP-TE)
+         RFC 7570: Label Switched Path (LSP) Attribute in the
+                   Explicit Route Object (ERO)";
+    }
+
+    identity lsp-integrity-required {
+      base lsp-attributes-flags;
+      description
+        "Indicates that LSP integrity is required.";
+      reference
+        "RFC 4875: Extensions to Resource Reservation Protocol -
+                   Traffic Engineering (RSVP-TE) for
+                   Point-to-Multipoint TE Label Switched Paths (LSPs)
+         RFC 7570: Label Switched Path (LSP) Attribute in the
+                   Explicit Route Object (ERO)";
+    }
+
+    identity contiguous-lsp-desired {
+      base lsp-attributes-flags;
+      description
+        "Indicates that a contiguous LSP is desired.";
+      reference
+        "RFC 5151: Inter-Domain MPLS and GMPLS Traffic Engineering --
+                   Resource Reservation Protocol-Traffic Engineering
+                   (RSVP-TE) Extensions
+         RFC 7570: Label Switched Path (LSP) Attribute in the
+                   Explicit Route Object (ERO)";
+    }
+
+    identity lsp-stitching-desired {
+      base lsp-attributes-flags;
+      description
+        "Indicates that LSP stitching is desired.";
+      reference
+        "RFC 5150: Label Switched Path Stitching with Generalized
+                   Multiprotocol Label Switching Traffic Engineering
+                   (GMPLS TE)
+         RFC 7570: Label Switched Path (LSP) Attribute in the
+                   Explicit Route Object (ERO)";
+    }
+
+    identity pre-planned-lsp-flag {
+      base lsp-attributes-flags;
+      description
+        "Indicates that the LSP MUST be provisioned in the
+         control plane only.";
+      reference
+        "RFC 6001: Generalized MPLS (GMPLS) Protocol Extensions for
+                   Multi-Layer and Multi-Region Networks (MLN/MRN)
+         RFC 7570: Label Switched Path (LSP) Attribute in the
+                   Explicit Route Object (ERO)";
+    }
+
+    identity non-php-behavior-flag {
+      base lsp-attributes-flags;
+      description
+        "Indicates that non-PHP (non-Penultimate Hop Popping)
+         behavior for the LSP is desired.";
+      reference
+        "RFC 6511: Non-Penultimate Hop Popping Behavior and
+                   Out-of-Band Mapping for RSVP-TE Label Switched
+                   Paths
+         RFC 7570: Label Switched Path (LSP) Attribute in the
+                   Explicit Route Object (ERO)";
+    }
+
+    identity oob-mapping-flag {
+      base lsp-attributes-flags;
+      description
+        "Indicates that signaling of the egress binding information
+         is out of band (e.g., via the Border Gateway Protocol
+         (BGP)).";
+      reference
+        "RFC 6511: Non-Penultimate Hop Popping Behavior and
+                   Out-of-Band Mapping for RSVP-TE Label Switched
+                   Paths
+         RFC 7570: Label Switched Path (LSP) Attribute in the
+                   Explicit Route Object (ERO)";
+    }
+
+    identity entropy-label-capability {
+      base lsp-attributes-flags;
+      description
+        "Indicates entropy label capability.";
+      reference
+        "RFC 6790: The Use of Entropy Labels in MPLS Forwarding
+         RFC 7570: Label Switched Path (LSP) Attribute in the
+                   Explicit Route Object (ERO)";
+    }
+
+    identity oam-mep-entity-desired {
+      base lsp-attributes-flags;
+      description
+        "OAM Maintenance Entity Group End Point (MEP) entities
+         desired.";
+      reference
+        "RFC 7260: GMPLS RSVP-TE Extensions for Operations,
+                   Administration, and Maintenance (OAM)
+                   Configuration";
+    }
+
+    identity oam-mip-entity-desired {
+      base lsp-attributes-flags;
+      description
+        "OAM Maintenance Entity Group Intermediate Points (MIP)
+         entities desired.";
+      reference
+        "RFC 7260: GMPLS RSVP-TE Extensions for Operations,
+                   Administration, and Maintenance (OAM)
+                   Configuration";
+    }
+
+    identity srlg-collection-desired {
+      base lsp-attributes-flags;
+      description
+        "SRLG collection desired.";
+      reference
+        "RFC 7570: Label Switched Path (LSP) Attribute in the
+                   Explicit Route Object (ERO)
+         RFC 8001: RSVP-TE Extensions for Collecting Shared Risk
+                   Link Group (SRLG) Information";
+    }
+
+    identity loopback-desired {
+      base lsp-attributes-flags;
+      description
+        "This flag indicates that a particular node on the LSP is
+         required to enter loopback mode.  This can also be
+         used to specify the loopback state of the node.";
+      reference
+        "RFC 7571: GMPLS RSVP-TE Extensions for Lock Instruct and
+                   Loopback";
+    }
+
+    identity p2mp-te-tree-eval-request {
+      base lsp-attributes-flags;
+      description
+        "P2MP-TE tree re-evaluation request.";
+      reference
+        "RFC 8149: RSVP Extensions for Reoptimization of Loosely
+                   Routed Point-to-Multipoint Traffic Engineering
+                   Label Switched Paths (LSPs)";
+    }
+
+    identity rtm-set-desired {
+      base lsp-attributes-flags;
+      description
+        "Residence Time Measurement (RTM) attribute flag requested.";
+      reference
+        "RFC 8169: Residence Time Measurement in MPLS Networks";
+    }
+
+  identity link-protection-type {
+    description
+      "Base identity for the link protection type.";
+  }
+
+    identity link-protection-unprotected {
+      base link-protection-type;
+      description
+        "Unprotected link type.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery";
+    }
+
+    identity link-protection-extra-traffic {
+      base link-protection-type;
+      description
+        "Extra-Traffic protected link type.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery";
+    }
+
+    identity link-protection-shared {
+      base link-protection-type;
+      description
+        "Shared protected link type.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery";
+    }
+
+    identity link-protection-1-for-1 {
+      base link-protection-type;
+      description
+        "One-for-one (1:1) protected link type.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery";
+    }
+
+    identity link-protection-1-plus-1 {
+      base link-protection-type;
+      description
+        "One-plus-one (1+1) protected link type.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery";
+    }
+
+    identity link-protection-enhanced {
+      base link-protection-type;
+      description
+        "A compound link protection type derived from the underlay
+         TE tunnel protection configuration supporting the TE link.";
+    }
+
+  identity association-type {
+    description
+      "Base identity for the tunnel association.";
+  }
+
+    identity association-type-recovery {
+      base association-type;
+      description
+        "Association type for recovery, used to associate LSPs of the
+         same tunnel for recovery.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery
+         RFC 6780: RSVP ASSOCIATION Object Extensions";
+    }
+
+    identity association-type-resource-sharing {
+      base association-type;
+      description
+        "Association type for resource sharing, used to enable
+         resource sharing during make-before-break.";
+      reference
+        "RFC 4873: GMPLS Segment Recovery
+         RFC 6780: RSVP ASSOCIATION Object Extensions";
+    }
+
+    identity association-type-double-sided-bidir {
+      base association-type;
+      description
+        "Association type for double-sided bidirectional LSPs,
+         used to associate two LSPs of two tunnels that are
+         independently configured on either endpoint.";
+      reference
+        "RFC 7551: RSVP-TE Extensions for Associated Bidirectional
+                   Label Switched Paths (LSPs)";
+    }
+
+    identity association-type-single-sided-bidir {
+      base association-type;
+      description
+        "Association type for single-sided bidirectional LSPs,
+         used to associate two LSPs of two tunnels, where one
+         tunnel is configured on one side/endpoint and the other
+         tunnel is dynamically created on the other endpoint.";
+      reference
+        "RFC 6780: RSVP ASSOCIATION Object Extensions
+         RFC 7551: RSVP-TE Extensions for Associated Bidirectional
+                   Label Switched Paths (LSPs)";
+    }
+
+    identity association-type-diversity {
+      base association-type;
+      description
+        "Association Type diversity used to associate LSPs whose
+         paths are to be diverse from each other.";
+      reference
+        "RFC 8800: Path Computation Element Communication Protocol
+                   (PCEP) Extension for Label Switched Path (LSP)
+                   Diversity Constraint Signaling";
+    }
+
+  identity objective-function-type {
+    description
+      "Base identity for path objective function types.";
+  }
+
+    identity of-minimize-cost-path {
+      base objective-function-type;
+      description
+        "Objective function for minimizing path cost.";
+      reference
+        "RFC 5541: Encoding of Objective Functions in the Path
+                   Computation Element Communication Protocol
+                   (PCEP)";
+    }
+
+    identity of-minimize-load-path {
+      base objective-function-type;
+      description
+        "Objective function for minimizing the load on one or more
+         paths.";
+      reference
+        "RFC 5541: Encoding of Objective Functions in the Path
+                   Computation Element Communication Protocol
+                   (PCEP)";
+    }
+
+    identity of-maximize-residual-bandwidth {
+      base objective-function-type;
+      description
+        "Objective function for maximizing residual bandwidth.";
+      reference
+        "RFC 5541: Encoding of Objective Functions in the Path
+                   Computation Element Communication Protocol
+                   (PCEP)";
+    }
+
+    identity of-minimize-agg-bandwidth-consumption {
+      base objective-function-type;
+      status obsolete;
+      description
+        "Objective function for minimizing aggregate bandwidth
+         consumption.
+
+         This identity has been obsoleted: the
+         'svec-of-minimize-agg-bandwidth-consumption' identity SHOULD
+         be used instead.";
+      reference
+        "RFC 5541: Encoding of Objective Functions in the Path
+                   Computation Element Communication Protocol
+                   (PCEP)";
+    }
+
+    identity of-minimize-load-most-loaded-link {
+      base objective-function-type;
+      status obsolete;
+      description
+        "Objective function for minimizing the load on the link that
+         is carrying the highest load.
+
+         This identity has been obsoleted: the
+         'svec-of-minimize-load-most-loaded-link' identity SHOULD
+         be used instead.";
+      reference
+        "RFC 5541: Encoding of Objective Functions in the Path
+                   Computation Element Communication Protocol
+                   (PCEP)";
+    }
+
+    identity of-minimize-cost-path-set {
+      base objective-function-type;
+      status obsolete;
+      description
+        "Objective function for minimizing the cost on a path set.
+
+         This identity has been obsoleted: the
+         'svec-of-minimize-cost-path-set' identity SHOULD
+         be used instead.";
+      reference
+        "RFC 5541: Encoding of Objective Functions in the Path
+                   Computation Element Communication Protocol
+                   (PCEP)";
+    }
+
+  identity path-computation-method {
+    description
+      "Base identity for supported path computation mechanisms.";
+  }
+
+    identity path-locally-computed {
+      base path-computation-method;
+      description
+        "Indicates a constrained-path LSP in which the
+         path is computed by the local LER.";
+      reference
+        "RFC 9522: Overview and Principles of Internet Traffic
+                   Engineering, Section 4.4";
+    }
+
+    identity path-externally-queried {
+      base path-computation-method;
+      description
+        "Constrained-path LSP in which the path is obtained by
+         querying an external source, such as a PCE server.
+         In the case that an LSP is defined to be externally queried,
+         it may also have associated explicit definitions (provided
+         to the external source to aid computation).  The path that
+         is returned by the external source may require further local
+         computation on the device.";
+      reference
+        "RFC 9522: Overview and Principles of Internet Traffic
+                   Engineering
+         RFC 4657: Path Computation Element (PCE) Communication
+                   Protocol Generic Requirements";
+    }
+
+    identity path-explicitly-defined {
+      base path-computation-method;
+      description
+        "Constrained-path LSP in which the path is
+         explicitly specified as a collection of strict and/or loose
+         hops.";
+      reference
+        "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels
+         RFC 9522: Overview and Principles of Internet Traffic
+                   Engineering";
+    }
+
+  identity lsp-metric-type {
+    description
+      "Base identity for the LSP metric specification types.";
+  }
+
+    identity lsp-metric-relative {
+      base lsp-metric-type;
+      description
+        "The metric specified for the LSPs to which this identity
+         refers is specified as a value relative to the IGP metric
+         cost to the LSP's tail end.";
+      reference
+        "RFC 4657: Path Computation Element (PCE) Communication
+                   Protocol Generic Requirements";
+    }
+
+    identity lsp-metric-absolute {
+      base lsp-metric-type;
+      description
+        "The metric specified for the LSPs to which this identity
+         refers is specified as an absolute value.";
+      reference
+        "RFC 4657: Path Computation Element (PCE) Communication
+                   Protocol Generic Requirements";
+    }
+
+    identity lsp-metric-inherited {
+      base lsp-metric-type;
+      description
+        "The metric for the LSPs to which this identity refers is
+         not specified explicitly; rather, it is directly inherited
+         from the IGP cost.";
+      reference
+        "RFC 4657: Path Computation Element (PCE) Communication
+                   Protocol Generic Requirements";
+    }
+
+  identity te-tunnel-type {
+    description
+      "Base identity from which specific tunnel types are derived.";
+  }
+
+    identity te-tunnel-p2p {
+      base te-tunnel-type;
+      description
+        "TE Point-to-Point (P2P) tunnel type.";
+      reference
+        "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels";
+    }
+
+    identity te-tunnel-p2mp {
+      base te-tunnel-type;
+      description
+        "TE P2MP tunnel type.";
+      reference
+        "RFC 4875: Extensions to Resource Reservation Protocol -
+                   Traffic Engineering (RSVP-TE) for
+                   Point-to-Multipoint TE Label Switched Paths
+                   (LSPs)";
+    }
+
+  identity tunnel-action-type {
+    description
+      "Base identity from which specific tunnel action types
+       are derived.";
+  }
+
+    identity tunnel-action-resetup {
+      base tunnel-action-type;
+      description
+        "TE tunnel action that tears down the tunnel's current LSP
+         (if any) and attempts to re-establish a new LSP.";
+    }
+
+    identity tunnel-action-reoptimize {
+      base tunnel-action-type;
+      description
+        "TE tunnel action that reoptimizes the placement of the
+         tunnel LSP(s).";
+    }
+
+    identity tunnel-action-switchpath {
+      base tunnel-action-type;
+      description
+        "TE tunnel action that switches the tunnel's LSP to use the
+         specified path.";
+    }
+
+  identity te-action-result {
+    description
+      "Base identity from which specific TE action results
+       are derived.";
+  }
+
+    identity te-action-success {
+      base te-action-result;
+      description
+        "TE action was successful.";
+    }
+
+    identity te-action-fail {
+      base te-action-result;
+      description
+        "TE action failed.";
+    }
+
+    identity tunnel-action-inprogress {
+      base te-action-result;
+      description
+        "TE action is in progress.";
+    }
+
+  identity tunnel-admin-state-type {
+    description
+      "Base identity for TE tunnel administrative states.";
+  }
+
+    identity tunnel-admin-state-up {
+      base tunnel-admin-state-type;
+      description
+        "Tunnel's administrative state is up.";
+    }
+
+    identity tunnel-admin-state-down {
+      base tunnel-admin-state-type;
+      description
+        "Tunnel's administrative state is down.";
+    }
+
+    identity tunnel-admin-state-auto {
+      base tunnel-admin-state-type;
+      description
+        "Tunnel administrative auto state. The administrative status
+         in state datastore transitions to 'tunnel-admin-up' when the
+         tunnel used by the client layer, and to 'tunnel-admin-down'
+         when it is not used by the client layer.";
+    }
+
+  identity tunnel-state-type {
+    description
+      "Base identity for TE tunnel states.";
+  }
+
+    identity tunnel-state-up {
+      base tunnel-state-type;
+      description
+        "Tunnel's state is up.";
+    }
+
+    identity tunnel-state-down {
+      base tunnel-state-type;
+      description
+        "Tunnel's state is down.";
+    }
+
+  identity lsp-state-type {
+    description
+      "Base identity for TE LSP states.";
+  }
+
+    identity lsp-path-computing {
+      base lsp-state-type;
+      description
+        "State path computation is in progress.";
+    }
+
+    identity lsp-path-computation-ok {
+      base lsp-state-type;
+      description
+        "State path computation was successful.";
+    }
+
+    identity lsp-path-computation-failed {
+      base lsp-state-type;
+      description
+        "State path computation failed.";
+    }
+
+    identity lsp-state-setting-up {
+      base lsp-state-type;
+      description
+        "State is being set up.";
+    }
+
+    identity lsp-state-setup-ok {
+      base lsp-state-type;
+      description
+        "State setup was successful.";
+    }
+
+    identity lsp-state-setup-failed {
+      base lsp-state-type;
+      description
+        "State setup failed.";
+    }
+
+    identity lsp-state-up {
+      base lsp-state-type;
+      description
+        "State is up.";
+    }
+
+    identity lsp-state-tearing-down {
+      base lsp-state-type;
+      description
+        "State is being torn down.";
+    }
+
+    identity lsp-state-down {
+      base lsp-state-type;
+      description
+        "State is down.";
+    }
+
+  identity path-invalidation-action-type {
+    description
+      "Base identity for TE path invalidation action types.";
+  }
+
+    identity path-invalidation-action-drop {
+      base path-invalidation-action-type;
+      description
+        "Upon invalidation of the TE tunnel path, the tunnel remains
+         valid, but any packet mapped over the tunnel is dropped.";
+      reference
+        "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels,
+                   Section 2.5";
+    }
+
+    identity path-invalidation-action-teardown {
+      base path-invalidation-action-type;
+      description
+        "TE path invalidation action teardown.";
+      reference
+        "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels,
+                   Section 2.5";
+    }
+
+  identity lsp-restoration-type {
+    description
+      "Base identity from which LSP restoration types are derived.";
+  }
+
+    identity lsp-restoration-restore-none {
+      base lsp-restoration-type;
+      description
+        "No LSP affected by a failure is restored.";
+    }
+
+    identity lsp-restoration-restore-any {
+      base lsp-restoration-type;
+      description
+        "Any LSP affected by a failure is restored.";
+    }
+
+    identity lsp-restoration-restore-all {
+      base lsp-restoration-type;
+      description
+        "Affected LSPs are restored after all LSPs of the tunnel are
+         broken.";
+    }
+
+  identity restoration-scheme-type {
+    description
+      "Base identity for LSP restoration schemes.";
+  }
+
+    identity restoration-scheme-rerouting {
+      base restoration-scheme-type;
+      description
+        "Restoration LSP is computed after the failure detection.
+
+         This restoration scheme is also known as
+         'Full LSP Re-routing.'";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery";
+    }
+
+    identity restoration-scheme-preconfigured {
+      base restoration-scheme-type;
+      description
+        "Restoration LSP is preconfigured prior to the failure.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                  Generalized Multi-Protocol Label Switching (GMPLS)
+                  Recovery";
+    }
+
+    identity restoration-scheme-precomputed {
+      base restoration-scheme-type;
+      description
+        "Restoration LSP is precomputed prior to the failure.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                  Generalized Multi-Protocol Label Switching (GMPLS)
+                  Recovery";
+    }
+
+    identity restoration-scheme-presignaled {
+      base restoration-scheme-type;
+      description
+        "Restoration LSP is presignaled prior to the failure.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                  Generalized Multi-Protocol Label Switching (GMPLS)
+                  Recovery";
+    }
+
+  identity lsp-protection-type {
+    description
+      "Base identity from which LSP protection types are derived.";
+    reference
+      "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                 Generalized Multi-Protocol Label Switching (GMPLS)
+                 Recovery";
+  }
+
+    identity lsp-protection-unprotected {
+      base lsp-protection-type;
+      description
+        "'Unprotected' LSP protection type.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery";
+    }
+
+    identity lsp-protection-reroute-extra {
+      base lsp-protection-type;
+      status obsolete;
+      description
+        "'(Full) Rerouting' LSP protection type.
+
+         This identity has been obsoleted: the
+         'restoration-scheme-rerouting' identity SHOULD be used
+         instead.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery";
+    }
+
+    identity lsp-protection-reroute {
+      base lsp-protection-type;
+      status obsolete;
+      description
+        "'Rerouting without Extra-Traffic' LSP protection type.
+
+         This identity has been obsoleted: the
+         'restoration-scheme-rerouting' identity SHOULD be used
+         instead.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery";
+    }
+
+    identity lsp-protection-1-for-n {
+      base lsp-protection-type;
+      description
+        "'1:N Protection with Extra-Traffic' LSP protection type.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery";
+    }
+
+    identity lsp-protection-1-for-1 {
+      base lsp-protection-type;
+      description
+        "LSP protection '1:1 Protection Type'.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery";
+    }
+
+    identity lsp-protection-unidir-1-plus-1 {
+      base lsp-protection-type;
+      description
+        "'1+1 Unidirectional Protection' LSP protection type.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery";
+    }
+
+    identity lsp-protection-bidir-1-plus-1 {
+      base lsp-protection-type;
+      description
+        "'1+1 Bidirectional Protection' LSP protection type.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery";
+    }
+
+    identity lsp-protection-extra-traffic {
+      base lsp-protection-type;
+      description
+        "Extra-Traffic LSP protection type.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery";
+    }
+
+  identity lsp-protection-state {
+    description
+      "Base identity of protection states for reporting purposes.";
+  }
+
+    identity normal {
+      base lsp-protection-state;
+      description
+        "Normal state.";
+      reference
+        "RFC 6378: MPLS Transport Profile (MPLS-TP) Linear Protection
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                   for Generalized Multi-Protocol Label Switching
+                   (GMPLS)";
+    }
+
+    identity signal-fail-of-protection {
+      base lsp-protection-state;
+      description
+        "The protection transport entity has a signal fail condition
+         that is of higher priority than the forced switchover
+         command.";
+      reference
+        "RFC 6378: MPLS Transport Profile (MPLS-TP) Linear Protection
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                   for Generalized Multi-Protocol Label Switching
+                   (GMPLS)";
+    }
+
+    identity lockout-of-protection {
+      base lsp-protection-state;
+      description
+        "A Loss of Protection (LoP) command is active.";
+      reference
+        "RFC 6378: MPLS Transport Profile (MPLS-TP) Linear Protection
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                   for Generalized Multi-Protocol Label Switching
+                   (GMPLS)";
+    }
+
+    identity forced-switch {
+      base lsp-protection-state;
+      description
+        "A forced switchover command is active.";
+      reference
+        "RFC 6378: MPLS Transport Profile (MPLS-TP) Linear Protection
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                   for Generalized Multi-Protocol Label Switching
+                   (GMPLS)";
+    }
+
+    identity signal-fail {
+      base lsp-protection-state;
+      description
+        "There is a signal fail condition on either the working path
+         or the protection path.";
+      reference
+        "RFC 6378: MPLS Transport Profile (MPLS-TP) Linear Protection
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                   for Generalized Multi-Protocol Label Switching
+                   (GMPLS)";
+    }
+
+    identity signal-degrade {
+      base lsp-protection-state;
+      description
+        "There is a signal degrade condition on either the working
+         path or the protection path.";
+      reference
+        "RFC 6378: MPLS Transport Profile (MPLS-TP) Linear Protection
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                   for Generalized Multi-Protocol Label Switching
+                   (GMPLS)";
+    }
+
+    identity manual-switch {
+      base lsp-protection-state;
+      description
+        "A manual switchover command is active.";
+      reference
+        "RFC 6378: MPLS Transport Profile (MPLS-TP) Linear Protection
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                   for Generalized Multi-Protocol Label Switching
+                   (GMPLS)";
+    }
+
+    identity wait-to-restore {
+      base lsp-protection-state;
+      description
+        "A Wait-to-Restore (WTR) timer is running.";
+      reference
+        "RFC 6378: MPLS Transport Profile (MPLS-TP) Linear Protection
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                   for Generalized Multi-Protocol Label Switching
+                   (GMPLS)";
+    }
+
+    identity do-not-revert {
+      base lsp-protection-state;
+      description
+        "A Do Not Revert (DNR) condition is active because of
+         non-revertive behavior.";
+      reference
+        "RFC 6378: MPLS Transport Profile (MPLS-TP) Linear Protection
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                   for Generalized Multi-Protocol Label Switching
+                   (GMPLS)";
+    }
+
+    identity failure-of-protocol {
+      base lsp-protection-state;
+      description
+        "LSP protection is not working because of a protocol failure
+         condition.";
+      reference
+        "RFC 7271: MPLS Transport Profile (MPLS-TP) Linear Protection
+                   to Match the Operational Expectations of
+                   Synchronous Digital Hierarchy, Optical Transport
+                   Network, and Ethernet Transport Network Operators
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                   for Generalized Multi-Protocol Label Switching
+                   (GMPLS)";
+    }
+
+  identity protection-external-commands {
+    description
+      "Base identity from which protection-related external commands
+       used for troubleshooting purposes are derived.";
+  }
+
+    identity action-freeze {
+      base protection-external-commands;
+      description
+        "A temporary configuration action initiated by an operator
+         command that prevents any switchover action from being taken
+         and, as such, freezes the current state.";
+      reference
+        "RFC 7271: MPLS Transport Profile (MPLS-TP) Linear Protection
+                   to Match the Operational Expectations of
+                   Synchronous Digital Hierarchy, Optical Transport
+                   Network, and Ethernet Transport Network Operators
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                   for Generalized Multi-Protocol Label Switching
+                   (GMPLS)";
+    }
+
+    identity clear-freeze {
+      base protection-external-commands;
+      description
+        "An action that clears the active freeze state.";
+      reference
+        "RFC 7271: MPLS Transport Profile (MPLS-TP) Linear Protection
+                   to Match the Operational Expectations of
+                   Synchronous Digital Hierarchy, Optical Transport
+                   Network, and Ethernet Transport Network Operators
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                   for Generalized Multi-Protocol Label Switching
+                   (GMPLS)";
+    }
+
+    identity action-lockout-of-normal {
+      base protection-external-commands;
+      description
+        "A temporary configuration action initiated by an operator
+         command to ensure that the normal traffic is not allowed
+         to use the protection transport entity.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                  for Generalized Multi-Protocol Label Switching
+                  (GMPLS)";
+    }
+
+    identity clear-lockout-of-normal {
+      base protection-external-commands;
+      description
+        "An action that clears the active lockout of the
+         normal state.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                  for Generalized Multi-Protocol Label Switching
+                  (GMPLS)";
+    }
+
+    identity action-lockout-of-protection {
+      base protection-external-commands;
+      description
+        "A temporary configuration action initiated by an operator
+         command to ensure that the protection transport entity is
+         temporarily not available to transport a traffic signal
+         (either normal or Extra-Traffic).";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                  for Generalized Multi-Protocol Label Switching
+                  (GMPLS)";
+    }
+
+    identity action-forced-switch {
+      base protection-external-commands;
+      description
+        "A switchover action initiated by an operator command to
+         switch the Extra-Traffic signal, the normal traffic signal,
+         or the null signal to the protection transport entity,
+         unless a switchover command of equal or higher priority is
+         in effect.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                  for Generalized Multi-Protocol Label Switching
+                  (GMPLS)";
+    }
+
+    identity action-manual-switch {
+      base protection-external-commands;
+      description
+        "A switchover action initiated by an operator command to
+         switch the Extra-Traffic signal, the normal traffic signal,
+         or the null signal to the protection transport entity,
+         unless a fault condition exists on other transport entities
+         or a switchover command of equal or higher priority is in
+         effect.";
+      reference
+        "RFC 4872: RSVP-TE Extensions in Support of End-to-End
+                   Generalized Multi-Protocol Label Switching (GMPLS)
+                   Recovery
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                  for Generalized Multi-Protocol Label Switching
+                  (GMPLS)";
+    }
+
+    identity action-exercise {
+      base protection-external-commands;
+      description
+        "An action that starts testing whether or not Automatic 
+        Protection Switching (APS) communication is operating 
+        correctly.  It is of lower priority than any
+        other state or command.";
+      reference
+        "RFC 7271: MPLS Transport Profile (MPLS-TP) Linear Protection
+                   to Match the Operational Expectations of
+                   Synchronous Digital Hierarchy, Optical Transport
+                   Network, and Ethernet Transport Network Operators
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                   for Generalized Multi-Protocol Label Switching
+                   (GMPLS)";
+    }
+
+    identity clear {
+      base protection-external-commands;
+      description
+        "An action that clears the active near-end lockout of a
+         protection, forced switchover, manual switchover,
+         Wait-to-Restore (WTR) state, or exercise command.";
+      reference
+        "RFC 6378: MPLS Transport Profile (MPLS-TP) Linear Protection
+         RFC 4427: Recovery (Protection and Restoration) Terminology
+                   for Generalized Multi-Protocol Label Switching
+                   (GMPLS)";
+    }
+
+  identity switching-capabilities {
+    description
+      "Base identity for interface switching capabilities.";
+    reference
+      "RFC 3471: Generalized Multi-Protocol Label Switching (GMPLS)
+                 Signaling Functional Description";
+  }
+
+    identity switching-psc1 {
+      base switching-capabilities;
+      description
+        "Packet-Switch Capable-1 (PSC-1).";
+      reference
+        "RFC 3471: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Signaling Functional Description";
+    }
+
+    identity switching-evpl {
+      base switching-capabilities;
+      description
+        "Ethernet Virtual Private Line (EVPL).";
+      reference
+        "RFC 6004: Generalized MPLS (GMPLS) Support for Metro
+                   Ethernet Forum and G.8011 Ethernet Service
+                   Switching";
+    }
+
+    identity switching-l2sc {
+      base switching-capabilities;
+      description
+        "Layer-2 Switch Capable (L2SC).";
+      reference
+        "RFC 3471: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Signaling Functional Description";
+    }
+
+    identity switching-tdm {
+      base switching-capabilities;
+      description
+        "Time-Division-Multiplex Capable (TDM).";
+      reference
+        "RFC 3471: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Signaling Functional Description";
+    }
+
+    identity switching-otn {
+      base switching-capabilities;
+      description
+        "OTN-TDM capable.";
+      reference
+        "RFC 7138: Traffic Engineering Extensions to OSPF for GMPLS
+                  Control of Evolving G.709 Optical Transport
+                  Networks";
+    }
+
+    identity switching-dcsc {
+      base switching-capabilities;
+      description
+        "Data Channel Switching Capable (DCSC).";
+      reference
+        "RFC 6002: Generalized MPLS (GMPLS) Data Channel
+                   Switching Capable (DCSC) and Channel Set Label
+                   Extensions";
+    }
+
+    identity switching-lsc {
+      base switching-capabilities;
+      description
+        "Lambda-Switch Capable (LSC).";
+      reference
+        "RFC 3471: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Signaling Functional Description";
+    }
+
+    identity switching-fsc {
+      base switching-capabilities;
+      description
+        "Fiber-Switch Capable (FSC).";
+      reference
+        "RFC 3471: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Signaling Functional Description";
+    }
+
+  identity lsp-encoding-types {
+    description
+      "Base identity for encoding types.";
+    reference
+      "RFC 3471: Generalized Multi-Protocol Label Switching (GMPLS)
+                 Signaling Functional Description";
+  }
+
+    identity lsp-encoding-packet {
+      base lsp-encoding-types;
+      description
+        "Packet LSP encoding.";
+      reference
+        "RFC 3471: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Signaling Functional Description";
+    }
+
+    identity lsp-encoding-ethernet {
+      base lsp-encoding-types;
+      description
+        "Ethernet LSP encoding.";
+      reference
+        "RFC 3471: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Signaling Functional Description";
+    }
+
+    identity lsp-encoding-pdh {
+      base lsp-encoding-types;
+      description
+        "ANSI/ETSI PDH LSP encoding.";
+      reference
+        "RFC 3471: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Signaling Functional Description";
+    }
+
+    identity lsp-encoding-sdh {
+      base lsp-encoding-types;
+      description
+        "SDH ITU-T G.707 / SONET ANSI T1.105 LSP encoding.";
+      reference
+        "RFC 3471: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Signaling Functional Description";
+    }
+
+    identity lsp-encoding-digital-wrapper {
+      base lsp-encoding-types;
+      description
+        "Digital Wrapper LSP encoding.";
+      reference
+        "RFC 3471: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Signaling Functional Description";
+    }
+
+    identity lsp-encoding-lambda {
+      base lsp-encoding-types;
+      description
+        "Lambda (photonic) LSP encoding.";
+      reference
+        "RFC 3471: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Signaling Functional Description";
+    }
+
+    identity lsp-encoding-fiber {
+      base lsp-encoding-types;
+      description
+        "Fiber LSP encoding.";
+      reference
+        "RFC 3471: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Signaling Functional Description";
+    }
+
+    identity lsp-encoding-fiber-channel {
+      base lsp-encoding-types;
+      description
+        "FiberChannel LSP encoding.";
+      reference
+        "RFC 3471: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Signaling Functional Description";
+    }
+
+    identity lsp-encoding-oduk {
+      base lsp-encoding-types;
+      description
+        "G.709 ODUk (Digital Path) LSP encoding.";
+      reference
+        "RFC 4328: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Signaling Extensions for G.709 Optical Transport
+                   Networks Control";
+    }
+
+    identity lsp-encoding-optical-channel {
+      base lsp-encoding-types;
+      description
+        "G.709 Optical Channel LSP encoding.";
+      reference
+        "RFC 4328: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Signaling Extensions for G.709 Optical Transport
+                   Networks Control";
+    }
+
+    identity lsp-encoding-line {
+      base lsp-encoding-types;
+      description
+        "Line (e.g., 8B/10B) LSP encoding.";
+      reference
+        "RFC 6004: Generalized MPLS (GMPLS) Support for Metro
+                   Ethernet Forum and G.8011 Ethernet Service
+                   Switching";
+    }
+
+  identity path-signaling-type {
+    description
+      "Base identity from which specific LSP path setup types
+       are derived.";
+  }
+
+    identity path-setup-static {
+      base path-signaling-type;
+      description
+        "Static LSP provisioning path setup.";
+    }
+
+    identity path-setup-rsvp {
+      base path-signaling-type;
+      description
+        "RSVP-TE signaling path setup.";
+      reference
+        "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels";
+    }
+
+    identity path-setup-sr {
+      base path-signaling-type;
+      description
+        "Segment-routing path setup.";
+    }
+
+  identity path-scope-type {
+    description
+      "Base identity from which specific path scope types are
+       derived.";
+  }
+
+    identity path-scope-segment {
+      base path-scope-type;
+      description
+        "Path scope segment.";
+      reference
+        "RFC 4873: GMPLS Segment Recovery";
+    }
+
+    identity path-scope-end-to-end {
+      base path-scope-type;
+      description
+        "Path scope end to end.";
+      reference
+        "RFC 4873: GMPLS Segment Recovery";
+    }
+
+  identity route-usage-type {
+    description
+      "Base identity for route usage.";
+  }
+
+    identity route-include-object {
+      base route-usage-type;
+      description
+        "'Include route' object.";
+    }
+
+    identity route-exclude-object {
+      base route-usage-type;
+      description
+        "'Exclude route' object.";
+      reference
+        "RFC 4874: Exclude Routes - Extension to Resource ReserVation
+                   Protocol-Traffic Engineering (RSVP-TE)";
+    }
+
+    identity route-exclude-srlg {
+      base route-usage-type;
+      description
+        "Excludes SRLGs.";
+      reference
+        "RFC 4874: Exclude Routes - Extension to Resource ReserVation
+                   Protocol-Traffic Engineering (RSVP-TE)";
+    }
+
+  identity path-metric-optimization-type {
+    description
+      "Base identity used to define the path metric optimization
+       types.";
+  }
+
+  identity link-path-metric-type {
+    description
+      "Base identity used to define the link and the path metric
+       types.
+
+       The unit of the path metric value is interpreted in the
+       context of the path metric type and the derived identities
+       SHOULD describe the unit of the path metric types they
+       define.";
+  }
+
+    identity link-metric-type {
+      base link-path-metric-type;
+      description
+        "Base identity for the link metric types.";
+    }
+
+      identity link-metric-te {
+        base link-metric-type;
+        description
+          "Traffic Engineering (TE) Link Metric.";
+        reference
+          "RFC 3630: Traffic Engineering (TE) Extensions to OSPF
+                     Version 2, Section 2.5.5
+           RFC 5305: IS-IS Extensions for Traffic Engineering,
+                     Section 3.7";
+      }
+
+      identity link-metric-igp {
+        base link-metric-type;
+        description
+          "Interior Gateway Protocol (IGP) Link Metric.";
+        reference
+          "RFC 3785: Use of Interior Gateway Protocol (IGP) Metric
+                     as a second MPLS Traffic Engineering (TE)
+                     Metric";
+      }
+
+      identity link-metric-delay-average {
+        base link-metric-type;
+        description
+          "Unidirectional Link Delay, measured in units of
+           microseconds.";
+        reference
+          "RFC 7471: OSPF Traffic Engineering (TE) Metric
+                     Extensions, Section 4.1        
+           RFC 8570: IS-IS Traffic Engineering (TE) Metric
+                     Extensions, Section 4.1";
+      }
+
+      identity link-metric-delay-minimum {
+        base link-metric-type;
+        description
+          "Minimum unidirectional Link Delay, measured in units of
+           microseconds.";
+        reference
+          "RFC 7471: OSPF Traffic Engineering (TE) Metric
+                     Extensions, Section 4.2
+           RFC 8570: IS-IS Traffic Engineering (TE) Metric
+                     Extensions, Section 4.2";
+      }
+
+      identity link-metric-delay-maximum {
+        base link-metric-type;
+        description
+          "Maximum unidirectional Link Delay, measured in units of
+           microseconds.";
+        reference
+          "RFC 7471: OSPF Traffic Engineering (TE) Metric
+                     Extensions, Section 4.2
+           RFC 8570: IS-IS Traffic Engineering (TE) Metric
+                     Extensions, Section 4.2";
+      }
+
+      identity link-metric-residual-bandwidth {
+        base link-metric-type;
+        description
+          "Unidirectional Residual Bandwidth, measured in units of
+           bytes per second.
+
+           It is defined to be Maximum Bandwidth minus the bandwidth
+           currently allocated to LSPs.";
+        reference
+          "RFC 7471: OSPF Traffic Engineering (TE) Metric
+                     Extensions, Section 4.5
+           RFC 8570: IS-IS Traffic Engineering (TE) Metric
+                     Extensions, Section 4.5";
+      }
+
+    identity path-metric-type {
+      base link-path-metric-type;
+      base path-metric-optimization-type;
+      description
+        "Base identity for the path metric types.";
+    }
+
+      identity path-metric-te {
+        base path-metric-type;
+        description
+          "Traffic Engineering (TE) Path Metric.";
+        reference
+          "RFC 5440: Path Computation Element (PCE) Communication
+                     Protocol (PCEP), Section 7.8";
+      }
+
+      identity path-metric-igp {
+        base path-metric-type;
+        description
+          "Interior Gateway Protocol (IGP) Path Metric.";
+        reference
+          "RFC 5440: Path Computation Element (PCE) Communication
+                     Protocol (PCEP), section 7.8";
+      }
+
+      identity path-metric-hop {
+        base path-metric-type;
+        description
+          "Hop Count Path Metric.";
+        reference
+          "RFC 5440: Path Computation Element (PCE) Communication
+                     Protocol (PCEP), Section 7.8";
+      }
+
+      identity path-metric-delay-average {
+        base path-metric-type;
+        description
+          "The Path Delay Metric, measured in units of
+           microseconds.";
+        reference
+          "RFC8233: Extensions to the Path Computation Element
+                    Communication Protocol (PCEP) to Compute
+                    Service-Aware Label Switched Paths (LSPs),
+                    Section 3.1.1";
+      }
+
+      identity path-metric-delay-minimum {
+        base path-metric-type;
+        description
+          "The Path Min Delay Metric, measured in units of
+           microseconds.";
+        reference
+          "I-D.ietf-pce-sid-algo: Carrying SR-Algorithm information
+                                  in PCE-based Networks,
+                                  draft-ietf-pce-sid-algo-14,
+                                  Sections 3.5.1 and 3.5.2";
+      }
+
+      identity path-metric-residual-bandwidth {
+        base path-metric-type;
+        description
+          "The Path Residual Bandwidth, defined as the minimum Link
+           Residual Bandwidth all the links along the path.
+
+           The Path Residual Bandwidth can be seen as the path
+           metric associated with the Maximum residual Bandwidth Path
+           (MBP) objective function.";
+        reference
+          "RFC 5541: Encoding of Objective Functions in the Path
+                     Computation Element Communication Protocol
+                     (PCEP)";
+      }
+
+    identity path-metric-optimize-includes {
+      base path-metric-optimization-type;
+      description
+        "A metric that optimizes the number of included resources
+         specified in a set.";
+    }
+
+    identity path-metric-optimize-excludes {
+      base path-metric-optimization-type;
+      description
+        "A metric that optimizes to a maximum the number of excluded
+         resources specified in a set.";
+    }
+
+  identity path-tiebreaker-type {
+    description
+      "Base identity for the path tiebreaker type.";
+  }
+
+    identity path-tiebreaker-minfill {
+      base path-tiebreaker-type;
+      description
+        "Min-Fill LSP path placement: selects the path with the most
+         available bandwidth (load balance LSPs over more links).";
+    }
+
+    identity path-tiebreaker-maxfill {
+      base path-tiebreaker-type;
+      description
+        "Max-Fill LSP path placement: selects the path with the least
+         available bandwidth (packing more LSPs over few links).";
+    }
+
+    identity path-tiebreaker-random {
+      base path-tiebreaker-type;
+      description
+        "Random LSP path placement.";
+    }
+
+  identity resource-affinities-type {
+    description
+      "Base identity for resource class affinities.";
+    reference
+      "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels
+       RFC 2702: Requirements for Traffic Engineering Over MPLS";
+  }
+
+    identity resource-aff-include-all {
+      base resource-affinities-type;
+      description
+        "The set of attribute filters associated with a
+         tunnel, all of which must be present for a link
+         to be acceptable.";
+      reference
+        "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels
+         RFC 2702: Requirements for Traffic Engineering Over MPLS";
+    }
+
+    identity resource-aff-include-any {
+      base resource-affinities-type;
+      description
+        "The set of attribute filters associated with a
+         tunnel, any of which must be present for a link
+         to be acceptable.";
+      reference
+        "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels
+         RFC 2702: Requirements for Traffic Engineering Over MPLS";
+    }
+
+    identity resource-aff-exclude-any {
+      base resource-affinities-type;
+      description
+        "The set of attribute filters associated with a
+         tunnel, any of which renders a link unacceptable.";
+      reference
+        "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels
+         RFC 2702: Requirements for Traffic Engineering Over MPLS";
+    }
+
+  identity te-optimization-criterion {
+    description
+      "Base identity for the TE optimization criteria.";
+    reference
+      "RFC 9522: Overview and Principles of Internet Traffic
+                 Engineering";
+  }
+
+    identity not-optimized {
+      base te-optimization-criterion;
+      description
+        "Optimization is not applied.";
+    }
+
+    identity cost {
+      base te-optimization-criterion;
+      description
+        "Optimized on cost.";
+      reference
+        "RFC 5541: Encoding of Objective Functions in the Path
+                    Computation Element Communication Protocol
+                    (PCEP)";
+    }
+
+    identity delay {
+      base te-optimization-criterion;
+      description
+        "Optimized on delay.";
+      reference
+        "RFC 5541: Encoding of Objective Functions in the Path
+                    Computation Element Communication Protocol
+                    (PCEP)";
+    }
+
+  identity path-computation-srlg-type {
+    description
+      "Base identity for SRLG path computation.";
+  }
+
+    identity srlg-ignore {
+      base path-computation-srlg-type;
+      description
+        "Ignores SRLGs in the path computation.";
+    }
+
+    identity srlg-strict {
+      base path-computation-srlg-type;
+      description
+        "Includes a strict SRLG check in the path computation.";
+    }
+
+    identity srlg-preferred {
+      base path-computation-srlg-type;
+      description
+        "Includes a preferred SRLG check in the path computation.";
+    }
+
+    identity srlg-weighted {
+      base path-computation-srlg-type;
+      description
+        "Includes a weighted SRLG check in the path computation.";
+    }
+
+  identity path-computation-error-reason {
+    description
+      "Base identity for path computation error reasons.";
+  }
+
+    identity path-computation-error-path-not-found {
+      base path-computation-error-reason;
+      description
+        "Path computation has failed because of an unspecified 
+         reason.";
+      reference
+        "RFC 5440: Path Computation Element (PCE) Communication
+                   Protocol (PCEP), Section 7.5";
+    }
+
+    identity path-computation-error-no-topology {
+      base path-computation-error-reason;
+      description
+        "Path computation has failed because there is no topology
+         with the provided topology-identifier.";
+    }
+
+    identity path-computation-error-no-dependent-server {
+      base path-computation-error-reason;
+      description
+        "Path computation has failed because one or more dependent
+         path computation servers are unavailable.
+
+         The dependent path computation server could be
+         a Backward-Recursive Path Computation (BRPC) downstream
+         PCE or a child PCE.";
+      reference
+        "RFC 5441: A Backward-Recursive PCE-Based Computation (BRPC)
+                   Procedure to Compute Shortest Constrained
+                   Inter-Domain Traffic Engineering Label Switched
+                   Paths
+         RFC 8685: Path Computation Element Communication Protocol
+                   (PCEP) Extensions for the Hierarchical Path
+                   Computation Element (H-PCE) Architecture";
+    }
+
+    identity path-computation-error-pce-unavailable {
+      base path-computation-error-reason;
+      description
+        "Path computation has failed because PCE is not available.
+
+         It corresponds to bit 31 of the Flags field of the 
+         NO-PATH-VECTOR TLV.";
+      reference
+        "RFC 5440: Path Computation Element (PCE) Communication
+                   Protocol (PCEP)
+
+         https://www.iana.org/assignments/pcep
+         /pcep.xhtml#no-path-vector-tlv";
+    }
+
+    identity path-computation-error-no-inclusion-hop {
+      base path-computation-error-reason;
+      description
+        "Path computation has failed because there is no
+         node or link provided by one or more inclusion hops.";
+    }
+
+    identity path-computation-error-destination-unknown-in-domain {
+      base path-computation-error-reason;
+      description
+        "Path computation has failed because the destination node is
+         unknown in indicated destination domain.
+
+         It corresponds to bit 19 of the Flags field of the 
+         NO-PATH-VECTOR TLV.";
+      reference
+        "RFC 8685: Path Computation Element Communication Protocol
+                   (PCEP) Extensions for the Hierarchical Path
+                   Computation Element (H-PCE) Architecture
+
+         https://www.iana.org/assignments/pcep
+         /pcep.xhtml#no-path-vector-tlv";
+    }
+
+    identity path-computation-error-no-resource {
+      base path-computation-error-reason;
+      description
+        "Path computation has failed because there is no
+         available resource in one or more domains.
+
+         It corresponds to bit 20 of the Flags field of the 
+         NO-PATH-VECTOR TLV.";
+      reference
+        "RFC 8685: Path Computation Element Communication Protocol
+                   (PCEP) Extensions for the Hierarchical Path
+                   Computation Element (H-PCE) Architecture
+
+         https://www.iana.org/assignments/pcep
+         /pcep.xhtml#no-path-vector-tlv";
+    }
+
+    identity path-computation-error-child-pce-unresponsive {
+      base path-computation-error-no-dependent-server;
+      description
+        "Path computation has failed because child PCE is not
+         responsive.
+
+         It corresponds to bit 21 of the Flags field of the 
+         NO-PATH-VECTOR TLV.";
+      reference
+        "RFC 8685: Path Computation Element Communication Protocol
+                   (PCEP) Extensions for the Hierarchical Path
+                   Computation Element (H-PCE) Architecture
+
+         https://www.iana.org/assignments/pcep
+         /pcep.xhtml#no-path-vector-tlv";
+    }
+
+    identity path-computation-error-destination-domain-unknown {
+      base path-computation-error-reason;
+      description
+        "Path computation has failed because the destination domain
+         was unknown.
+
+         It corresponds to bit 22 of the Flags field of the 
+         NO-PATH-VECTOR TLV.";
+      reference
+        "RFC 8685: Path Computation Element Communication Protocol
+                   (PCEP) Extensions for the Hierarchical Path
+                   Computation Element (H-PCE) Architecture
+
+         https://www.iana.org/assignments/pcep
+         /pcep.xhtml#no-path-vector-tlv";
+    }
+
+    identity path-computation-error-p2mp {
+      base path-computation-error-reason;
+      description
+        "Path computation has failed because of P2MP reachability
+         problem.
+
+         It corresponds to bit 24 of the Flags field of the 
+         NO-PATH-VECTOR TLV.";
+      reference
+        "RFC 8306: Extensions to the Path Computation Element
+                   Communication Protocol (PCEP) for
+                   Point-to-Multipoint Traffic Engineering Label
+                   Switched Paths
+
+         https://www.iana.org/assignments/pcep
+         /pcep.xhtml#no-path-vector-tlv";
+    }
+
+    identity path-computation-error-no-gco-migration {
+      base path-computation-error-reason;
+      description
+        "Path computation has failed because of no Global Concurrent
+         Optimization (GCO) migration path found.
+
+         It corresponds to bit 26 of the Flags field of the 
+         NO-PATH-VECTOR TLV.";
+      reference
+        "RFC 5557: Path Computation Element Communication Protocol
+                   (PCEP) Requirements and Protocol Extensions in
+                   Support of Global Concurrent Optimization
+
+         https://www.iana.org/assignments/pcep
+         /pcep.xhtml#no-path-vector-tlv";
+    }
+
+    identity path-computation-error-no-gco-solution {
+      base path-computation-error-reason;
+      description
+        "Path computation has failed because of no GCO solution
+         found.
+
+         It corresponds to bit 25 of the Flags field of the 
+         NO-PATH-VECTOR TLV.";
+      reference
+        "RFC 5557: Path Computation Element Communication Protocol
+                   (PCEP) Requirements and Protocol Extensions in
+                   Support of Global Concurrent Optimization
+
+         https://www.iana.org/assignments/pcep
+         /pcep.xhtml#no-path-vector-tlv";
+    }
+
+    identity path-computation-error-pks-expansion {
+      base path-computation-error-reason;
+      description
+        "Path computation has failed because of Path-Key Subobject
+         (PKS)  expansion failure.
+
+         It corresponds to bit 27 of the Flags field of the 
+         NO-PATH-VECTOR TLV.";
+      reference
+        "RFC 5520: Preserving Topology Confidentiality in
+                   Inter-Domain Path Computation Using a
+                   Path-Key-Based Mechanism
+
+         https://www.iana.org/assignments/pcep
+         /pcep.xhtml#no-path-vector-tlv";
+    }
+
+    identity path-computation-error-brpc-chain-unavailable {
+      base path-computation-error-no-dependent-server;
+      description
+        "Path computation has failed because PCE BRPC chain
+         unavailable.
+
+         It corresponds to bit 28 of the Flags field of the 
+         NO-PATH-VECTOR TLV.";
+      reference
+        "RFC 5441: A Backward-Recursive PCE-Based Computation (BRPC)
+                   Procedure to Compute Shortest Constrained
+                   Inter-Domain Traffic Engineering Label Switched
+                   Paths
+
+         https://www.iana.org/assignments/pcep
+         /pcep.xhtml#no-path-vector-tlv";
+    }
+
+    identity path-computation-error-source-unknown {
+      base path-computation-error-reason;
+      description
+        "Path computation has failed because source node is 
+         unknown.
+
+         It corresponds to bit 29 of the Flags field of the 
+         NO-PATH-VECTOR TLV.";
+      reference
+        "RFC 5440: Path Computation Element (PCE) Communication
+                   Protocol (PCEP);
+
+         https://www.iana.org/assignments/pcep
+         /pcep.xhtml#no-path-vector-tlv";
+    }
+
+    identity path-computation-error-destination-unknown {
+      base path-computation-error-reason;
+      description
+        "Path computation has failed because destination node is
+         unknown.
+
+         It corresponds to bit 30 of the Flags field of the 
+         NO-PATH-VECTOR TLV.";
+      reference
+        "RFC 5440: Path Computation Element (PCE) Communication
+        Protocol (PCEP);
+
+         https://www.iana.org/assignments/pcep
+         /pcep.xhtml#no-path-vector-tlv";
+    }
+
+    identity path-computation-error-no-server {
+      base path-computation-error-reason;
+      description
+        "Path computation has failed because path computation
+         server is unavailable.";
+      reference
+        "RFC 5440: Path Computation Element (PCE) Communication
+                   Protocol (PCEP);
+
+         https://www.iana.org/assignments/pcep
+         /pcep.xhtml#no-path-vector-tlv";
+    }
+
+  identity protocol-origin-type {
+    description
+      "Base identity for protocol origin type.";
+  }
+
+    identity protocol-origin-api {
+      base protocol-origin-type;
+      description
+        "Protocol origin is via Application Programming Interface
+         (API).";
+    }
+
+    identity protocol-origin-pcep {
+      base protocol-origin-type;
+      description
+        "Protocol origin is Path Computation Engine Protocol 
+         (PCEP).";
+      reference
+        "RFC 5440: Path Computation Element (PCE) Communication
+                   Protocol (PCEP)";
+    }
+
+    identity protocol-origin-bgp {
+      base protocol-origin-type;
+      description
+        "Protocol origin is Border Gateway Protocol (BGP).";
+      reference
+        "RFC 9012: The BGP Tunnel Encapsulation Attribute";
+    }
+
+  identity svec-objective-function-type {
+    description
+      "Base identity for SVEC objective function type.";
+    reference
+      "RFC 5541: Encoding of Objective Functions in the Path
+                 Computation Element Communication Protocol (PCEP)";
+  }
+
+    identity svec-of-minimize-agg-bandwidth-consumption {
+      base svec-objective-function-type;
+      description
+        "Objective function for minimizing aggregate bandwidth 
+         consumption (MBC).";
+      reference
+        "RFC 5541: Encoding of Objective Functions in the Path
+                   Computation Element Communication Protocol
+                   (PCEP)";
+    }
+
+    identity svec-of-minimize-load-most-loaded-link {
+      base svec-objective-function-type;
+      description
+        "Objective function for minimizing the load on the link that 
+         is carrying the highest load (MLL).";
+      reference
+        "RFC 5541: Encoding of Objective Functions in the Path
+                   Computation Element Communication Protocol
+                   (PCEP)";
+    }
+
+    identity svec-of-minimize-cost-path-set {
+      base svec-objective-function-type;
+      description
+        "Objective function for minimizing the cost on a path set 
+         (MCC).";
+      reference
+        "RFC 5541: Encoding of Objective Functions in the Path
+                   Computation Element Communication Protocol
+                   (PCEP)";
+    }
+
+    identity svec-of-minimize-common-transit-domain {
+      base svec-objective-function-type;
+      description
+        "Objective function for minimizing the number of common 
+         transit domains (MCTD).";
+      reference
+        "RFC 8685: Path Computation Element Communication Protocol 
+                   (PCEP) Extensions for the Hierarchical Path
+                   Computation Element (H-PCE) Architecture.";
+    }
+
+    identity svec-of-minimize-shared-link {
+      base svec-objective-function-type;
+      description
+        "Objective function for minimizing the number of shared 
+         links (MSL).";
+      reference
+        "RFC 8685: Path Computation Element Communication Protocol 
+                   (PCEP) Extensions for the Hierarchical Path
+                   Computation Element (H-PCE) Architecture.";
+    }
+
+    identity svec-of-minimize-shared-srlg {
+      base svec-objective-function-type;
+      description
+        "Objective function for minimizing the number of shared 
+         Shared Risk Link Groups (SRLG) (MSS).";
+      reference
+        "RFC 8685: Path Computation Element Communication Protocol 
+                   (PCEP) Extensions for the Hierarchical Path
+                   Computation Element (H-PCE) Architecture.";
+    }
+
+    identity svec-of-minimize-shared-nodes {
+      base svec-objective-function-type;
+      description
+        "Objective function for minimizing the number of shared 
+         nodes (MSN).";
+      reference
+        "RFC 8685: Path Computation Element Communication Protocol
+                   (PCEP) Extensions for the Hierarchical Path
+                   Computation Element (H-PCE) Architecture.";
+    }
+
+  identity svec-metric-type {
+    description
+      "Base identity for SVEC metric type.";
+    reference
+      "RFC 5541: Encoding of Objective Functions in the Path
+                 Computation Element Communication Protocol (PCEP)";
+  }
+
+    identity svec-metric-cumulative-te {
+      base svec-metric-type;
+      description
+        "Cumulative TE cost.";
+      reference
+        "RFC 5541: Encoding of Objective Functions in the Path
+                   Computation Element Communication Protocol
+                   (PCEP)";
+    }
+
+    identity svec-metric-cumulative-igp {
+      base svec-metric-type;
+      description
+        "Cumulative IGP cost.";
+      reference
+        "RFC 5541: Encoding of Objective Functions in the Path
+                   Computation Element Communication Protocol
+                   (PCEP)";
+    }
+
+    identity svec-metric-cumulative-hop {
+      base svec-metric-type;
+      description
+        "Cumulative Hop path metric.";
+      reference
+        "RFC 5541: Encoding of Objective Functions in the Path
+                   Computation Element Communication Protocol
+                   (PCEP)";
+    }
+
+    identity svec-metric-aggregate-bandwidth-consumption {
+      base svec-metric-type;
+      description
+        "Aggregate bandwidth consumption.";
+      reference
+        "RFC 5541: Encoding of Objective Functions in the Path
+                   Computation Element Communication Protocol
+                   (PCEP)";
+    }
+
+    identity svec-metric-load-of-the-most-loaded-link {
+      base svec-metric-type;
+      description
+        "Load of the most loaded link.";
+      reference
+        "RFC 5541: Encoding of Objective Functions in the Path
+                   Computation Element Communication Protocol
+                   (PCEP)";
+    }
+
+  /**
+   * TE bandwidth groupings
+   **/
+
+  grouping te-bandwidth {
+    description
+      "This grouping defines the generic TE bandwidth.
+       For some known data-plane technologies, specific modeling
+       structures are specified.  The string-encoded 'te-bandwidth'
+       type is used for unspecified technologies.
+       The modeling structure can be augmented later for other
+       technologies.";
+    container te-bandwidth {
+      description
+        "Container that specifies TE bandwidth.  The choices
+         can be augmented for specific data-plane technologies.";
+      choice technology {
+        default "generic";
+        description
+          "Data-plane technology type.";
+        case generic {
+          leaf generic {
+            type te-bandwidth;
+            description
+              "Bandwidth specified in a generic format.";
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * TE label groupings
+   **/
+
+  grouping te-label {
+    description
+      "This grouping defines the generic TE label.
+       The modeling structure can be augmented for each technology.
+       For unspecified technologies, 'rt-types:generalized-label'
+       is used.";
+    container te-label {
+      description
+        "Container that specifies the TE label.  The choices can
+         be augmented for specific data-plane technologies.";
+      choice technology {
+        default "generic";
+        description
+          "Data-plane technology type.";
+        case generic {
+          leaf generic {
+            type rt-types:generalized-label;
+            description
+              "TE label specified in a generic format.";
+          }
+        }
+      }
+      leaf direction {
+        type te-label-direction;
+        default "forward";
+        description
+          "Label direction.";
+      }
+    }
+  }
+
+  grouping te-topology-identifier {
+    description
+      "Augmentation for a TE topology.";
+    container te-topology-identifier {
+      description
+        "TE topology identifier container.";
+      leaf provider-id {
+        type te-global-id;
+        default "0";
+        description
+          "An identifier to uniquely identify a provider.
+           If omitted, it assumes that the topology provider ID
+           value = 0 (the default).";
+      }
+      leaf client-id {
+        type te-global-id;
+        default "0";
+        description
+          "An identifier to uniquely identify a client.
+           If omitted, it assumes that the topology client ID
+           value = 0 (the default).";
+      }
+      leaf topology-id {
+        type te-topology-id;
+        default "";
+        description
+          "When the datastore contains several topologies,
+           'topology-id' distinguishes between them.  If omitted,
+           the default (empty) string for this leaf is assumed.";
+      }
+    }
+  }
+
+  /**
+   * TE performance metrics groupings
+   **/
+
+  grouping performance-metrics-one-way-delay-loss {
+    description
+      "Performance Metrics (PM) information in real time that can
+       be applicable to links or connections.  PM defined in this
+       grouping are applicable to generic TE PM as well as packet TE
+       PM.";
+    reference
+      "RFC 7471: OSPF Traffic Engineering (TE) Metric Extensions
+       RFC 8570: IS-IS Traffic Engineering (TE) Metric Extensions
+       RFC 7823: Performance-Based Path Selection for Explicitly
+                 Routed Label Switched Paths (LSPs) Using TE Metric
+                 Extensions";
+    leaf one-way-delay {
+      type uint32 {
+        range "0..16777215";
+      }
+      description
+        "One-way delay or latency in microseconds.";
+    }
+    leaf one-way-delay-normality {
+      type te-types:performance-metrics-normality;
+      description
+        "One-way delay normality.";
+    }
+  }
+
+  grouping performance-metrics-two-way-delay-loss {
+    description
+      "PM information in real time that can be applicable to links or
+       connections.  PM defined in this grouping are applicable to
+       generic TE PM as well as packet TE PM.";
+    reference
+      "RFC 7471: OSPF Traffic Engineering (TE) Metric Extensions
+       RFC 8570: IS-IS Traffic Engineering (TE) Metric Extensions
+       RFC 7823: Performance-Based Path Selection for Explicitly
+                 Routed Label Switched Paths (LSPs) Using TE Metric
+                 Extensions";
+    leaf two-way-delay {
+      type uint32 {
+        range "0..16777215";
+      }
+      description
+        "Two-way delay or latency in microseconds.";
+    }
+    leaf two-way-delay-normality {
+      type te-types:performance-metrics-normality;
+      description
+        "Two-way delay normality.";
+    }
+  }
+
+  grouping performance-metrics-one-way-bandwidth {
+    description
+      "PM information in real time that can be applicable to links.
+       PM defined in this grouping are applicable to generic TE PM
+       as well as packet TE PM.";
+    reference
+      "RFC 7471: OSPF Traffic Engineering (TE) Metric Extensions
+       RFC 8570: IS-IS Traffic Engineering (TE) Metric Extensions
+       RFC 7823: Performance-Based Path Selection for Explicitly
+                 Routed Label Switched Paths (LSPs) Using TE Metric
+                 Extensions";
+    leaf one-way-residual-bandwidth {
+      type rt-types:bandwidth-ieee-float32;
+      units "bytes per second";
+      default "0x0p0";
+      description
+        "Residual bandwidth that subtracts tunnel reservations from
+         Maximum Bandwidth (or link capacity) (RFC 3630) and
+         provides an aggregated remainder across QoS classes.";
+      reference
+        "RFC 3630: Traffic Engineering (TE) Extensions to OSPF
+                   Version 2";
+    }
+    leaf one-way-residual-bandwidth-normality {
+      type te-types:performance-metrics-normality;
+      default "normal";
+      description
+        "Residual bandwidth normality.";
+    }
+    leaf one-way-available-bandwidth {
+      type rt-types:bandwidth-ieee-float32;
+      units "bytes per second";
+      default "0x0p0";
+      description
+        "Available bandwidth that is defined to be residual
+         bandwidth minus the measured bandwidth used for the
+         actual forwarding of non-RSVP-TE LSP packets.  For a
+         bundled link, available bandwidth is defined to be the
+         sum of the component link available bandwidths.";
+    }
+    leaf one-way-available-bandwidth-normality {
+      type te-types:performance-metrics-normality;
+      default "normal";
+      description
+        "Available bandwidth normality.";
+    }
+    leaf one-way-utilized-bandwidth {
+      type rt-types:bandwidth-ieee-float32;
+      units "bytes per second";
+      default "0x0p0";
+      description
+        "Bandwidth utilization that represents the actual
+         utilization of the link (i.e., as measured in the router).
+         For a bundled link, bandwidth utilization is defined to
+         be the sum of the component link bandwidth utilizations.";
+    }
+    leaf one-way-utilized-bandwidth-normality {
+      type te-types:performance-metrics-normality;
+      default "normal";
+      description
+        "Bandwidth utilization normality.";
+    }
+  }
+
+  grouping one-way-performance-metrics {
+    description
+      "One-way PM throttle grouping.";
+    leaf one-way-delay {
+      type uint32 {
+        range "0..16777215";
+      }
+      default "0";
+      description
+        "One-way delay or latency in microseconds.";
+    }
+    leaf one-way-residual-bandwidth {
+      type rt-types:bandwidth-ieee-float32;
+      units "bytes per second";
+      default "0x0p0";
+      description
+        "Residual bandwidth that subtracts tunnel reservations from
+         Maximum Bandwidth (or link capacity) (RFC 3630) and
+         provides an aggregated remainder across QoS classes.";
+      reference
+        "RFC 3630: Traffic Engineering (TE) Extensions to OSPF
+                   Version 2";
+    }
+    leaf one-way-available-bandwidth {
+      type rt-types:bandwidth-ieee-float32;
+      units "bytes per second";
+      default "0x0p0";
+      description
+        "Available bandwidth that is defined to be residual
+         bandwidth minus the measured bandwidth used for the
+         actual forwarding of non-RSVP-TE LSP packets.  For a
+         bundled link, available bandwidth is defined to be the
+         sum of the component link available bandwidths.";
+    }
+    leaf one-way-utilized-bandwidth {
+      type rt-types:bandwidth-ieee-float32;
+      units "bytes per second";
+      default "0x0p0";
+      description
+        "Bandwidth utilization that represents the actual
+         utilization of the link (i.e., as measured in the router).
+         For a bundled link, bandwidth utilization is defined to
+         be the sum of the component link bandwidth utilizations.";
+    }
+  }
+
+  grouping two-way-performance-metrics {
+    description
+      "Two-way PM throttle grouping.";
+    leaf two-way-delay {
+      type uint32 {
+        range "0..16777215";
+      }
+      default "0";
+      description
+        "Two-way delay or latency in microseconds.";
+    }
+  }
+
+  grouping performance-metrics-thresholds {
+    description
+      "Grouping for configurable thresholds for measured
+       attributes.";
+    uses one-way-performance-metrics;
+    uses two-way-performance-metrics;
+  }
+
+  grouping performance-metrics-attributes {
+    description
+      "Contains PM attributes.";
+    container performance-metrics-one-way {
+      description
+        "One-way link performance information in real time.";
+      reference
+        "RFC 7471: OSPF Traffic Engineering (TE) Metric Extensions
+         RFC 8570: IS-IS Traffic Engineering (TE) Metric Extensions
+         RFC 7823: Performance-Based Path Selection for Explicitly
+                   Routed Label Switched Paths (LSPs) Using TE Metric
+                   Extensions";
+      uses performance-metrics-one-way-delay-loss;
+      uses performance-metrics-one-way-bandwidth;
+    }
+    container performance-metrics-two-way {
+      description
+        "Two-way link performance information in real time.";
+      reference
+        "RFC 6374: Packet Loss and Delay Measurement for MPLS
+                   Networks";
+      uses performance-metrics-two-way-delay-loss;
+    }
+  }
+
+  grouping performance-metrics-throttle-container {
+    description
+      "Controls PM throttling.";
+    container throttle {
+      must 'suppression-interval >= measure-interval' {
+        error-message "'suppression-interval' cannot be less than "
+                    + "'measure-interval'.";
+        description
+          "Constraint on 'suppression-interval' and
+           'measure-interval'.";
+      }
+      description
+        "Link performance information in real time.";
+      reference
+        "RFC 7471: OSPF Traffic Engineering (TE) Metric Extensions
+         RFC 8570: IS-IS Traffic Engineering (TE) Metric Extensions
+         RFC 7823: Performance-Based Path Selection for Explicitly
+                   Routed Label Switched Paths (LSPs) Using TE Metric
+                   Extensions";
+      leaf one-way-delay-offset {
+        type uint32 {
+          range "0..16777215";
+        }
+        default "0";
+        description
+          "Offset value to be added to the measured delay value.";
+      }
+      leaf measure-interval {
+        type uint32;
+        default "30";
+        description
+          "Interval, in seconds, to measure the extended metric
+           values.";
+      }
+      leaf advertisement-interval {
+        type uint32;
+        default "0";
+        description
+          "Interval, in seconds, to advertise the extended metric
+           values.";
+      }
+      leaf suppression-interval {
+        type uint32 {
+          range "1..max";
+        }
+        default "120";
+        description
+          "Interval, in seconds, to suppress advertisement of the
+           extended metric values.";
+        reference
+          "RFC 8570: IS-IS Traffic Engineering (TE) Metric
+                     Extensions, Section 6";
+      }
+      container threshold-out {
+        uses performance-metrics-thresholds;
+        description
+          "If the measured parameter falls outside an upper bound
+           for all but the minimum-delay metric (or a lower bound
+           for the minimum-delay metric only) and the advertised
+           value is not already outside that bound, an 'anomalous'
+           announcement (anomalous bit set) will be triggered.";
+      }
+      container threshold-in {
+        uses performance-metrics-thresholds;
+        description
+          "If the measured parameter falls inside an upper bound
+           for all but the minimum-delay metric (or a lower bound
+           for the minimum-delay metric only) and the advertised
+           value is not already inside that bound, a 'normal'
+           announcement (anomalous bit cleared) will be triggered.";
+      }
+      container threshold-accelerated-advertisement {
+        description
+          "When the difference between the last advertised value and
+           the current measured value exceeds this threshold, an
+           'anomalous' announcement (anomalous bit set) will be
+           triggered.";
+        uses performance-metrics-thresholds;
+      }
+    }
+  }
+
+  /**
+   * TE tunnel generic groupings
+   **/
+
+  grouping explicit-route-hop {
+    description
+      "The explicit route entry grouping.";
+    choice type {
+      description
+        "The explicit route entry type.";
+      case numbered-node-hop {
+        container numbered-node-hop {
+          must "node-id-uri or node-id" {
+            description
+              "At least one node identifier MUST be present.";
+          }
+          leaf node-id-uri {
+            type nw:node-id;
+            description
+              "The identifier of a node in the topology.";
+          }
+          leaf node-id {
+            type te-node-id;
+            description
+              "The identifier of a node in the TE topology.";
+          }
+          leaf hop-type {
+            type te-hop-type;
+            default "strict";
+            description
+              "Strict or loose hop.";
+          }
+          description
+            "Numbered node route hop.";
+          reference
+            "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels,
+                       Section 4.3, EXPLICIT_ROUTE in RSVP-TE
+             RFC 3477: Signalling Unnumbered Links in Resource
+                       ReSerVation Protocol - Traffic Engineering
+                       (RSVP-TE)";
+        }
+      }
+      case numbered-link-hop {
+        container numbered-link-hop {
+          leaf link-tp-id {
+            type te-tp-id;
+            mandatory true;
+            description
+              "TE Link Termination Point (LTP) identifier.";
+          }
+          leaf hop-type {
+            type te-hop-type;
+            default "strict";
+            description
+              "Strict or loose hop.";
+          }
+          leaf direction {
+            type te-link-direction;
+            default "outgoing";
+            description
+              "Link route object direction.";
+          }
+          description
+            "Numbered link explicit route hop.";
+          reference
+            "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels,
+                       Section 4.3, EXPLICIT_ROUTE in RSVP-TE
+             RFC 3477: Signalling Unnumbered Links in Resource
+                       ReSerVation Protocol - Traffic Engineering
+                       (RSVP-TE)";
+        }
+      }
+      case unnumbered-link-hop {
+        container unnumbered-link-hop {
+          must "(link-tp-id-uri or link-tp-id) and " +
+                "(node-id-uri or node-id)" {
+            description
+              "At least one node identifier and at least one Link 
+              Termination Point (LTP) identifier MUST be present.";
+          }
+          leaf link-tp-id-uri {
+            type nt:tp-id;
+            description
+              "Link Termination Point (LTP) identifier.";
+          }
+          leaf link-tp-id {
+            type te-tp-id;
+            description
+              "TE LTP identifier.  The combination of the TE link ID
+               and the TE node ID is used to identify an unnumbered
+               TE link.";
+          }
+          leaf node-id-uri {
+            type nw:node-id;
+            description
+              "The identifier of a node in the topology.";
+          }
+          leaf node-id {
+            type te-node-id;
+            description
+              "The identifier of a node in the TE topology.";
+          }
+          leaf hop-type {
+            type te-hop-type;
+            default "strict";
+            description
+              "Strict or loose hop.";
+          }
+          leaf direction {
+            type te-link-direction;
+            default "outgoing";
+            description
+              "Link route object direction.";
+          }
+          description
+            "Unnumbered link explicit route hop.";
+          reference
+            "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels,
+                       Section 4.3, EXPLICIT_ROUTE in RSVP-TE
+             RFC 3477: Signalling Unnumbered Links in Resource
+                       ReSerVation Protocol - Traffic Engineering
+                       (RSVP-TE)";
+        }
+      }
+      case as-number {
+        container as-number-hop {
+          leaf as-number {
+            type inet:as-number;
+            mandatory true;
+            description
+              "The Autonomous System (AS) number.";
+          }
+          leaf hop-type {
+            type te-hop-type;
+            default "strict";
+            description
+              "Strict or loose hop.";
+          }
+          description
+            "AS explicit route hop.";
+        }
+      }
+      case label {
+        container label-hop {
+          description
+            "Label hop type.";
+          uses te-label;
+        }
+        description
+          "The label explicit route hop type.";
+      }
+    }
+  }
+
+  grouping record-route-state {
+    description
+      "The Record Route grouping.";
+    leaf index {
+      type uint32;
+      description
+        "Record Route hop index.  The index is used to
+         identify an entry in the list.  The order of entries
+         is defined by the user without relying on key values.";
+    }
+    choice type {
+      description
+        "The Record Route entry type.";
+      case numbered-node-hop {
+        container numbered-node-hop {
+          must "node-id-uri or node-id" {
+            description
+              "At least one node identifier MUST be present.";
+          }
+          description
+            "Numbered node route hop container.";
+          leaf node-id-uri {
+            type nw:node-id;
+            description
+              "The identifier of a node in the topology.";
+          }
+          leaf node-id {
+            type te-node-id;
+            description
+              "The identifier of a node in the TE topology.";
+          }
+          leaf-list flags {
+            type path-attribute-flags;
+            description
+              "Path attributes flags.";
+            reference
+              "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels
+               RFC 4090: Fast Reroute Extensions to RSVP-TE for LSP
+                         Tunnels
+               RFC 4561: Definition of a Record Route Object (RRO)
+                         Node-Id Sub-Object";
+          }
+        }
+        description
+          "Numbered node route hop.";
+      }
+      case numbered-link-hop {
+        container numbered-link-hop {
+          description
+            "Numbered link route hop container.";
+          leaf link-tp-id {
+            type te-tp-id;
+            mandatory true;
+            description
+              "Numbered TE LTP identifier.";
+          }
+          leaf-list flags {
+            type path-attribute-flags;
+            description
+              "Path attributes flags.";
+            reference
+              "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels
+               RFC 4090: Fast Reroute Extensions to RSVP-TE for LSP
+                         Tunnels
+               RFC 4561: Definition of a Record Route Object (RRO)
+                         Node-Id Sub-Object";
+          }
+        }
+        description
+          "Numbered link route hop.";
+      }
+      case unnumbered-link-hop {
+        container unnumbered-link-hop {
+          must "(link-tp-id-uri or link-tp-id) and " +
+              "(node-id-uri or node-id)" {
+            description
+              "At least one node identifier and at least one Link 
+              Termination Point (LTP) identifier MUST be present.";
+          }
+          leaf link-tp-id-uri {
+            type nt:tp-id;
+            description
+              "Link Termination Point (LTP) identifier.";
+          }
+          leaf link-tp-id {
+            type te-tp-id;
+            description
+              "TE LTP identifier.  The combination of the TE link ID
+               and the TE node ID is used to identify an unnumbered
+               TE link.";
+          }
+          leaf node-id-uri {
+            type nw:node-id;
+            description
+              "The identifier of a node in the topology.";
+          }
+          leaf node-id {
+            type te-node-id;
+            description
+              "The identifier of a node in the TE topology.";
+          }
+          leaf-list flags {
+            type path-attribute-flags;
+            description
+              "Path attributes flags.";
+            reference
+              "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels
+               RFC 4090: Fast Reroute Extensions to RSVP-TE for LSP
+                         Tunnels
+               RFC 4561: Definition of a Record Route Object (RRO)
+                         Node-Id Sub-Object";
+          }
+          description
+            "Unnumbered link Record Route hop.";
+          reference
+            "RFC 3477: Signalling Unnumbered Links in Resource
+                       ReSerVation Protocol - Traffic Engineering
+                       (RSVP-TE)";
+        }
+        description
+          "Unnumbered link route hop.";
+      }
+      case label {
+        container label-hop {
+          description
+            "Label route hop type.";
+          uses te-label;
+          leaf-list flags {
+            type path-attribute-flags;
+            description
+              "Path attributes flags.";
+            reference
+              "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels
+               RFC 4090: Fast Reroute Extensions to RSVP-TE for LSP
+                         Tunnels
+               RFC 4561: Definition of a Record Route Object (RRO)
+                         Node-Id Sub-Object";
+          }
+        }
+        description
+          "The label Record Route entry types.";
+      }
+    }
+  }
+
+  grouping label-restriction-info {
+    description
+      "Label set item information.";
+    leaf restriction {
+      type enumeration {
+        enum inclusive {
+          description
+            "The label or label range is inclusive.";
+        }
+        enum exclusive {
+          description
+            "The label or label range is exclusive.";
+        }
+      }
+      default "inclusive";
+      description
+        "Indicates whether the list item is inclusive or exclusive.";
+    }
+    leaf index {
+      type uint32;
+      description
+        "The index of the label restriction list entry.";
+    }
+    container label-start {
+      must "(not(../label-end/te-label/direction) and"
+         + " not(te-label/direction))"
+         + " or "
+         + "(../label-end/te-label/direction = te-label/direction)"
+         + " or "
+         + "(not(te-label/direction) and"
+         + " (../label-end/te-label/direction = 'forward'))"
+         + " or "
+         + "(not(../label-end/te-label/direction) and"
+         + " (te-label/direction = 'forward'))" {
+        error-message "'label-start' and 'label-end' must have the "
+                    + "same direction.";
+      }
+      description
+        "This is the starting label if a label range is specified.
+         This is the label value if a single label is specified,
+         in which case the 'label-end' attribute is not set.";
+      uses te-label;
+    }
+    container label-end {
+      must "(not(../label-start/te-label/direction) and"
+         + " not(te-label/direction))"
+         + " or "
+         + "(../label-start/te-label/direction = te-label/direction)"
+         + " or "
+         + "(not(te-label/direction) and"
+         + " (../label-start/te-label/direction = 'forward'))"
+         + " or "
+         + "(not(../label-start/te-label/direction) and"
+         + " (te-label/direction = 'forward'))" {
+        error-message "'label-start' and 'label-end' must have the "
+                    + "same direction.";
+      }
+      description
+        "This is the ending label if a label range is specified.
+         This attribute is not set if a single label is specified.";
+      uses te-label;
+    }
+    container label-step {
+      description
+        "The step increment between labels in the label range.
+         The label start/end values will have to be consistent
+         with the sign of label step.  For example,
+         'label-start' < 'label-end' enforces 'label-step' > 0
+         'label-start' > 'label-end' enforces 'label-step' < 0.";
+      choice technology {
+        default "generic";
+        description
+          "Data-plane technology type.";
+        case generic {
+          leaf generic {
+            type int32;
+            default "1";
+            description
+              "Label range step.";
+          }
+        }
+      }
+    }
+    leaf range-bitmap {
+      type yang:hex-string;
+      description
+        "When there are gaps between 'label-start' and 'label-end',
+         this attribute is used to specify the positions
+         of the used labels.  This is represented in big endian as
+         'hex-string'.
+
+         In case the restriction is 'inclusive', the bit-position is
+         set if the corresponding mapped label is available.
+         In this case, if the range-bitmap is not present, all the
+         labels in the range are available.
+
+         In case the restriction is 'exclusive', the bit-position is
+         set if the corresponding mapped label is not available.
+         In this case, if the range-bitmap is not present, all the
+         labels in the range are not available.
+
+         The most significant byte in the hex-string is the farthest
+         to the left in the byte sequence.  Leading zero bytes in the
+         configured value may be omitted for brevity.
+         Each bit position in the 'range-bitmap' 'hex-string' maps
+         to a label in the range derived from 'label-start'.
+
+         For example, assuming that 'label-start' = 16000 and
+         'range-bitmap' = 0x01000001, then:
+
+         - bit position (0) is set, and the corresponding mapped
+           label from the range is 16000 + (0 * 'label-step') or
+           16000 for default 'label-step' = 1.
+         - bit position (24) is set, and the corresponding mapped
+           label from the range is 16000 + (24 * 'label-step') or
+           16024 for default 'label-step' = 1.";
+    }
+  }
+
+  grouping label-set-info {
+    description
+      "Grouping for the list of label restrictions specifying what
+       labels may or may not be used.";
+    container label-restrictions {
+      description
+        "The label restrictions container.";
+      list label-restriction {
+        key "index";
+        description
+          "The absence of the label restrictions container implies
+           that all labels are acceptable; otherwise, only restricted
+           labels are available.";
+        reference
+          "RFC 7579: General Network Element Constraint Encoding
+                     for GMPLS-Controlled Networks";
+        uses label-restriction-info;
+      }
+    }
+  }
+
+  grouping optimization-metric-entry {
+    description
+      "Optimization metrics configuration grouping.";
+    leaf metric-type {
+      type identityref {
+        base path-metric-optimization-type;
+      }
+      description
+        "Identifies the 'metric-type' that the path computation
+         process uses for optimization.";
+    }
+    leaf weight {
+      type uint8;
+      default "1";
+      description
+        "TE path metric normalization weight.";
+    }
+    container explicit-route-exclude-objects {
+      when "../metric-type = "
+         + "'te-types:path-metric-optimize-excludes'";
+      description
+        "Container for the 'exclude route' object list.";
+      uses path-route-exclude-objects;
+    }
+    container explicit-route-include-objects {
+      when "../metric-type = "
+         + "'te-types:path-metric-optimize-includes'";
+      description
+        "Container for the 'include route' object list.";
+      uses path-route-include-objects;
+    }
+  }
+
+  grouping common-constraints {
+    description
+      "Common constraints grouping that can be set on
+       a constraint set or directly on the tunnel.";
+    uses te-bandwidth {
+      description
+        "A requested bandwidth to use for path computation.";
+    }
+    leaf link-protection {
+      type identityref {
+        base link-protection-type;
+      }
+      default "te-types:link-protection-unprotected";
+      description
+        "Link protection type required for the links included
+         in the computed path.";
+      reference
+        "RFC 4202: Routing Extensions in Support of
+                   Generalized Multi-Protocol Label Switching
+                   (GMPLS)";
+    }
+    leaf setup-priority {
+      type uint8 {
+        range "0..7";
+      }
+      default "7";
+      description
+        "TE LSP requested setup priority.";
+      reference
+        "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels";
+    }
+    leaf hold-priority {
+      type uint8 {
+        range "0..7";
+      }
+      default "7";
+      description
+        "TE LSP requested hold priority.";
+      reference
+        "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels";
+    }
+    leaf signaling-type {
+      type identityref {
+        base path-signaling-type;
+      }
+      default "te-types:path-setup-rsvp";
+      description
+        "TE tunnel path signaling type.";
+    }
+  }
+
+  grouping tunnel-constraints {
+    description
+      "Tunnel constraints grouping that can be set on
+       a constraint set or directly on the tunnel.";
+    leaf network-id {
+      type nw:network-id;
+      description
+        "The network topology identifier.";
+    }
+    uses te-topology-identifier;
+    uses common-constraints;
+  }
+
+  grouping path-constraints-route-objects {
+    description
+      "List of route entries to be included or excluded when
+       performing the path computation.";
+    container explicit-route-objects {
+      description
+        "Container for the explicit route object lists.";
+      list route-object-exclude-always {
+        key "index";
+        ordered-by user;
+        description
+          "List of route objects to always exclude from the path
+           computation.";
+        leaf index {
+          type uint32;
+          description
+            "Explicit Route Object index.  The index is used to
+             identify an entry in the list.  The order of entries
+             is defined by the user without relying on key values.";
+        }
+        uses explicit-route-hop;
+      }
+      list route-object-include-exclude {
+        key "index";
+        ordered-by user;
+        description
+          "List of route objects to include or exclude in the path
+           computation.";
+        leaf explicit-route-usage {
+          type identityref {
+            base route-usage-type;
+          }
+          default "te-types:route-include-object";
+          description
+            "Indicates whether to include or exclude the
+             route object.  The default is to include it.";
+        }
+        leaf index {
+          type uint32;
+          description
+            "Route object include-exclude index.  The index is used
+             to identify an entry in the list.  The order of entries
+             is defined by the user without relying on key values.";
+        }
+        uses explicit-route-hop {
+          augment "type" {
+            case srlg {
+              container srlg {
+                description
+                  "SRLG container.";
+                leaf srlg {
+                  type uint32;
+                  description
+                    "SRLG value.";
+                }
+              }
+              description
+                "An SRLG value to be included or excluded.";
+            }
+            description
+              "Augmentation for a generic explicit route for SRLG
+               exclusion.";
+          }
+        }
+      }
+    }
+  }
+
+  grouping path-route-include-objects {
+    description
+      "List of route objects to be included when performing
+       the path computation.";
+    list route-object-include-object {
+      key "index";
+      ordered-by user;
+      description
+        "List of Explicit Route Objects to be included in the
+         path computation.";
+      leaf index {
+        type uint32;
+        description
+          "Route object entry index.  The index is used to
+           identify an entry in the list.  The order of entries
+           is defined by the user without relying on key values.";
+      }
+      uses explicit-route-hop;
+    }
+  }
+
+  grouping path-route-exclude-objects {
+    description
+      "List of route objects to be excluded when performing
+       the path computation.";
+    list route-object-exclude-object {
+      key "index";
+      ordered-by user;
+      description
+        "List of Explicit Route Objects to be excluded in the
+         path computation.";
+      leaf index {
+        type uint32;
+        description
+          "Route object entry index.  The index is used to
+           identify an entry in the list.  The order of entries
+           is defined by the user without relying on key values.";
+      }
+      uses explicit-route-hop {
+        augment "type" {
+          case srlg {
+            container srlg {
+              description
+                "SRLG container.";
+              leaf srlg {
+                type uint32;
+                description
+                  "SRLG value.";
+              }
+            }
+            description
+              "An SRLG value to be included or excluded.";
+          }
+          description
+            "Augmentation for a generic explicit route for SRLG
+             exclusion.";
+        }
+      }
+    }
+  }
+
+  grouping generic-path-metric-bounds {
+    description
+      "TE path metric bounds grouping.";
+    container path-metric-bounds {
+      description
+        "Top-level container for the list of path metric bounds.";
+      list path-metric-bound {
+        key "metric-type";
+        description
+          "List of path metric bounds, which can apply to link and
+           path metrics.
+
+           TE paths which have at least one path metric which
+           exceeds the specified bounds MUST NOT be selected.
+
+           TE paths that traverse TE links which have at least one
+           link metric which exceeds the specified bounds MUST NOT
+           be selected.";
+        leaf metric-type {
+          type identityref {
+            base link-path-metric-type;
+          }
+          description
+            "Identifies an entry in the list of 'metric-type' items
+             bound for the TE path.";
+        }
+        leaf upper-bound {
+          type uint64;
+          default "0";
+          description
+            "Upper bound on the specified 'metric-type'.
+
+             A zero indicates an unbounded upper limit for the
+             specificied 'metric-type'.
+
+             The unit of is interpreted in the context of the
+             'metric-type' identity.";
+        }
+      }
+    }
+  }
+
+  grouping generic-path-optimization {
+    description
+      "TE generic path optimization grouping.";
+    container optimizations {
+      description
+        "The objective function container that includes
+         attributes to impose when computing a TE path.";
+      choice algorithm {
+        description
+          "Optimizations algorithm.";
+        case metric {
+          if-feature "path-optimization-metric";
+          /* Optimize by metric */
+          list optimization-metric {
+            key "metric-type";
+            description
+              "TE path metric type.";
+            uses optimization-metric-entry;
+          }
+          /* Tiebreakers */
+          container tiebreakers {
+            status deprecated;
+            description
+              "Container for the list of tiebreakers.
+
+               This container has been deprecated by the tiebreaker
+               leaf.";
+            list tiebreaker {
+              key "tiebreaker-type";
+              status deprecated;
+              description
+                "The list of tiebreaker criteria to apply on an
+                 equally favored set of paths, in order to pick
+                 the best.";
+              leaf tiebreaker-type {
+                type identityref {
+                  base path-metric-type;
+                }
+                status deprecated;
+                description
+                  "Identifies an entry in the list of tiebreakers.";
+              }
+            }
+          }
+        }
+        case objective-function {
+          if-feature "path-optimization-objective-function";
+          /* Objective functions */
+          container objective-function {
+            description
+              "The objective function container that includes
+               attributes to impose when computing a TE path.";
+            leaf objective-function-type {
+              type identityref {
+                base objective-function-type;
+              }
+              default "te-types:of-minimize-cost-path";
+              description
+                "Objective function entry.";
+            }
+          }
+        }
+      }
+    }
+    leaf tiebreaker {
+      type identityref {
+        base path-tiebreaker-type;
+      }
+      default "te-types:path-tiebreaker-random";
+      description
+        "The tiebreaker criteria to apply on an equally favored set
+         of paths, in order to pick the best.";
+    }
+  }
+
+  grouping generic-path-affinities {
+    description
+      "Path affinities grouping.";
+    container path-affinities-values {
+      description
+        "Path affinities represented as values.";
+      list path-affinities-value {
+        key "usage";
+        description
+          "List of named affinity constraints.";
+        leaf usage {
+          type identityref {
+            base resource-affinities-type;
+          }
+          description
+            "Identifies an entry in the list of value affinity
+             constraints.";
+        }
+        leaf value {
+          type admin-groups;
+          default "";
+          description
+            "The affinity value.  The default is empty.";
+        }
+      }
+    }
+    container path-affinity-names {
+      description
+        "Path affinities represented as names.";
+      list path-affinity-name {
+        key "usage";
+        description
+          "List of named affinity constraints.";
+        leaf usage {
+          type identityref {
+            base resource-affinities-type;
+          }
+          description
+            "Identifies an entry in the list of named affinity
+             constraints.";
+        }
+        list affinity-name {
+          key "name";
+          leaf name {
+            type string;
+            description
+              "Identifies a named affinity entry.";
+          }
+          description
+            "List of named affinities.";
+        }
+      }
+    }
+  }
+
+  grouping generic-path-srlgs {
+    description
+      "Path SRLG grouping.";
+    container path-srlgs-lists {
+      description
+        "Path SRLG properties container.";
+      list path-srlgs-list {
+        key "usage";
+        description
+          "List of SRLG values to be included or excluded.";
+        leaf usage {
+          type identityref {
+            base route-usage-type;
+          }
+          description
+            "Identifies an entry in a list of SRLGs to either
+             include or exclude.";
+        }
+        leaf-list values {
+          type srlg;
+          description
+            "List of SRLG values.";
+        }
+      }
+    }
+    container path-srlgs-names {
+      description
+        "Container for the list of named SRLGs.";
+      list path-srlgs-name {
+        key "usage";
+        description
+          "List of named SRLGs to be included or excluded.";
+        leaf usage {
+          type identityref {
+            base route-usage-type;
+          }
+          description
+            "Identifies an entry in a list of named SRLGs to either
+             include or exclude.";
+        }
+        leaf-list names {
+          type string;
+          description
+            "List of named SRLGs.";
+        }
+      }
+    }
+  }
+
+  grouping generic-path-disjointness {
+    description
+      "Path disjointness grouping.";
+    leaf disjointness {
+      type te-path-disjointness;
+      description
+        "The type of resource disjointness.
+         When configured for a primary path, the disjointness level
+         applies to all secondary LSPs.  When configured for a
+         secondary path, the disjointness level overrides the level
+         configured for the primary path.";
+    }
+  }
+
+  grouping common-path-constraints-attributes {
+    description
+      "Common path constraints configuration grouping.";
+    uses common-constraints;
+    uses generic-path-metric-bounds;
+    uses generic-path-affinities;
+    uses generic-path-srlgs;
+  }
+
+  grouping generic-path-constraints {
+    description
+      "Global named path constraints configuration grouping.";
+    container path-constraints {
+      description
+        "TE named path constraints container.";
+      uses common-path-constraints-attributes;
+      uses generic-path-disjointness;
+    }
+  }
+
+  grouping generic-path-properties {
+    description
+      "TE generic path properties grouping.";
+    container path-properties {
+      config false;
+      description
+        "The TE path properties.";
+      list path-metric {
+        key "metric-type";
+        description
+          "TE path metric type.";
+        leaf metric-type {
+          type identityref {
+            base path-metric-type;
+          }
+          description
+            "TE path metric type.";
+        }
+        leaf accumulative-value {
+          type uint64;
+          description
+            "TE path metric accumulative value.";
+        }
+      }
+      uses generic-path-affinities;
+      uses generic-path-srlgs;
+      container path-route-objects {
+        description
+          "Container for the list of route objects either returned by
+           the computation engine or actually used by an LSP.";
+        list path-route-object {
+          key "index";
+          ordered-by user;
+          description
+            "List of route objects either returned by the computation
+             engine or actually used by an LSP.";
+          leaf index {
+            type uint32;
+            description
+              "Route object entry index.  The index is used to
+               identify an entry in the list.  The order of entries
+               is defined by the user without relying on key
+               values.";
+          }
+          uses explicit-route-hop;
+        }
+      }
+    }
+  }
+
+  grouping encoding-and-switching-type {
+    description
+      "Common grouping to define the LSP encoding and
+       switching types";
+    leaf encoding {
+      type identityref {
+        base te-types:lsp-encoding-types;
+      }
+      description
+        "LSP encoding type.";
+      reference
+        "RFC 3945: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Architecture";
+    }
+    leaf switching-type {
+      type identityref {
+        base te-types:switching-capabilities;
+      }
+      description
+        "LSP switching type.";
+      reference
+        "RFC 3945: Generalized Multi-Protocol Label Switching (GMPLS)
+                   Architecture";
+    }
+  }
+
+  grouping te-generic-node-id {
+    description
+      "A reusable grouping for a TE generic node identifier.";
+    leaf id {
+      type union {
+        type te-node-id;
+        type inet:ip-address;
+        type nw:node-id;
+      }
+      description
+        "The identifier of the node.
+
+         It can be represented as IP address or dotted quad address
+         or as an URI.
+
+         The type data node disambiguates the union type.";
+    }
+    leaf type {
+      type enumeration {
+        enum ip {
+          description
+            "IP address representation of the node identifier.";
+        }
+        enum te-id {
+          description
+            "TE identifier of the node";
+        }
+        enum node-id {
+          description
+            "URI representation of the node identifier.";
+        }
+      }
+      description
+        "Type of node identifier representation.";
+    }
+  }
+}
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-vpn-common@2021-09-10.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-vpn-common@2021-09-10.yang
new file mode 100644
index 0000000000000000000000000000000000000000..075437d3a43dd7d81f98f1103fd2e34e2571005b
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_network_slice/yang/ietf-vpn-common@2021-09-10.yang
@@ -0,0 +1,2205 @@
+module ietf-vpn-common {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-vpn-common";
+  prefix vpn-common;
+
+  import ietf-netconf-acm {
+    prefix nacm;
+    reference
+      "RFC 8341: Network Configuration Access Control Model";
+  }
+  import ietf-routing-types {
+    prefix rt-types;
+    reference
+      "RFC 8294: Common YANG Data Types for the Routing Area";
+  }
+  import ietf-yang-types {
+    prefix yang;
+    reference
+      "RFC 6991: Common YANG Data Types, Section 3";
+  }
+  import ietf-packet-fields {
+    prefix packet-fields;
+    reference
+      "RFC 8519: YANG Data Model for Network Access
+                 Control Lists (ACLs)";
+  }
+
+  organization
+    "IETF OPSAWG (Operations and Management Area Working Group)";
+  contact
+    "WG Web:   <https://datatracker.ietf.org/wg/opsawg/>
+     WG List:  <mailto:opsawg@ietf.org>
+
+     Editor:  Mohamed Boucadair
+              <mailto:mohamed.boucadair@orange.com>
+     Author:  Samier Barguil
+              <mailto:samier.barguilgiraldo.ext@telefonica.com>
+     Author:  Oscar Gonzalez de Dios
+              <mailto:oscar.gonzalezdedios@telefonica.com>
+     Author:  Qin Wu
+              <mailto:bill.wu@huawei.com>";
+  description
+    "This YANG module defines a common module that is meant
+     to be reused by various VPN-related modules (e.g.,
+     Layer 3 VPN Service Model (L3SM), Layer 2 VPN Service
+     Model (L2SM), Layer 3 VPN Network Model (L3NM), Layer 2
+     VPN Network Model (L2NM)).
+
+     Copyright (c) 2021 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC XXXX; see
+     the RFC itself for full legal notices.";
+
+  revision 2021-09-10 {
+    description
+      "Initial revision.";
+    reference
+      "RFC XXXX: A Layer 2/3 VPN Common YANG Model";
+  }
+
+  /******** Collection of VPN-related Features ********/
+  /*
+   * Features related to encapsulation schemes
+   */
+
+  feature dot1q {
+    description
+      "Indicates the support for the Dot1q encapsulation.";
+    reference
+      "IEEE Std 802.1Q: Bridges and Bridged Networks";
+  }
+
+  feature qinq {
+    description
+      "Indicates the support for the QinQ encapsulation.";
+    reference
+      "IEEE Std 802.1ad: Provider Bridges";
+  }
+
+  feature vxlan {
+    description
+      "Indicates the support for the Virtual eXtensible
+       Local Area Network (VXLAN) encapsulation.";
+    reference
+      "RFC 7348: Virtual eXtensible Local Area  Network (VXLAN):
+                 A Framework for Overlaying Virtualized Layer 2
+                 Networks over Layer 3 Networks";
+  }
+
+  feature qinany {
+    description
+      "Indicates the support for the QinAny encapsulation.
+       The outer VLAN tag is set to a specific value but
+       the inner VLAN tag is set to any.";
+  }
+
+  feature lag-interface {
+    description
+      "Indicates the support for Link Aggregation Group (LAG)
+       between VPN network accesses.";
+    reference
+      "IEEE Std. 802.1AX: Link Aggregation";
+  }
+
+  /*
+   * Features related to multicast
+   */
+
+  feature multicast {
+    description
+      "Indicates multicast capabilities support in a VPN.";
+    reference
+      "RFC 6513: Multicast in MPLS/BGP IP VPNs";
+  }
+
+  feature igmp {
+    description
+      "Indicates support for Internet Group Management Protocol
+       (IGMP).";
+    reference
+      "RFC 1112: Host Extensions for IP Multicasting
+       RFC 2236: Internet Group Management Protocol, Version 2
+       RFC 3376: Internet Group Management Protocol, Version 3";
+  }
+
+  feature mld {
+    description
+      "Indicates support for Multicast Listener Discovery (MLD).";
+    reference
+      "RFC 2710: Multicast Listener Discovery (MLD) for IPv6
+       RFC 3810: Multicast Listener Discovery Version 2 (MLDv2)
+                 for IPv6";
+  }
+
+  feature pim {
+    description
+      "Indicates support for Protocol Independent Multicast (PIM).";
+    reference
+      "RFC 7761: Protocol Independent Multicast - Sparse Mode
+                (PIM-SM): Protocol Specification (Revised)";
+  }
+
+  /*
+   * Features related to address family types
+   */
+
+  feature ipv4 {
+    description
+      "Indicates IPv4 support in a VPN. That is, IPv4 traffic
+       can be carried in the VPN, IPv4 addresses/prefixes can
+       be assigned to a VPN network access, IPv4 routes can be
+       installed for the CE/PE link, etc.";
+    reference
+      "RFC 791: Internet Protocol";
+  }
+
+  feature ipv6 {
+    description
+      "Indicates IPv6 support in a VPN. That is, IPv6 traffic
+       can be carried in the VPN, IPv6 addresses/prefixes can
+       be assigned to a VPN network access, IPv6 routes can be
+       installed for the CE/PE link, etc.";
+    reference
+      "RFC 8200: Internet Protocol, Version 6 (IPv6)";
+  }
+
+  /*
+   * Features related to routing protocols
+   */
+
+  feature rtg-ospf {
+    description
+      "Indicates support for the OSPF as the Provider Edge (PE)/
+       Customer Edge (CE) routing protocol.";
+    reference
+      "RFC 4577: OSPF as the Provider/Customer Edge Protocol
+                 for BGP/MPLS IP Virtual Private Networks (VPNs)
+       RFC 6565: OSPFv3 as a Provider Edge to Customer Edge
+                 (PE-CE) Routing Protocol";
+  }
+
+  feature rtg-ospf-sham-link {
+    description
+      "Indicates support for OSPF sham links.";
+    reference
+      "RFC 4577: OSPF as the Provider/Customer Edge Protocol
+                 for BGP/MPLS IP Virtual Private Networks (VPNs),
+                 Section 4.2.7
+       RFC 6565: OSPFv3 as a Provider Edge to Customer Edge
+                 (PE-CE) Routing Protocol, Section 5";
+  }
+
+  feature rtg-bgp {
+    description
+      "Indicates support for BGP as the PE/CE routing protocol.";
+    reference
+      "RFC 4271: A Border Gateway Protocol 4 (BGP-4)";
+  }
+  feature rtg-rip {
+    description
+      "Indicates support for RIP as the PE/CE routing protocol.";
+    reference
+      "RFC 2453: RIP Version 2
+       RFC 2080: RIPng for IPv6";
+  }
+
+  feature rtg-isis {
+    description
+      "Indicates support for IS-IS as the PE/CE routing protocol.";
+    reference
+      "ISO10589: Intermediate System to Intermediate System intra-
+                 domain routeing information exchange protocol for
+                 use in conjunction with the protocol for providing
+                 the connectionless-mode network service
+                 (ISO 8473)";
+  }
+
+  feature rtg-vrrp {
+    description
+      "Indicates support for the Virtual Router Redundancy
+       Protocol (VRRP) in CE/PE link.";
+    reference
+      "RFC 5798: Virtual Router Redundancy Protocol (VRRP) Version 3
+                 for IPv4 and IPv6";
+  }
+
+  feature bfd {
+    description
+      "Indicates support for Bidirectional Forwarding Detection (BFD)
+       between the CE and the PE.";
+    reference
+      "RFC 5880: Bidirectional Forwarding Detection (BFD)";
+  }
+
+  /*
+   * Features related to VPN service constraints
+   */
+
+  feature bearer-reference {
+    description
+      "A bearer refers to properties of the CE-PE attachment that
+       are below Layer 3.
+       This feature indicates support for the bearer reference access
+       constraint. That is, the reuse of a network connection that was
+       already ordered to the service provider apart from the IP VPN
+       site.";
+  }
+
+  feature placement-diversity {
+    description
+      "Indicates support for placement diversity constraints in the
+       customer premises. An example of these constraints may be to
+       avoid connecting a site network access to the same Provider
+       Edge as a target site network access.";
+  }
+
+  /*
+   * Features related to bandwidth and Quality of Service (QoS)
+   */
+
+  feature qos {
+    description
+      "Indicates support for Classes of Service (CoSes) in the VPN.";
+  }
+
+  feature inbound-bw {
+    description
+      "Indicates support for the inbound bandwidth in a VPN. That is,
+       support for specifying the download bandwidth from the service
+       provider network to the VPN site. Note that the L3SM uses
+       'input' to identify the same feature. That terminology should
+       be deprecated in favor of the one defined in this module.";
+  }
+
+  feature outbound-bw {
+    description
+      "Indicates support for the outbound bandwidth in a VPN. That is,
+       support for specifying the upload bandwidth from the VPN site
+       to the service provider network. Note that the L3SM uses
+       'output' to identify the same feature. That terminology should
+       be deprecated in favor of the one defined in this module.";
+  }
+
+  /*
+   * Features related to security and resilience
+   */
+
+  feature encryption {
+    description
+      "Indicates support for encryption in the VPN.";
+  }
+
+  feature fast-reroute {
+    description
+      "Indicates support for Fast Reroute (FRR) capabilities for
+       a VPN site.";
+  }
+
+  /*
+   * Features related to advanced VPN options
+   */
+
+  feature external-connectivity {
+    description
+      "Indicates support for the VPN to provide external
+       connectivity (e.g., Internet, private or public cloud).";
+    reference
+      "RFC 4364: BGP/MPLS IP Virtual Private Networks
+                 (VPNs), Section 11";
+  }
+
+  feature extranet-vpn {
+    description
+      "Indicates support for extranet VPNs. That is, the capability of
+       a VPN to access a list of other VPNs.";
+    reference
+      "RFC 4364: BGP/MPLS IP Virtual Private Networks
+                 (VPNs), Section 1.1";
+  }
+
+  feature carriers-carrier {
+    description
+      "Indicates support for Carrier-of-Carrier VPNs.";
+    reference
+      "RFC 4364: BGP/MPLS IP Virtual Private Networks
+                 (VPNs), Section 9";
+  }
+
+  /*
+   * Address family related identities
+   */
+
+  identity address-family {
+    description
+      "Defines a type for the address family.";
+  }
+
+  identity ipv4 {
+    base address-family;
+    description
+      "Identity for IPv4 address family.";
+  }
+  identity ipv6 {
+    base address-family;
+    description
+      "Identity for IPv6 address family.";
+  }
+
+  identity dual-stack {
+    base address-family;
+    description
+      "Identity for IPv4 and IPv6 address family.";
+  }
+
+  /*
+   * Identities related to VPN topology
+   */
+
+  identity vpn-topology {
+    description
+      "Base identity of the VPN topology.";
+  }
+
+  identity any-to-any {
+    base vpn-topology;
+    description
+      "Identity for any-to-any VPN topology. All VPN sites
+       can communicate with each other without any restrictions.";
+  }
+
+  identity hub-spoke {
+    base vpn-topology;
+    description
+      "Identity for Hub-and-Spoke VPN topology. All Spokes can
+       communicate only with Hubs but not with each other. Hubs
+       can communicate with each other.";
+  }
+
+  identity hub-spoke-disjoint {
+    base vpn-topology;
+    description
+      "Identity for Hub-and-Spoke VPN topology where Hubs cannot
+       communicate with each other.";
+  }
+
+  identity custom {
+    base vpn-topology;
+    description
+      "Identity for custom VPN topologies where the role of the nodes
+       is not strictly Hub or Spoke. The VPN topology is controlled by
+       the import/export policies. The custom topology reflects more
+       complex VPN nodes such as VPN node that acts as Hub for certain
+       nodes and Spoke to others.";
+  }
+
+  /*
+   * Identities related to network access types
+   */
+
+  identity site-network-access-type {
+    description
+      "Base identity for site network access type.";
+  }
+
+  identity point-to-point {
+    base site-network-access-type;
+    description
+      "Point-to-point access type.";
+  }
+
+  identity multipoint {
+    base site-network-access-type;
+    description
+      "Multipoint access type.";
+  }
+
+  identity irb {
+    base site-network-access-type;
+    description
+      "Integrated Routing Bridge (IRB).
+       Identity for pseudowire connections.";
+  }
+
+  identity loopback {
+    base site-network-access-type;
+    description
+      "Loopback access type.";
+  }
+
+  /*
+   * Identities related to operational and administrative status
+   */
+
+  identity operational-status {
+    description
+      "Base identity for the operational status.";
+  }
+
+  identity op-up {
+    base operational-status;
+    description
+      "Operational status is Up/Enabled.";
+  }
+
+  identity op-down {
+    base operational-status;
+    description
+      "Operational status is Down/Disabled.";
+  }
+
+  identity op-unknown {
+    base operational-status;
+    description
+      "Operational status is Unknown.";
+  }
+
+  identity administrative-status {
+    description
+      "Base identity for administrative status.";
+  }
+
+  identity admin-up {
+    base administrative-status;
+    description
+      "Administrative status is Up/Enabled.";
+  }
+
+  identity admin-down {
+    base administrative-status;
+    description
+      "Administrative status is Down/Disabled.";
+  }
+
+  identity admin-testing {
+    base administrative-status;
+    description
+      "Administrative status is up for testing purposes.";
+  }
+
+  identity admin-pre-deployment {
+    base administrative-status;
+    description
+      "Administrative status is pre-deployment phase. That is,
+       prior to the actual deployment of a service.";
+  }
+
+  /*
+   * Identities related to site or node role
+   */
+
+  identity role {
+    description
+      "Base identity of a site or a node role.";
+  }
+
+  identity any-to-any-role {
+    base role;
+    description
+      "Any-to-any role.";
+  }
+
+  identity spoke-role {
+    base role;
+    description
+      "A node or a site is acting as a Spoke.";
+  }
+
+  identity hub-role {
+    base role;
+    description
+      "A node or a site is acting as a Hub.";
+  }
+
+  identity custom-role {
+    base role;
+    description
+      "VPN node with custom or complex role in the VPN. For some
+       sources/destinations it can behave as a Hub, but for others it
+       can act as a Spoke depending on the configured policy.";
+  }
+
+  /*
+   * Identities related to VPN service constraints
+   */
+
+  identity placement-diversity {
+    description
+      "Base identity for access placement constraints.";
+  }
+
+  identity bearer-diverse {
+    base placement-diversity;
+    description
+      "Bearer diversity.
+       The bearers should not use common elements.";
+  }
+
+  identity pe-diverse {
+    base placement-diversity;
+    description
+      "PE diversity.";
+  }
+
+  identity pop-diverse {
+    base placement-diversity;
+    description
+      "Point Of Presence (POP) diversity.";
+  }
+
+  identity linecard-diverse {
+    base placement-diversity;
+    description
+      "Linecard diversity.";
+  }
+
+  identity same-pe {
+    base placement-diversity;
+    description
+      "Having sites connected on the same PE.";
+  }
+
+  identity same-bearer {
+    base placement-diversity;
+    description
+      "Having sites connected using the same bearer.";
+  }
+
+  /*
+   * Identities related to service types
+   */
+
+  identity service-type {
+    description
+      "Base identity for service type.";
+  }
+
+  identity l3vpn {
+    base service-type;
+    description
+      "L3VPN service.";
+    reference
+      "RFC 4364: BGP/MPLS IP Virtual Private Networks (VPNs)";
+  }
+
+  identity vpls {
+    base service-type;
+    description
+      "VPLS service.";
+    reference
+      "RFC 4761: Virtual Private LAN Service (VPLS) Using BGP for
+                 Auto-Discovery and Signaling
+       RFC 4762: Virtual Private LAN Service (VPLS) Using Label
+                 Distribution Protocol (LDP) Signaling";
+  }
+
+  identity vpws {
+    base service-type;
+    description
+      "Virtual Private Wire Service (VPWS) service.";
+    reference
+      "RFC 4664: Framework for Layer 2 Virtual Private Networks
+                 (L2VPNs), Section 3.1.1";
+  }
+
+  identity vpws-evpn {
+    base service-type;
+    description
+      "EVPN used to support VPWS service.";
+    reference
+      "RFC 8214: Virtual Private Wire Service Support in Ethernet VPN";
+  }
+
+  identity pbb-evpn {
+    base service-type;
+    description
+      "Provider Backbone Bridging (PBB) EVPNs service.";
+    reference
+      "RFC 7623: Provider Backbone Bridging Combined with Ethernet VPN
+                (PBB-EVPN)";
+  }
+
+  identity mpls-evpn {
+    base service-type;
+    description
+      "MPLS-based EVPN service.";
+    reference
+      "RFC 7432: BGP MPLS-Based Ethernet VPN";
+  }
+
+  identity vxlan-evpn {
+    base service-type;
+    description
+      "VXLAN-based EVPN service.";
+    reference
+      "RFC 8365: A Network Virtualization Overlay Solution Using
+                 Ethernet VPN (EVPN)";
+  }
+
+  /*
+   * Identities related to VPN signaling type
+   */
+
+  identity vpn-signaling-type {
+    description
+      "Base identity for VPN signaling types";
+  }
+
+  identity bgp-signaling {
+    base vpn-signaling-type;
+    description
+      "Layer 2 VPNs using BGP signaling.";
+    reference
+      "RFC 6624: Layer 2 Virtual Private Networks Using BGP for
+                 Auto-Discovery and Signaling
+       RFC 7432: BGP MPLS-Based Ethernet VPN";
+  }
+
+  identity ldp-signaling {
+    base vpn-signaling-type;
+    description
+      "Targeted Label Distribution Protocol (LDP) signaling.";
+    reference
+      "RFC 5036: LDP Specification";
+  }
+
+  identity l2tp-signaling {
+    base vpn-signaling-type;
+    description
+      "Layer Two Tunneling Protocol (L2TP) signaling.";
+    reference
+      "RFC 3931: Layer Two Tunneling Protocol - Version 3 (L2TPv3)";
+  }
+
+  /*
+   * Identities related to routing protocols
+   */
+
+  identity routing-protocol-type {
+    description
+      "Base identity for routing protocol type.";
+  }
+
+  identity static-routing {
+    base routing-protocol-type;
+    description
+      "Static routing protocol.";
+  }
+
+  identity bgp-routing {
+    if-feature "rtg-bgp";
+    base routing-protocol-type;
+    description
+      "BGP routing protocol.";
+    reference
+      "RFC 4271: A Border Gateway Protocol 4 (BGP-4)";
+  }
+
+  identity ospf-routing {
+    if-feature "rtg-ospf";
+    base routing-protocol-type;
+    description
+      "OSPF routing protocol.";
+    reference
+      "RFC 4577: OSPF as the Provider/Customer Edge Protocol
+                 for BGP/MPLS IP Virtual Private Networks(VPNs)
+       RFC 6565: OSPFv3 as a Provider Edge to Customer Edge
+                 (PE-CE) Routing Protocol";
+  }
+
+  identity rip-routing {
+    if-feature "rtg-rip";
+    base routing-protocol-type;
+    description
+      "RIP routing protocol.";
+    reference
+      "RFC 2453: RIP Version 2
+       RFC 2080: RIPng for IPv6";
+  }
+
+  identity isis-routing {
+    if-feature "rtg-isis";
+    base routing-protocol-type;
+    description
+      "IS-IS routing protocol.";
+    reference
+      "ISO10589: Intermediate System to Intermediate System intra-
+                 domain routeing information exchange protocol for
+                 use in conjunction with the protocol for providing
+                 the connectionless-mode network service
+                 (ISO 8473)";
+  }
+
+  identity vrrp-routing {
+    if-feature "rtg-vrrp";
+    base routing-protocol-type;
+    description
+      "VRRP protocol.
+
+       This is to be used when LANs are directly connected to PEs.";
+    reference
+      "RFC 5798: Virtual Router Redundancy Protocol (VRRP) Version 3
+                 for IPv4 and IPv6";
+  }
+
+  identity direct-routing {
+    base routing-protocol-type;
+    description
+      "Direct routing.
+
+       This is to be used when LANs are directly connected to PEs
+       and must be advertised in the VPN.";
+  }
+
+  identity any-routing {
+    base routing-protocol-type;
+    description
+      "Any routing protocol.
+
+       This can be, e.g., used to set policies that apply to any
+       routing protocol in place.";
+  }
+
+  identity isis-level {
+    if-feature "rtg-isis";
+    description
+      "Base identity for the IS-IS level.";
+    reference
+      "ISO10589: Intermediate System to Intermediate System intra-
+                 domain routeing information exchange protocol for
+                 use in conjunction with the protocol for providing
+                 the connectionless-mode network service
+                 (ISO 8473)";
+  }
+
+  identity level-1 {
+    base isis-level;
+    description
+      "IS-IS level 1.";
+  }
+
+  identity level-2 {
+    base isis-level;
+    description
+      "IS-IS level 2.";
+  }
+
+  identity level-1-2 {
+    base isis-level;
+    description
+      "IS-IS levels 1 and 2.";
+  }
+
+  identity bfd-session-type {
+    if-feature "bfd";
+    description
+      "Base identity for the BFD session type.";
+  }
+
+  identity classic-bfd {
+    base bfd-session-type;
+    description
+      "Classic BFD.";
+    reference
+      "RFC 5880: Bidirectional Forwarding Detection (BFD)";
+  }
+
+  identity s-bfd {
+    base bfd-session-type;
+    description
+      "Seamless BFD.";
+    reference
+      "RFC 7880: Seamless Bidirectional Forwarding Detection (S-BFD)";
+  }
+
+  /*
+   * Identities related to Routes Import and Export
+   */
+
+  identity ie-type {
+    description
+      "Base identity for 'import/export' routing profiles.
+       These profiles can be reused between VPN nodes.";
+  }
+
+  identity import {
+    base ie-type;
+    description
+      "'Import' routing profile.";
+    reference
+      "RFC 4364: BGP/MPLS IP Virtual Private Networks
+                 (VPNs), Section 4.3.1";
+  }
+
+  identity export {
+    base ie-type;
+    description
+      "'Export' routing profile.";
+    reference
+      "RFC 4364: BGP/MPLS IP Virtual Private Networks
+                 (VPNs), Section 4.3.1";
+  }
+
+  identity import-export {
+    base ie-type;
+    description
+      "'Import/export' routing profile.";
+  }
+
+  /*
+   * Identities related to bandwidth and QoS
+   */
+
+  identity bw-direction {
+    description
+      "Base identity for the bandwidth direction.";
+  }
+
+  identity inbound-bw {
+    if-feature "inbound-bw";
+    base bw-direction;
+    description
+      "Inbound bandwidth.";
+  }
+
+  identity outbound-bw {
+    if-feature "outbound-bw";
+    base bw-direction;
+    description
+      "Outbound bandwidth.";
+  }
+  identity bw-type {
+    description
+      "Base identity for the bandwidth type.";
+  }
+
+  identity bw-per-cos {
+    if-feature "qos";
+    base bw-type;
+    description
+      "The bandwidth is per-CoS.";
+  }
+
+  identity bw-per-port {
+    base bw-type;
+    description
+      "The bandwidth is per-site network access.";
+  }
+
+  identity bw-per-site {
+    base bw-type;
+    description
+      "The bandwidth is per-site. It is applicable to all the site
+       network accesses within a site.";
+  }
+
+  identity bw-per-service {
+    base bw-type;
+    description
+      "The bandwidth is per-VPN service.";
+  }
+
+  identity qos-profile-direction {
+    if-feature "qos";
+    description
+      "Base identity for the QoS profile direction.";
+  }
+
+  identity site-to-wan {
+    base qos-profile-direction;
+    description
+      "Customer site to provider's network direction.
+       This is typically the CE-to-PE direction.";
+  }
+
+  identity wan-to-site {
+    base qos-profile-direction;
+    description
+      "Provider's network to customer site direction.
+       This is typically the PE-to-CE direction.";
+  }
+
+  identity both {
+    base qos-profile-direction;
+    description
+      "Both WAN-to-Site and Site-to-WAN directions.";
+  }
+
+  /*
+   *  Identities related to underlay transport instances
+   */
+
+  identity transport-instance-type {
+    description
+      "Base identity for underlay transport instance type.";
+  }
+
+  identity virtual-network {
+    base transport-instance-type;
+    description
+      "Virtual network.";
+    reference
+      "RFC 8453: Framework for Abstraction and Control of TE
+                 Networks (ACTN)";
+  }
+
+  identity enhanced-vpn {
+    base transport-instance-type;
+    description
+      "Enhanced VPN (VPN+). VPN+ is an approach that is
+       based on existing VPN and Traffic Engineering (TE)
+       technologies but adds characteristics that specific
+       services require over and above classical VPNs.";
+    reference
+      "I-D.ietf-teas-enhanced-vpn:
+         A Framework for Enhanced Virtual Private Network
+         (VPN+) Services";
+  }
+
+  identity ietf-network-slice {
+    base transport-instance-type;
+    description
+      "IETF network slice. An IETF network slice
+       is a logical network topology connecting a number of
+       endpoints using a set of shared or dedicated network
+       resources that are used to satisfy specific service
+       objectives.";
+    reference
+      "I-D.ietf-teas-ietf-network-slices:
+         Framework for IETF Network Slices";
+  }
+
+  /*
+   *  Identities related to protocol types. These types are typically
+   *  used to identify the underlay transport.
+   */
+
+  identity protocol-type {
+    description
+      "Base identity for Protocol Type.";
+  }
+
+  identity ip-in-ip {
+    base protocol-type;
+    description
+      "Transport is based on IP-in-IP.";
+    reference
+      "RFC 2003: IP Encapsulation within IP
+       RFC 2473: Generic Packet Tunneling in IPv6 Specification";
+  }
+
+  identity ip-in-ipv4 {
+    base ip-in-ip;
+    description
+      "Transport is based on IP over IPv4.";
+    reference
+      "RFC 2003: IP Encapsulation within IP";
+  }
+
+  identity ip-in-ipv6 {
+    base ip-in-ip;
+    description
+      "Transport is based on IP over IPv6.";
+    reference
+      "RFC 2473: Generic Packet Tunneling in IPv6 Specification";
+  }
+
+  identity gre {
+    base protocol-type;
+    description
+      "Transport is based on Generic Routing Encapsulation (GRE).";
+    reference
+      "RFC 1701: Generic Routing Encapsulation (GRE)
+       RFC 1702: Generic Routing Encapsulation over IPv4 networks
+       RFC 7676: IPv6 Support for Generic Routing Encapsulation (GRE)";
+  }
+
+  identity gre-v4 {
+    base gre;
+    description
+      "Transport is based on GRE over IPv4.";
+    reference
+      "RFC 1702: Generic Routing Encapsulation over IPv4 networks";
+  }
+
+  identity gre-v6 {
+    base gre;
+    description
+      "Transport is based on GRE over IPv6.";
+    reference
+      "RFC 7676: IPv6 Support for Generic Routing Encapsulation (GRE)";
+  }
+
+  identity vxlan-trans {
+    base protocol-type;
+    description
+      "Transport is based on VXLAN.";
+    reference
+      "RFC 7348: Virtual eXtensible Local Area  Network (VXLAN):
+                 A Framework for Overlaying Virtualized Layer 2
+                 Networks over Layer 3 Networks";
+  }
+
+  identity geneve {
+    base protocol-type;
+    description
+      "Transport is based on Generic Network Virtualization
+       Encapsulation (GENEVE).";
+    reference
+      "RFC 8926: Geneve: Generic Network Virtualization Encapsulation";
+  }
+
+  identity ldp {
+    base protocol-type;
+    description
+      "Transport is based on LDP.";
+    reference
+      "RFC 5036: LDP Specification";
+  }
+
+  identity mpls-in-udp {
+    base protocol-type;
+    description
+      "Transport is MPLS in UDP.";
+    reference
+      "RFC 7510: Encapsulating MPLS in UDP";
+  }
+
+  identity sr {
+    base protocol-type;
+    description
+      "Transport is based on Segment Routing (SR).";
+    reference
+      "RFC 8660: Segment Routing with the MPLS Data Plane
+       RFC 8663: MPLS Segment Routing over IP
+       RFC 8754: IPv6 Segment Routing Header (SRH)";
+  }
+
+  identity sr-mpls {
+    base sr;
+    description
+      "Transport is based on SR with MPLS.";
+    reference
+      "RFC 8660: Segment Routing with the MPLS Data Plane";
+  }
+
+  identity srv6 {
+    base sr;
+    description
+      "Transport is based on SR over IPv6.";
+    reference
+      "RFC 8754: IPv6 Segment Routing Header (SRH)";
+  }
+
+  identity sr-mpls-over-ip {
+    base sr;
+    description
+      "Transport is based on SR over MPLS over IP.";
+    reference
+      "RFC 8663: MPLS Segment Routing over IP";
+  }
+
+  identity rsvp-te {
+    base protocol-type;
+    description
+      "Transport setup relies upon RSVP-TE.";
+    reference
+      "RFC 3209: RSVP-TE: Extensions to RSVP for LSP Tunnels";
+  }
+
+  identity bgp-lu {
+    base protocol-type;
+    description
+      "Transport setup relies upon BGP-LU.";
+    reference
+      "RFC 8277: Using BGP to Bind MPLS Labels to Address Prefixes";
+  }
+
+  identity unknown {
+    base protocol-type;
+    description
+      "Not known protocol type.";
+  }
+
+  /*
+   * Identities related to encapsulations
+   */
+
+  identity encapsulation-type {
+    description
+      "Base identity for the encapsulation type.";
+  }
+
+  identity priority-tagged {
+    base encapsulation-type;
+    description
+      "Priority-tagged interface.";
+  }
+
+  identity dot1q {
+    if-feature "dot1q";
+    base encapsulation-type;
+    description
+      "Dot1q encapsulation.";
+  }
+
+  identity qinq {
+    if-feature "qinq";
+    base encapsulation-type;
+    description
+      "QinQ encapsulation.";
+  }
+
+  identity qinany {
+    if-feature "qinany";
+    base encapsulation-type;
+    description
+      "QinAny encapsulation.";
+  }
+  identity vxlan {
+    if-feature "vxlan";
+    base encapsulation-type;
+    description
+      "VxLAN encapsulation.";
+  }
+
+  identity ethernet-type {
+    base encapsulation-type;
+    description
+      "Ethernet encapsulation type.";
+  }
+
+  identity vlan-type {
+    base encapsulation-type;
+    description
+      "VLAN encapsulation type.";
+  }
+
+  identity untagged-int {
+    base encapsulation-type;
+    description
+      "Untagged interface type.";
+  }
+
+  identity tagged-int {
+    base encapsulation-type;
+    description
+      "Tagged interface type.";
+  }
+
+  identity lag-int {
+    if-feature "lag-interface";
+    base encapsulation-type;
+    description
+      "LAG interface type.";
+  }
+
+  /*
+   * Identities related to VLAN Tag
+   */
+
+  identity tag-type {
+    description
+      "Base identity for the tag types.";
+  }
+
+  identity c-vlan {
+    base tag-type;
+    description
+      "Indicates Customer VLAN (C-VLAN) tag, normally using
+       the 0x8100 Ethertype.";
+  }
+
+  identity s-vlan {
+    base tag-type;
+    description
+      "Indicates Service VLAN (S-VLAN) tag.";
+  }
+
+  identity s-c-vlan {
+    base tag-type;
+    description
+      "Uses both an S-VLAN tag and a C-VLAN tag.";
+  }
+
+  /*
+   * Identities related to VXLAN
+   */
+
+  identity vxlan-peer-mode {
+    if-feature "vxlan";
+    description
+      "Base identity for the VXLAN peer mode.";
+  }
+
+  identity static-mode {
+    base vxlan-peer-mode;
+    description
+      "VXLAN access in the static mode.";
+  }
+
+  identity bgp-mode {
+    base vxlan-peer-mode;
+    description
+      "VXLAN access by BGP EVPN learning.";
+  }
+
+  /*
+   * Identities related to multicast
+   */
+
+  identity multicast-gp-address-mapping {
+    if-feature "multicast";
+    description
+      "Base identity for multicast group mapping type.";
+  }
+
+  identity static-mapping {
+    base multicast-gp-address-mapping;
+    description
+      "Static mapping, i.e., attach the interface to the
+       multicast group as a static member.";
+  }
+
+  identity dynamic-mapping {
+    base multicast-gp-address-mapping;
+    description
+      "Dynamic mapping, i.e., an interface is added to the
+       multicast group as a result of snooping.";
+  }
+
+  identity multicast-tree-type {
+    if-feature "multicast";
+    description
+      "Base identity for multicast tree type.";
+  }
+
+  identity ssm-tree-type {
+    base multicast-tree-type;
+    description
+      "Source-Specific Multicast (SSM) tree type.";
+  }
+
+  identity asm-tree-type {
+    base multicast-tree-type;
+    description
+      "Any-Source Multicast (ASM) tree type.";
+  }
+
+  identity bidir-tree-type {
+    base multicast-tree-type;
+    description
+      "Bidirectional tree type.";
+  }
+
+  identity multicast-rp-discovery-type {
+    if-feature "multicast";
+    description
+      "Base identity for Rendezvous Point (RP) discovery type.";
+  }
+
+  identity auto-rp {
+    base multicast-rp-discovery-type;
+    description
+      "Auto-RP discovery type.";
+  }
+
+  identity static-rp {
+    base multicast-rp-discovery-type;
+    description
+      "Static type.";
+  }
+
+  identity bsr-rp {
+    base multicast-rp-discovery-type;
+    description
+      "Bootstrap Router (BSR) discovery type.";
+  }
+
+  identity group-management-protocol {
+    if-feature "multicast";
+    description
+      "Base identity for multicast group management protocol.";
+  }
+
+  identity igmp-proto {
+    base group-management-protocol;
+    description
+      "IGMP.";
+    reference
+      "RFC 1112: Host Extensions for IP Multicasting
+       RFC 2236: Internet Group Management Protocol, Version 2
+       RFC 3376: Internet Group Management Protocol, Version 3";
+  }
+
+  identity mld-proto {
+    base group-management-protocol;
+    description
+      "MLD.";
+    reference
+      "RFC 2710: Multicast Listener Discovery (MLD) for IPv6
+       RFC 3810: Multicast Listener Discovery Version 2 (MLDv2)
+                 for IPv6";
+  }
+
+  identity pim-proto {
+    if-feature "pim";
+    base routing-protocol-type;
+    description
+      "PIM.";
+    reference
+      "RFC 7761: Protocol Independent Multicast - Sparse Mode
+                (PIM-SM): Protocol Specification (Revised)";
+  }
+
+  identity igmp-version {
+    if-feature "igmp";
+    description
+      "Base identity for IGMP version.";
+  }
+
+  identity igmpv1 {
+    base igmp-version;
+    description
+      "IGMPv1.";
+    reference
+      "RFC 1112: Host Extensions for IP Multicasting";
+  }
+
+  identity igmpv2 {
+    base igmp-version;
+    description
+      "IGMPv2.";
+    reference
+      "RFC 2236: Internet Group Management Protocol, Version 2";
+  }
+
+  identity igmpv3 {
+    base igmp-version;
+    description
+      "IGMPv3.";
+    reference
+      "RFC 3376: Internet Group Management Protocol, Version 3";
+  }
+
+  identity mld-version {
+    if-feature "mld";
+    description
+      "Base identity for MLD version.";
+  }
+
+  identity mldv1 {
+    base mld-version;
+    description
+      "MLDv1.";
+    reference
+      "RFC 2710: Multicast Listener Discovery (MLD) for IPv6";
+  }
+
+  identity mldv2 {
+    base mld-version;
+    description
+      "MLDv2.";
+    reference
+      "RFC 3810: Multicast Listener Discovery Version 2 (MLDv2)
+                 for IPv6";
+  }
+
+  /*
+   * Identities related to traffic types
+   */
+
+  identity tf-type {
+    description
+      "Base identity for the traffic type.";
+  }
+
+  identity multicast-traffic {
+    base tf-type;
+    description
+      "Multicast traffic.";
+  }
+
+  identity broadcast-traffic {
+    base tf-type;
+    description
+      "Broadcast traffic.";
+  }
+
+  identity unknown-unicast-traffic {
+    base tf-type;
+    description
+      "Unknown unicast traffic.";
+  }
+
+  /*
+   * Identities related to customer applications
+   */
+
+  identity customer-application {
+    description
+      "Base identity for customer applications.";
+  }
+
+  identity web {
+    base customer-application;
+    description
+      "Web applications (e.g., HTTP, HTTPS).";
+  }
+
+  identity mail {
+    base customer-application;
+    description
+      "Mail application.";
+  }
+
+  identity file-transfer {
+    base customer-application;
+    description
+      "File transfer application (e.g., FTP, SFTP).";
+  }
+
+  identity database {
+    base customer-application;
+    description
+      "Database application.";
+  }
+
+  identity social {
+    base customer-application;
+    description
+      "Social-network application.";
+  }
+
+  identity games {
+    base customer-application;
+    description
+      "Gaming application.";
+  }
+
+  identity p2p {
+    base customer-application;
+    description
+      "Peer-to-peer application.";
+  }
+
+  identity network-management {
+    base customer-application;
+    description
+      "Management application (e.g., Telnet, syslog,
+       SNMP).";
+  }
+
+  identity voice {
+    base customer-application;
+    description
+      "Voice application.";
+  }
+
+  identity video {
+    base customer-application;
+    description
+      "Video conference application.";
+  }
+
+  identity embb {
+    base customer-application;
+    description
+      "Enhanced Mobile Broadband (eMBB) application.
+       Note that an eMBB application demands network performance with a
+       wide variety of characteristics, such as data rate, latency,
+       loss rate, reliability, and many other parameters.";
+  }
+
+  identity urllc {
+    base customer-application;
+    description
+      "Ultra-Reliable and Low Latency Communications
+       (URLLC) application.  Note that an URLLC application demands
+       network performance with a wide variety of characteristics, such
+       as latency, reliability, and many other parameters.";
+  }
+
+  identity mmtc {
+    base customer-application;
+    description
+      "Massive Machine Type Communications (mMTC) application.
+       Note that an mMTC application demands network performance with
+       a wide variety of characteristics, such as data rate, latency,
+       loss rate, reliability, and many other parameters.";
+  }
+
+  /*
+   * Identities related to service bundling
+   */
+
+  identity bundling-type {
+    description
+      "The base identity for the bundling type. It supports a subset or
+       all CE-VLANs associated with an L2VPN service.";
+  }
+
+  identity multi-svc-bundling {
+    base bundling-type;
+    description
+      "Multi-service bundling, i.e., multiple C-VLAN IDs
+       can be associated with an L2VPN service at a site.";
+  }
+
+  identity one2one-bundling {
+    base bundling-type;
+    description
+      "One-to-one service bundling, i.e., each L2VPN can
+       be associated with only one C-VLAN ID at a site.";
+  }
+
+  identity all2one-bundling {
+    base bundling-type;
+    description
+      "All-to-one bundling, i.e., all C-VLAN IDs are mapped
+       to one L2VPN service.";
+  }
+
+  /*
+   * Identities related to Ethernet Services
+   */
+
+  identity control-mode {
+    description
+      "Base Identity for the type of control mode on Layer 2
+       Control Protocol (L2CP).";
+  }
+
+  identity peer {
+    base control-mode;
+    description
+      "'peer' mode, i.e., participate in the protocol towards the CE.
+       Peering is common for Link Aggregation Control Protocol (LACP)
+       and the Ethernet Local Management Interface (E-LMI) and,
+       occasionally, for Link Layer Discovery Protocol (LLDP).
+       For VPLSs and VPWSs, the subscriber can also request that the
+       peer service provider enables spanning tree.";
+  }
+
+  identity tunnel {
+    base control-mode;
+    description
+      "'tunnel' mode, i.e., pass to the egress or destination site. For
+       Ethernet Private Lines (EPLs), the expectation is that L2CP
+       frames are tunnelled.";
+  }
+  identity discard {
+    base control-mode;
+    description
+      "'Discard' mode, i.e., discard the frame.";
+  }
+
+  identity neg-mode {
+    description
+      "Base identity for the negotiation mode.";
+  }
+
+  identity full-duplex {
+    base neg-mode;
+    description
+      "Full-duplex negotiation mode.";
+  }
+
+  identity auto-neg {
+    base neg-mode;
+    description
+      "Auto-negotiation mode.";
+  }
+
+  /******** Collection of VPN-related Types ********/
+
+  typedef vpn-id {
+    type string;
+    description
+      "Defines an identifier that is used with a VPN module.
+       This can be, for example, a service identifier, a node
+       identifier, etc.";
+  }
+
+  /******* VPN-related reusable groupings *******/
+
+  grouping vpn-description {
+    description
+      "Provides common VPN information.";
+    leaf vpn-id {
+      type vpn-common:vpn-id;
+      description
+        "A VPN identifier that uniquely identifies a VPN.
+         This identifier has a local meaning, e.g., within
+         a service provider network.";
+    }
+    leaf vpn-name {
+      type string;
+      description
+        "Used to associate a name with the service
+         in order to facilitate the identification of
+         the service.";
+    }
+    leaf vpn-description {
+      type string;
+      description
+        "Textual description of a VPN.";
+    }
+    leaf customer-name {
+      type string;
+      description
+        "Name of the customer that actually uses the VPN.";
+    }
+  }
+
+  grouping vpn-profile-cfg {
+    description
+      "Grouping for VPN Profile configuration.";
+    container valid-provider-identifiers {
+      description
+        "Container for valid provider profile identifiers.";
+      list external-connectivity-identifier {
+        if-feature "external-connectivity";
+        key "id";
+        description
+          "List for profile identifiers that uniquely identify profiles
+           governing how external connectivity is provided to a VPN.
+           A profile indicates the type of external connectivity
+           (Internet, cloud, etc.), the sites/nodes that are associated
+           with a connectivity profile, etc. A profile can also indicate
+           filtering rules and/or address translation rules. Such
+           features may involve PE, P, or dedicated nodes as a function
+           of the deployment.";
+        leaf id {
+          type string;
+          description
+            "Identification of an external connectivity profile. The
+             profile only has significance within the service provider's
+             administrative domain.";
+        }
+      }
+      list encryption-profile-identifier {
+        key "id";
+        description
+          "List for encryption profile identifiers.";
+        leaf id {
+          type string;
+          description
+            "Identification of the encryption profile to be used. The
+             profile only has significance within the service provider's
+             administrative domain.";
+        }
+      }
+      list qos-profile-identifier {
+        key "id";
+        description
+          "List for QoS Profile Identifiers.";
+        leaf id {
+          type string;
+          description
+            "Identification of the QoS profile to be used. The
+             profile only has significance within the service provider's
+             administrative domain.";
+        }
+      }
+      list bfd-profile-identifier {
+        key "id";
+        description
+          "List for BFD profile identifiers.";
+        leaf id {
+          type string;
+          description
+            "Identification of the BFD profile to be used. The
+             profile only has significance within the service provider's
+             administrative domain.";
+        }
+      }
+      list forwarding-profile-identifier {
+        key "id";
+        description
+          "List for forwarding profile identifiers.";
+        leaf id {
+          type string;
+          description
+            "Identification of the forwarding profile to be used.
+             The profile only has significance within the service
+             provider's administrative domain.";
+        }
+      }
+      list routing-profile-identifier {
+        key "id";
+        description
+          "List for Routing Profile Identifiers.";
+        leaf id {
+          type string;
+          description
+            "Identification of the routing profile to be used by the
+             routing protocols within sites, vpn-network-accesses, or
+             vpn-nodes for refering VRF's import/export policies.
+
+             The profile only has significance within the service
+             provider's administrative domain.";
+        }
+      }
+      nacm:default-deny-write;
+    }
+  }
+
+  grouping oper-status-timestamp {
+    description
+      "This grouping defines some operational parameters for the
+       service.";
+    leaf status {
+      type identityref {
+        base operational-status;
+      }
+      config false;
+      description
+        "Operations status.";
+    }
+    leaf last-change {
+      type yang:date-and-time;
+      config false;
+      description
+        "Indicates the actual date and time of the service status
+         change.";
+    }
+  }
+
+  grouping service-status {
+    description
+      "Service status grouping.";
+    container status {
+      description
+        "Service status.";
+      container admin-status {
+        description
+          "Administrative service status.";
+        leaf status {
+          type identityref {
+            base administrative-status;
+          }
+          description
+            "Administrative service status.";
+        }
+        leaf last-change {
+          type yang:date-and-time;
+          description
+            "Indicates the actual date and time of the service status
+             change.";
+        }
+      }
+      container oper-status {
+        description
+          "Operational service status.";
+        uses oper-status-timestamp;
+      }
+    }
+  }
+
+  grouping underlay-transport {
+    description
+      "This grouping defines the type of underlay transport for the
+       VPN service or how that underlay is set. It can include an
+       identifier to an abstract transport instance to which the VPN
+       is grafted or indicate a technical implementation that is
+       expressed as an ordered list of protocols.";
+    choice type {
+      description
+        "A choice based on the type of underlay transport
+         constraints.";
+      case abstract {
+        description
+          "Indicates that the transport constraint is an abstract
+           concept.";
+        leaf transport-instance-id {
+          type string;
+          description
+            "An optional identifier of the abstract transport instance.";
+        }
+        leaf instance-type {
+          type identityref {
+            base transport-instance-type;
+          }
+          description
+            "Indicates a transport instance type. For example, it can
+             be a VPN+, an IETF network slice, a virtual network, etc.";
+        }
+      }
+      case protocol {
+        description
+          "Indicates a list of protocols.";
+        leaf-list protocol {
+          type identityref {
+            base protocol-type;
+          }
+          ordered-by user;
+          description
+            "A client ordered list of transport protocols.";
+        }
+      }
+    }
+  }
+
+  grouping vpn-route-targets {
+    description
+      "A grouping that specifies Route Target (RT) import-export rules
+       used in a BGP-enabled VPN.";
+    reference
+      "RFC 4364: BGP/MPLS IP Virtual Private Networks (VPNs)
+       RFC 4664: Framework for Layer 2 Virtual Private Networks
+                 (L2VPNs)";
+    list vpn-target {
+      key "id";
+      description
+        "Route targets. AND/OR operations may be defined
+         based on the RTs assigment.";
+      leaf id {
+        type uint8;
+        description
+          "Identifies each VPN Target.";
+      }
+      list route-targets {
+        key "route-target";
+        description
+          "List of RTs.";
+        leaf route-target {
+          type rt-types:route-target;
+          description
+            "Conveys an RT value.";
+        }
+      }
+      leaf route-target-type {
+        type rt-types:route-target-type;
+        mandatory true;
+        description
+          "Import/export type of the RT.";
+      }
+    }
+    container vpn-policies {
+      description
+        "VPN service policies. It contains references to the
+         import and export policies to be associated with the
+         VPN service.";
+      leaf import-policy {
+        type string;
+        description
+          "Identifies the 'import' policy.";
+      }
+      leaf export-policy {
+        type string;
+        description
+          "Identifies the 'export' policy.";
+      }
+    }
+  }
+
+  grouping route-distinguisher {
+    description
+      "Grouping for route distinguisher (RD).";
+    choice rd-choice {
+      description
+        "Route distinguisher choice between several options
+         on providing the route distinguisher value.";
+      case directly-assigned {
+        description
+          "Explicitly assign an RD value.";
+        leaf rd {
+          type rt-types:route-distinguisher;
+          description
+            "Indicates an RD value that is explicitly
+             assigned.";
+        }
+      }
+      case directly-assigned-suffix {
+        description
+          "The value of the Assigned Number subfield of the RD.
+           The Administrator subfield of the RD will be
+           based on other configuration information such as
+           router-id or ASN.";
+        leaf rd-suffix {
+          type uint16;
+          description
+            "Indicates the value of the Assigned Number
+             subfield that is explicitly assigned.";
+        }
+      }
+      case auto-assigned {
+        description
+          "The RD is auto-assigned.";
+        container rd-auto {
+          description
+            "The RD is auto-assigned.";
+          choice auto-mode {
+            description
+              "Indicates the auto-assignment mode. RD can be
+               automatically assigned with or without
+               indicating a pool from which the RD should be
+               taken.
+
+               For both cases, the server will auto-assign an RD
+               value 'auto-assigned-rd' and use that value
+               operationally.";
+            case from-pool {
+              leaf rd-pool-name {
+                type string;
+                description
+                  "The auto-assignment will be made from the pool
+                   identified by the rd-pool-name.";
+              }
+            }
+            case full-auto {
+              leaf auto {
+                type empty;
+                description
+                  "Indicates an RD is fully auto-assigned.";
+              }
+            }
+          }
+          leaf auto-assigned-rd {
+            type rt-types:route-distinguisher;
+            config false;
+            description
+              "The value of the auto-assigned RD.";
+          }
+        }
+      }
+      case auto-assigned-suffix {
+        description
+          "The value of the Assigned Number subfield will
+           be auto-assigned. The Administrator subfield
+           will be based on other configuration information such as
+           router-id or ASN.";
+        container rd-auto-suffix {
+          description
+            "The Assigned Number subfield is auto-assigned.";
+          choice auto-mode {
+            description
+              "Indicates the auto-assignment mode of the Assigned Number
+               subfield. This number can be automatically assigned
+               with or without indicating a pool from which the value
+               should be taken.
+
+               For both cases, the server will auto-assign
+               'auto-assigned-rd-suffix' and use that value to build
+               the RD that will be used operationally.";
+            case from-pool {
+              leaf rd-pool-name {
+                type string;
+                description
+                  "The assignment will be made from the pool identified
+                   by the rd-pool-name.";
+              }
+            }
+            case full-auto {
+              leaf auto {
+                type empty;
+                description
+                  "Indicates that the Assigned Number is fully auto
+                   assigned.";
+              }
+            }
+          }
+          leaf auto-assigned-rd-suffix {
+            type uint16;
+            config false;
+            description
+              "Includes the value of the Assigned Number subfield that
+               is auto-assigned .";
+          }
+        }
+      }
+      case no-rd {
+        description
+          "Use the empty type to indicate RD has no value and is not to
+           be auto-assigned.";
+        leaf no-rd {
+          type empty;
+          description
+            "No RD is assigned.";
+        }
+      }
+    }
+  }
+
+  grouping vpn-components-group {
+    description
+      "Grouping definition to assign group-ids to associate VPN nodes,
+       sites, or network accesses.";
+    container groups {
+      description
+        "Lists the groups to which a VPN node, a site, or a network
+         access belongs to.";
+      list group {
+        key "group-id";
+        description
+          "List of group-ids.";
+        leaf group-id {
+          type string;
+          description
+            "Is the group-id to which a VPN node, a site, or a network
+             access belongs to.";
+        }
+      }
+    }
+  }
+
+  grouping placement-constraints {
+    description
+      "Constraints for placing a network access.";
+    list constraint {
+      key "constraint-type";
+      description
+        "List of constraints.";
+      leaf constraint-type {
+        type identityref {
+          base placement-diversity;
+        }
+        description
+          "Diversity constraint type.";
+      }
+      container target {
+        description
+          "The constraint will apply against this list of groups.";
+        choice target-flavor {
+          description
+            "Choice for the group definition.";
+          case id {
+            list group {
+              key "group-id";
+              description
+                "List of groups.";
+              leaf group-id {
+                type string;
+                description
+                  "The constraint will apply against this particular
+                   group-id.";
+              }
+            }
+          }
+          case all-accesses {
+            leaf all-other-accesses {
+              type empty;
+              description
+                "The constraint will apply against all other network
+                 accesses of a site.";
+            }
+          }
+          case all-groups {
+            leaf all-other-groups {
+              type empty;
+              description
+                "The constraint will apply against all other groups that
+                 the customer is managing.";
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping ports {
+    description
+      "Choice of specifying a source or destination port numbers.";
+    choice source-port {
+      description
+        "Choice of specifying the source port or referring to a group
+         of source port numbers.";
+      container source-port-range-or-operator {
+        description
+          "Source port definition.";
+        uses packet-fields:port-range-or-operator;
+      }
+    }
+    choice destination-port {
+      description
+        "Choice of specifying a destination port or referring to a group
+         of destination port numbers.";
+      container destination-port-range-or-operator {
+        description
+          "Destination port definition.";
+        uses packet-fields:port-range-or-operator;
+      }
+    }
+  }
+
+  grouping qos-classification-policy {
+    description
+      "Configuration of the traffic classification policy.";
+    list rule {
+      key "id";
+      ordered-by user;
+      description
+        "List of marking rules.";
+      leaf id {
+        type string;
+        description
+          "An identifier of the QoS classification policy rule.";
+      }
+      choice match-type {
+        default "match-flow";
+        description
+          "Choice for classification.";
+        case match-flow {
+          choice l3 {
+            description
+              "Either IPv4 or IPv6.";
+            container ipv4 {
+              description
+                "Rule set that matches IPv4 header.";
+              uses packet-fields:acl-ip-header-fields;
+              uses packet-fields:acl-ipv4-header-fields;
+            }
+            container ipv6 {
+              description
+                "Rule set that matches IPv6 header.";
+              uses packet-fields:acl-ip-header-fields;
+              uses packet-fields:acl-ipv6-header-fields;
+            }
+          }
+          choice l4 {
+            description
+              "Includes Layer 4 specific information.
+               This version focuses on TCP and UDP.";
+            container tcp {
+              description
+                "Rule set that matches TCP header.";
+              uses packet-fields:acl-tcp-header-fields;
+              uses ports;
+            }
+            container udp {
+              description
+                "Rule set that matches UDP header.";
+              uses packet-fields:acl-udp-header-fields;
+              uses ports;
+            }
+          }
+        }
+        case match-application {
+          leaf match-application {
+            type identityref {
+              base customer-application;
+            }
+            description
+              "Defines the application to match.";
+          }
+        }
+      }
+      leaf target-class-id {
+        if-feature "qos";
+        type string;
+        description
+          "Identification of the class of service. This identifier is
+           internal to the administration.";
+      }
+    }
+  }
+}
diff --git a/src/nbi/tests/data/agg-net-topology.json b/src/nbi/tests/data/agg-net-topology.json
new file mode 100644
index 0000000000000000000000000000000000000000..bb27d6f258fb317662a30ab746bbe0d0ffff331f
--- /dev/null
+++ b/src/nbi/tests/data/agg-net-topology.json
@@ -0,0 +1,858 @@
+{
+    "contexts": [
+        {
+            "context_id": {
+                "context_uuid": {
+                    "uuid": "admin"
+                }
+            }
+        }
+    ],
+    "topologies": [
+        {
+            "topology_id": {
+                "context_id": {
+                    "context_uuid": {
+                        "uuid": "admin"
+                    }
+                },
+                "topology_uuid": {
+                    "uuid": "admin"
+                }
+            }
+        }
+    ],
+    "devices": [
+        {
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "ip-net-controller"
+                }
+            },
+            "name": "ip-net-controller",
+            "device_type": "ip-sdn-controller",
+            "device_operational_status": 1,
+            "device_drivers": [
+                13
+            ],
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "10.0.58.29"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "80"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [
+                                    {
+                                        "uuid": "mgmt",
+                                        "name": "mgmt",
+                                        "type": "mgmt"
+                                    }
+                                ],
+                                "scheme": "http",
+                                "username": "admin",
+                                "password": "admin",
+                                "base_url": "/restconf/v2/data",
+                                "timeout": 120,
+                                "verify": false
+                            }
+                        }
+                    }
+                ]
+            },
+            "device_endpoints": []
+        },
+        {
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "172.16.182.25"
+                }
+            },
+            "name": "172.16.182.25",
+            "device_type": "emu-packet-router",
+            "controller_id": {
+                "device_uuid": {
+                    "uuid": "ip-net-controller"
+                }
+            },
+            "device_operational_status": 1,
+            "device_drivers": [
+                13
+            ],
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [
+                                    {
+                                        "uuid": "mgmt",
+                                        "name": "mgmt",
+                                        "type": "mgmt"
+                                    },
+                                    {
+                                        "uuid": "200",
+                                        "name": "200",
+                                        "type": "optical",
+                                        "address_ip": "128.32.33.254",
+                                        "address_prefix": "24",
+                                        "site_location": "access"
+                                    },
+                                    {
+                                        "uuid": "500",
+                                        "name": "500",
+                                        "type": "optical"
+                                    },
+                                    {
+                                        "uuid": "501",
+                                        "name": "501",
+                                        "type": "optical"
+                                    }
+                                ]
+                            }
+                        }
+                    }
+                ]
+            }
+        },
+        {
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "172.16.185.31"
+                }
+            },
+            "name": "172.16.185.31",
+            "device_type": "emu-packet-router",
+            "controller_id": {
+                "device_uuid": {
+                    "uuid": "ip-net-controller"
+                }
+            },
+            "device_operational_status": 1,
+            "device_drivers": [
+                13
+            ],
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [
+                                    {
+                                        "uuid": "mgmt",
+                                        "name": "mgmt",
+                                        "type": "mgmt"
+                                    },
+                                    {
+                                        "uuid": "500",
+                                        "name": "500",
+                                        "type": "optical"
+                                    },
+                                    {
+                                        "uuid": "501",
+                                        "name": "501",
+                                        "type": "optical"
+                                    }
+                                ]
+                            }
+                        }
+                    }
+                ]
+            }
+        },
+        {
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "172.16.185.33"
+                }
+            },
+            "name": "172.16.185.33",
+            "device_type": "emu-packet-router",
+            "controller_id": {
+                "device_uuid": {
+                    "uuid": "ip-net-controller"
+                }
+            },
+            "device_operational_status": 1,
+            "device_drivers": [
+                13
+            ],
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [
+                                    {
+                                        "uuid": "mgmt",
+                                        "name": "mgmt",
+                                        "type": "mgmt"
+                                    },
+                                    {
+                                        "uuid": "500",
+                                        "name": "500",
+                                        "type": "optical"
+                                    },
+                                    {
+                                        "uuid": "501",
+                                        "name": "501",
+                                        "type": "optical"
+                                    }
+                                ]
+                            }
+                        }
+                    }
+                ]
+            }
+        },
+        {
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "172.16.185.32"
+                }
+            },
+            "name": "172.16.185.32",
+            "device_type": "emu-packet-router",
+            "controller_id": {
+                "device_uuid": {
+                    "uuid": "ip-net-controller"
+                }
+            },
+            "device_operational_status": 1,
+            "device_drivers": [
+                13
+            ],
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [
+                                    {
+                                        "uuid": "mgmt",
+                                        "name": "mgmt",
+                                        "type": "mgmt"
+                                    },
+                                    {
+                                        "uuid": "200",
+                                        "name": "200",
+                                        "type": "optical",
+                                        "address_ip": "172.10.33.254",
+                                        "address_prefix": "24",
+                                        "site_location": "cloud"
+                                    },
+                                    {
+                                        "uuid": "500",
+                                        "name": "500",
+                                        "type": "optical"
+                                    },
+                                    {
+                                        "uuid": "501",
+                                        "name": "501",
+                                        "type": "optical"
+                                    }
+                                ]
+                            }
+                        }
+                    }
+                ]
+            }
+        },
+        {
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "172.16.204.220"
+                }
+            },
+            "device_type": "emu-datacenter",
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_operational_status": 1,
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [
+                                    {
+                                        "sample_types": [],
+                                        "type": "optical",
+                                        "uuid": "500"
+                                    },
+                                    {
+                                        "sample_types": [],
+                                        "type": "optical",
+                                        "uuid": "200"
+                                    },
+                                    {
+                                        "sample_types": [],
+                                        "type": "optical",
+                                        "uuid": "201"
+                                    }
+                                ]
+                            }
+                        }
+                    }
+                ]
+            }
+        }
+    ],
+    "links": [
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "ip-net-controller/mgmt==172.16.182.25/mgmt"
+                }
+            },
+            "name": "ip-net-controller/mgmt==172.16.182.25/mgmt",
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "ip-net-controller"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "mgmt"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.182.25"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "mgmt"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "ip-net-controller/mgmt==172.16.185.31/mgmt"
+                }
+            },
+            "name": "ip-net-controller/mgmt==172.16.185.31/mgmt",
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "ip-net-controller"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "mgmt"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.31"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "mgmt"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "ip-net-controller/mgmt==172.16.185.33/mgmt"
+                }
+            },
+            "name": "ip-net-controller/mgmt==172.16.185.33/mgmt",
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "ip-net-controller"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "mgmt"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.33"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "mgmt"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "ip-net-controller/mgmt==172.16.185.32/mgmt"
+                }
+            },
+            "name": "ip-net-controller/mgmt==172.16.185.32/mgmt",
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "ip-net-controller"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "mgmt"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "mgmt"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.182.25-500"
+                }
+            },
+            "name": "172.16.182.25-500",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.182.25"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.33"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.33-500"
+                }
+            },
+            "name": "172.16.185.33-500",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.33"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.182.25"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.182.25-501"
+                }
+            },
+            "name": "172.16.182.25-501",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.182.25"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.31"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.31-501"
+                }
+            },
+            "name": "172.16.185.31-501",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.31"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.182.25"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.31-500"
+                }
+            },
+            "name": "172.16.185.31-500",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.31"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.32-500"
+                }
+            },
+            "name": "172.16.185.32-500",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.31"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.33-501"
+                }
+            },
+            "name": "172.16.185.33-501",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.33"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.32-501"
+                }
+            },
+            "name": "172.16.185.32-501",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.33"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.32-200"
+                }
+            },
+            "name": "172.16.185.32-200",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "200"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.204.220"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.204.220-500"
+                }
+            },
+            "name": "172.16.204.220-500",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.204.220"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "200"
+                    }
+                }
+            ]
+        }
+    ]
+}
diff --git a/src/nbi/tests/data/camara-e2e-topology.json b/src/nbi/tests/data/camara-e2e-topology.json
new file mode 100644
index 0000000000000000000000000000000000000000..02a21e6918c5d8fb49016d7babe75a51bf751979
--- /dev/null
+++ b/src/nbi/tests/data/camara-e2e-topology.json
@@ -0,0 +1,1725 @@
+{
+  "contexts": [
+    {
+      "context_id": {
+        "context_uuid": {
+          "uuid": "admin"
+        }
+      }
+    }
+  ],
+  "topologies": [
+    {
+      "topology_id": {
+        "context_id": {
+          "context_uuid": {
+            "uuid": "admin"
+          }
+        },
+        "topology_uuid": {
+          "uuid": "admin"
+        }
+      }
+    }
+  ],
+  "devices": [
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "ip-transport-controller"
+        }
+      },
+      "name": "ip-transport-controller",
+      "device_type": "ietf-slice",
+      "device_operational_status": 1,
+      "device_drivers": [
+        14
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "10.0.58.9"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "80"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  }
+                ],
+                "scheme": "http",
+                "username": "admin",
+                "password": "admin",
+                "base_url": "/restconf/v2/data",
+                "timeout": 120,
+                "verify": false
+              }
+            }
+          }
+        ]
+      },
+      "device_endpoints": []
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "agg-net-controller"
+        }
+      },
+      "name": "agg-net-controller",
+      "device_type": "ietf-slice",
+      "device_operational_status": 1,
+      "device_drivers": [
+        14
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "10.0.58.9"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "80"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  }
+                ],
+                "scheme": "http",
+                "username": "admin",
+                "password": "admin",
+                "base_url": "/restconf/v2/data",
+                "timeout": 120,
+                "verify": false
+              }
+            }
+          }
+        ]
+      },
+      "device_endpoints": []
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "nce-controller"
+        }
+      },
+      "name": "nce-controller",
+      "device_type": "nce",
+      "device_operational_status": 1,
+      "device_drivers": [
+        15
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "1.1.1.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "80"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  }
+                ],
+                "scheme": "http",
+                "username": "admin",
+                "password": "admin",
+                "base_url": "/restconf/v2/data",
+                "timeout": 120,
+                "verify": false
+              }
+            }
+          }
+        ]
+      },
+      "device_endpoints": []
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.182.25"
+        }
+      },
+      "name": "172.16.182.25",
+      "device_type": "emu-packet-router",
+      "controller_id": {
+        "device_uuid": {
+          "uuid": "ip-transport-controller"
+        }
+      },
+      "device_operational_status": 1,
+      "device_drivers": [
+        0,
+        14
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  },
+                  {
+                    "uuid": "200",
+                    "name": "200",
+                    "type": "optical",
+                    "address_ip": "128.32.33.254",
+                    "address_prefix": "24",
+                    "site_location": "access",
+                    "mtu": "1500"
+                  },
+                  {
+                    "uuid": "500",
+                    "name": "500",
+                    "type": "optical"
+                  },
+                  {
+                    "uuid": "501",
+                    "name": "501",
+                    "type": "optical"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.185.31"
+        }
+      },
+      "name": "172.16.185.31",
+      "device_type": "emu-packet-router",
+      "controller_id": {
+        "device_uuid": {
+          "uuid": "ip-transport-controller"
+        }
+      },
+      "device_operational_status": 1,
+      "device_drivers": [
+        0,
+        14
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  },
+                  {
+                    "uuid": "500",
+                    "name": "500",
+                    "type": "optical"
+                  },
+                  {
+                    "uuid": "501",
+                    "name": "501",
+                    "type": "optical"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.185.33"
+        }
+      },
+      "name": "172.16.185.33",
+      "device_type": "emu-packet-router",
+      "controller_id": {
+        "device_uuid": {
+          "uuid": "ip-transport-controller"
+        }
+      },
+      "device_operational_status": 1,
+      "device_drivers": [
+        0,
+        14
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  },
+                  {
+                    "uuid": "500",
+                    "name": "500",
+                    "type": "optical"
+                  },
+                  {
+                    "uuid": "501",
+                    "name": "501",
+                    "type": "optical"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.185.32"
+        }
+      },
+      "name": "172.16.185.32",
+      "device_type": "emu-packet-router",
+      "controller_id": {
+        "device_uuid": {
+          "uuid": "ip-transport-controller"
+        }
+      },
+      "device_operational_status": 1,
+      "device_drivers": [
+        0,
+        14
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  },
+                  {
+                    "uuid": "200",
+                    "name": "200",
+                    "type": "optical",
+                    "ce-ip": "172.10.33.2",
+                    "address_ip": "172.10.33.254",
+                    "address_prefix": "24",
+                    "site_location": "cloud",
+                    "mtu": "1500"
+                  },
+                  {
+                    "uuid": "500",
+                    "name": "500",
+                    "type": "optical"
+                  },
+                  {
+                    "uuid": "501",
+                    "name": "501",
+                    "type": "optical"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.58.10"
+        }
+      },
+      "name": "172.16.58.10",
+      "device_type": "emu-packet-router",
+      "controller_id": {
+        "device_uuid": {
+          "uuid": "nce-controller"
+        }
+      },
+      "device_operational_status": 1,
+      "device_drivers": [
+        15
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  },
+                  {
+                    "uuid": "200",
+                    "name": "200",
+                    "type": "optical",
+                    "address_ip": "0.0.0.0",
+                    "address_prefix": "24"
+                  },
+                  {
+                    "uuid": "201",
+                    "name": "201",
+                    "type": "optical",
+                    "address_ip": "0.0.0.0",
+                    "address_prefix": "24"
+                  },
+                  {
+                    "uuid": "500",
+                    "name": "500",
+                    "type": "optical",
+                    "address_ip": "128.32.33.2",
+                    "address_prefix": "24"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.61.10"
+        }
+      },
+      "name": "172.16.61.10",
+      "device_type": "emu-packet-router",
+      "controller_id": {
+        "device_uuid": {
+          "uuid": "nce-controller"
+        }
+      },
+      "device_operational_status": 1,
+      "device_drivers": [
+        15
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  },
+                  {
+                    "uuid": "200",
+                    "name": "200",
+                    "type": "optical",
+                    "address_ip": "0.0.0.0",
+                    "address_prefix": "24"
+                  },
+                  {
+                    "uuid": "500",
+                    "name": "500",
+                    "type": "optical",
+                    "address_ip": "128.32.33.2",
+                    "address_prefix": "24"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.61.11"
+        }
+      },
+      "name": "172.16.61.11",
+      "device_type": "emu-packet-router",
+      "controller_id": {
+        "device_uuid": {
+          "uuid": "nce-controller"
+        }
+      },
+      "device_operational_status": 1,
+      "device_drivers": [
+        15
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  },
+                  {
+                    "uuid": "200",
+                    "name": "200",
+                    "type": "optical",
+                    "address_ip": "0.0.0.0",
+                    "address_prefix": "24"
+                  },
+                  {
+                    "uuid": "500",
+                    "name": "500",
+                    "type": "optical",
+                    "address_ip": "128.32.33.2",
+                    "address_prefix": "24"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.104.221"
+        }
+      },
+      "device_type": "emu-datacenter",
+      "device_drivers": [
+        0
+      ],
+      "device_endpoints": [],
+      "device_operational_status": 1,
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "sample_types": [],
+                    "type": "copper",
+                    "uuid": "eth0"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.104.222"
+        }
+      },
+      "device_type": "emu-datacenter",
+      "device_drivers": [
+        0
+      ],
+      "device_endpoints": [],
+      "device_operational_status": 1,
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "sample_types": [],
+                    "type": "copper",
+                    "uuid": "eth0"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.204.220"
+        }
+      },
+      "device_type": "emu-datacenter",
+      "device_drivers": [
+        0
+      ],
+      "device_endpoints": [],
+      "device_operational_status": 1,
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "sample_types": [],
+                    "type": "optical",
+                    "uuid": "500"
+                  },
+                  {
+                    "sample_types": [],
+                    "type": "optical",
+                    "uuid": "200"
+                  },
+                  {
+                    "sample_types": [],
+                    "type": "optical",
+                    "uuid": "201"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    }
+  ],
+  "links": [
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "agg-net-controller/mgmt==ip-transport-controller/mgmt"
+        }
+      },
+      "name": "agg-net-controller/mgmt==ip-transport-controller/mgmt",
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "agg-net-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "ip-transport-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "nce-controller/mgmt==172.16.61.11/mgmt"
+        }
+      },
+      "name": "nce-controller/mgmt==172.16.61.11/mgmt",
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "nce-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.11"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "nce-controller/mgmt==172.16.61.10/mgmt"
+        }
+      },
+      "name": "nce-controller/mgmt==172.16.61.10/mgmt",
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "nce-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "nce-controller/mgmt==172.16.58.10/mgmt"
+        }
+      },
+      "name": "nce-controller/mgmt==172.16.58.10/mgmt",
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "nce-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.58.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "ip-transport-controller/mgmt==172.16.185.33/mgmt"
+        }
+      },
+      "name": "ip-transport-controller/mgmt==172.16.185.33/mgmt",
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "ip-transport-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.33"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "ip-transport-controller/mgmt==172.16.185.31/mgmt"
+        }
+      },
+      "name": "ip-transport-controller/mgmt==172.16.185.31/mgmt",
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "ip-transport-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.31"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "ip-transport-controller/mgmt==172.16.185.32/mgmt"
+        }
+      },
+      "name": "ip-transport-controller/mgmt==172.16.185.32/mgmt",
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "ip-transport-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.32"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "ip-transport-controller/mgmt==172.16.182.25/mgmt"
+        }
+      },
+      "name": "ip-transport-controller/mgmt==172.16.182.25/mgmt",
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "ip-transport-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.182.25"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.182.25-500"
+        }
+      },
+      "name": "172.16.182.25-500",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.182.25"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.33"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.185.33-500"
+        }
+      },
+      "name": "172.16.185.33-500",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.33"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.182.25"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.182.25-501"
+        }
+      },
+      "name": "172.16.182.25-501",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.182.25"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "501"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.31"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "501"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.185.31-501"
+        }
+      },
+      "name": "172.16.185.31-501",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.31"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "501"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.182.25"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "501"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.185.31-500"
+        }
+      },
+      "name": "172.16.185.31-500",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.31"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.32"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.185.32-500"
+        }
+      },
+      "name": "172.16.185.32-500",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.32"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.31"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.185.33-501"
+        }
+      },
+      "name": "172.16.185.33-501",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.33"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "501"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.32"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "501"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.185.32-501"
+        }
+      },
+      "name": "172.16.185.32-501",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.32"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "501"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.33"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "501"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.185.32-200"
+        }
+      },
+      "name": "172.16.185.32-200",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.32"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.204.220"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.204.220-500"
+        }
+      },
+      "name": "172.16.204.220-500",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.204.220"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.32"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.182.25-200"
+        }
+      },
+      "name": "172.16.182.25-200",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.182.25"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.58.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.58.10-500"
+        }
+      },
+      "name": "172.16.58.10-500",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.58.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.182.25"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.58.10-200"
+        }
+      },
+      "name": "172.16.58.10-200",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.58.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.61.10-500"
+        }
+      },
+      "name": "172.16.61.10-500",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.58.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.58.10-201"
+        }
+      },
+      "name": "172.16.58.10-201",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.58.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "201"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.11"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.61.11-500"
+        }
+      },
+      "name": "172.16.61.11-500",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.11"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.58.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "201"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.61.10-200"
+        }
+      },
+      "name": "172.16.61.10-200",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.104.221"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "eth0"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.104.221-eth0"
+        }
+      },
+      "name": "172.16.104.221-eth0",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.104.221"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "eth0"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.61.11-200"
+        }
+      },
+      "name": "172.16.61.11-200",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.11"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.104.222"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "eth0"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.104.222-eth0"
+        }
+      },
+      "name": "172.16.104.222-eth0",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.104.222"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "eth0"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.11"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/src/nbi/tests/data/ip-net-descriptor.json b/src/nbi/tests/data/ip-net-descriptor.json
new file mode 100644
index 0000000000000000000000000000000000000000..dafeeb5bc22dd457fa7b924a30feac660b38f491
--- /dev/null
+++ b/src/nbi/tests/data/ip-net-descriptor.json
@@ -0,0 +1,535 @@
+{
+    "contexts": [
+        {
+            "context_id": {
+                "context_uuid": {
+                    "uuid": "admin"
+                }
+            }
+        }
+    ],
+    "topologies": [
+        {
+            "topology_id": {
+                "context_id": {
+                    "context_uuid": {
+                        "uuid": "admin"
+                    }
+                },
+                "topology_uuid": {
+                    "uuid": "admin"
+                }
+            }
+        }
+    ],
+    "devices": [
+        {
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "172.16.182.25"
+                }
+            },
+            "name": "172.16.182.25",
+            "device_type": "emu-packet-router",
+            "device_operational_status": 1,
+            "device_drivers": [
+                0
+            ],
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [
+                                    {
+                                        "uuid": "mgmt",
+                                        "name": "mgmt",
+                                        "type": "mgmt"
+                                    },
+                                    {
+                                        "uuid": "200",
+                                        "name": "200",
+                                        "type": "optical"
+                                    },
+                                    {
+                                        "uuid": "500",
+                                        "name": "500",
+                                        "type": "optical"
+                                    },
+                                    {
+                                        "uuid": "501",
+                                        "name": "501",
+                                        "type": "optical"
+                                    }
+                                ]
+                            }
+                        }
+                    }
+                ]
+            }
+        },
+        {
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "172.16.185.31"
+                }
+            },
+            "name": "172.16.185.31",
+            "device_type": "emu-packet-router",
+            "device_operational_status": 1,
+            "device_drivers": [
+                0
+            ],
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [
+                                    {
+                                        "uuid": "mgmt",
+                                        "name": "mgmt",
+                                        "type": "mgmt"
+                                    },
+                                    {
+                                        "uuid": "500",
+                                        "name": "500",
+                                        "type": "optical"
+                                    },
+                                    {
+                                        "uuid": "501",
+                                        "name": "501",
+                                        "type": "optical"
+                                    }
+                                ]
+                            }
+                        }
+                    }
+                ]
+            }
+        },
+        {
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "172.16.185.33"
+                }
+            },
+            "name": "172.16.185.33",
+            "device_type": "emu-packet-router",
+            "device_operational_status": 1,
+            "device_drivers": [
+                0
+            ],
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [
+                                    {
+                                        "uuid": "mgmt",
+                                        "name": "mgmt",
+                                        "type": "mgmt"
+                                    },
+                                    {
+                                        "uuid": "500",
+                                        "name": "500",
+                                        "type": "optical"
+                                    },
+                                    {
+                                        "uuid": "501",
+                                        "name": "501",
+                                        "type": "optical"
+                                    }
+                                ]
+                            }
+                        }
+                    }
+                ]
+            }
+        },
+        {
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "172.16.185.32"
+                }
+            },
+            "name": "172.16.185.32",
+            "device_type": "emu-packet-router",
+            "device_operational_status": 1,
+            "device_drivers": [
+                0
+            ],
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [
+                                    {
+                                        "uuid": "mgmt",
+                                        "name": "mgmt",
+                                        "type": "mgmt"
+                                    },
+                                    {
+                                        "uuid": "200",
+                                        "name": "200",
+                                        "type": "optical"
+                                    },
+                                    {
+                                        "uuid": "500",
+                                        "name": "500",
+                                        "type": "optical"
+                                    },
+                                    {
+                                        "uuid": "501",
+                                        "name": "501",
+                                        "type": "optical"
+                                    }
+                                ]
+                            }
+                        }
+                    }
+                ]
+            }
+        }
+    ],
+    "links": [
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.182.25-500"
+                }
+            },
+            "name": "172.16.182.25-500",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.182.25"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.33"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.33-500"
+                }
+            },
+            "name": "172.16.185.33-500",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.33"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.182.25"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.182.25-501"
+                }
+            },
+            "name": "172.16.182.25-501",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.182.25"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.31"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.31-501"
+                }
+            },
+            "name": "172.16.185.31-501",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.31"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.182.25"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.31-500"
+                }
+            },
+            "name": "172.16.185.31-500",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.31"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.32-500"
+                }
+            },
+            "name": "172.16.185.32-500",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.31"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.33-501"
+                }
+            },
+            "name": "172.16.185.33-501",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.33"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.32-501"
+                }
+            },
+            "name": "172.16.185.32-501",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.33"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                }
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/nbi/tests/data/slice/post_connection_group_to_network_slice1.json b/src/nbi/tests/data/slice/post_connection_group_to_network_slice1.json
new file mode 100644
index 0000000000000000000000000000000000000000..d39a837bd8c3719463e8ecfd3fbfc2d25111afef
--- /dev/null
+++ b/src/nbi/tests/data/slice/post_connection_group_to_network_slice1.json
@@ -0,0 +1,62 @@
+{
+    "connection-group": [
+        {
+            "id": "line2",
+            "connectivity-type": "point-to-point",
+            "connectivity-construct": [
+                {
+                    "id": 1,
+                    "p2p-sender-sdp": "1",
+                    "p2p-receiver-sdp": "3",
+                    "service-slo-sle-policy": {
+                        "slo-policy": {
+                            "metric-bound": [
+                                {
+                                    "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                                    "metric-unit": "milliseconds",
+                                    "bound": "10"
+                                },
+                                {
+                                    "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                                    "metric-unit": "Mbps",
+                                    "bound": "5000"
+                                },
+                                {
+                                    "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                                    "metric-unit": "percentage",
+                                    "percentile-value": "0.001"
+                                }
+                            ]
+                        }
+                    }
+                },
+                {
+                    "id": 2,
+                    "p2p-sender-sdp": "3",
+                    "p2p-receiver-sdp": "1",
+                    "service-slo-sle-policy": {
+                        "slo-policy": {
+                            "metric-bound": [
+                                {
+                                    "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                                    "metric-unit": "milliseconds",
+                                    "bound": "20"
+                                },
+                                {
+                                    "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                                    "metric-unit": "Mbps",
+                                    "bound": "1000"
+                                },
+                                {
+                                    "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                                    "metric-unit": "percentage",
+                                    "percentile-value": "0.001"
+                                }
+                            ]
+                        }
+                    }
+                }
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/nbi/tests/data/slice/post_connection_group_to_network_slice2.json b/src/nbi/tests/data/slice/post_connection_group_to_network_slice2.json
new file mode 100644
index 0000000000000000000000000000000000000000..d39a837bd8c3719463e8ecfd3fbfc2d25111afef
--- /dev/null
+++ b/src/nbi/tests/data/slice/post_connection_group_to_network_slice2.json
@@ -0,0 +1,62 @@
+{
+    "connection-group": [
+        {
+            "id": "line2",
+            "connectivity-type": "point-to-point",
+            "connectivity-construct": [
+                {
+                    "id": 1,
+                    "p2p-sender-sdp": "1",
+                    "p2p-receiver-sdp": "3",
+                    "service-slo-sle-policy": {
+                        "slo-policy": {
+                            "metric-bound": [
+                                {
+                                    "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                                    "metric-unit": "milliseconds",
+                                    "bound": "10"
+                                },
+                                {
+                                    "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                                    "metric-unit": "Mbps",
+                                    "bound": "5000"
+                                },
+                                {
+                                    "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                                    "metric-unit": "percentage",
+                                    "percentile-value": "0.001"
+                                }
+                            ]
+                        }
+                    }
+                },
+                {
+                    "id": 2,
+                    "p2p-sender-sdp": "3",
+                    "p2p-receiver-sdp": "1",
+                    "service-slo-sle-policy": {
+                        "slo-policy": {
+                            "metric-bound": [
+                                {
+                                    "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                                    "metric-unit": "milliseconds",
+                                    "bound": "20"
+                                },
+                                {
+                                    "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                                    "metric-unit": "Mbps",
+                                    "bound": "1000"
+                                },
+                                {
+                                    "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                                    "metric-unit": "percentage",
+                                    "percentile-value": "0.001"
+                                }
+                            ]
+                        }
+                    }
+                }
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/nbi/tests/data/slice/post_match_criteria_to_sdp1_in_slice1.json b/src/nbi/tests/data/slice/post_match_criteria_to_sdp1_in_slice1.json
new file mode 100644
index 0000000000000000000000000000000000000000..16a36d45b86230b27eafa45a612b95c248a7b3ac
--- /dev/null
+++ b/src/nbi/tests/data/slice/post_match_criteria_to_sdp1_in_slice1.json
@@ -0,0 +1,40 @@
+{
+    "match-criterion": [
+        {
+            "index": 2,
+            "match-type": [
+                {
+                    "type": "ietf-network-slice-service:vlan",
+                    "value": [
+                        "101"
+                    ]
+                },
+                {
+                    "type": "ietf-network-slice-service:source-ip-prefix",
+                    "value": [
+                        "172.1.101.22/24"
+                    ]
+                },
+                {
+                    "type": "ietf-network-slice-service:source-tcp-port",
+                    "value": [
+                        "10200"
+                    ]
+                },
+                {
+                    "type": "ietf-network-slice-service:destination-ip-prefix",
+                    "value": [
+                        "172.16.104.222/24"
+                    ]
+                },
+                {
+                    "type": "ietf-network-slice-service:destination-tcp-port",
+                    "value": [
+                        "10500"
+                    ]
+                }
+            ],
+            "target-connection-group-id": "line2"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/nbi/tests/data/slice/post_match_criteria_to_sdp1_in_slice2.json b/src/nbi/tests/data/slice/post_match_criteria_to_sdp1_in_slice2.json
new file mode 100644
index 0000000000000000000000000000000000000000..8ceefdc2f2471af225143e5a1def2d7ba71e2ab1
--- /dev/null
+++ b/src/nbi/tests/data/slice/post_match_criteria_to_sdp1_in_slice2.json
@@ -0,0 +1,40 @@
+{
+    "match-criterion": [
+        {
+            "index": 2,
+            "match-type": [
+                {
+                    "type": "ietf-network-slice-service:vlan",
+                    "value": [
+                        "201"
+                    ]
+                },
+                {
+                    "type": "ietf-network-slice-service:source-ip-prefix",
+                    "value": [
+                        "172.1.201.22/24"
+                    ]
+                },
+                {
+                    "type": "ietf-network-slice-service:source-tcp-port",
+                    "value": [
+                        "10200"
+                    ]
+                },
+                {
+                    "type": "ietf-network-slice-service:destination-ip-prefix",
+                    "value": [
+                        "172.16.104.222/24"
+                    ]
+                },
+                {
+                    "type": "ietf-network-slice-service:destination-tcp-port",
+                    "value": [
+                        "10500"
+                    ]
+                }
+            ],
+            "target-connection-group-id": "line2"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/nbi/tests/data/slice/post_network_slice1.json b/src/nbi/tests/data/slice/post_network_slice1.json
new file mode 100644
index 0000000000000000000000000000000000000000..e6e0ee90a25ff12f73c8f8896f9c2c74ab6b4019
--- /dev/null
+++ b/src/nbi/tests/data/slice/post_network_slice1.json
@@ -0,0 +1,188 @@
+{
+    "slice-service": [
+        {
+            "id": "slice1",
+            "description": "network slice 1, connect to VM1",
+            "sdps": {
+                "sdp": [
+                    {
+                        "id": "1",
+                        "node-id": "172.16.204.220",
+                        "sdp-ip-address": [
+                            "172.16.204.220"
+                        ],
+                        "service-match-criteria": {
+                            "match-criterion": [
+                                {
+                                    "index": 1,
+                                    "match-type": [
+                                        {
+                                            "type": "ietf-network-slice-service:vlan",
+                                            "value": [
+                                                "101"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:destination-ip-prefix",
+                                            "value": [
+                                                "172.16.104.221/24"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:destination-tcp-port",
+                                            "value": [
+                                                "10500"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:source-ip-prefix",
+                                            "value": [
+                                                "172.1.101.22/24"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:source-tcp-port",
+                                            "value": [
+                                                "10200"
+                                            ]
+                                        }
+                                    ],
+                                    "target-connection-group-id": "line1"
+                                }
+                            ]
+                        },
+                        "attachment-circuits": {
+                            "attachment-circuit": [
+                                {
+                                    "id": "AC POP to VM1",
+                                    "description": "AC VM1 connected to POP",
+                                    "ac-node-id": "172.16.204.220",
+                                    "ac-tp-id": "200"
+                                }
+                            ]
+                        }
+                    },
+                    {
+                        "id": "2",
+                        "node-id": "172.16.61.10",
+                        "sdp-ip-address": [
+                            "172.16.61.10"
+                        ],
+                        "service-match-criteria": {
+                            "match-criterion": [
+                                {
+                                    "index": 1,
+                                    "match-type": [
+                                        {
+                                            "type": "ietf-network-slice-service:vlan",
+                                            "value": [
+                                                "21"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:source-ip-prefix",
+                                            "value": [
+                                                "172.16.104.221/24"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:source-tcp-port",
+                                            "value": [
+                                                "10500"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:destination-ip-prefix",
+                                            "value": [
+                                                "172.1.101.22/24"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:destination-tcp-port",
+                                            "value": [
+                                                "10200"
+                                            ]
+                                        }
+                                    ],
+                                    "target-connection-group-id": "line1"
+                                }
+                            ]
+                        },
+                        "attachment-circuits": {
+                            "attachment-circuit": [
+                                {
+                                    "id": "AC ONT",
+                                    "description": "AC connected to PC1",
+                                    "ac-node-id": "172.16.61.10",
+                                    "ac-tp-id": "200"
+                                }
+                            ]
+                        }
+                    }
+                ]
+            },
+            "connection-groups": {
+                "connection-group": [
+                    {
+                        "id": "line1",
+                        "connectivity-type": "point-to-point",
+                        "connectivity-construct": [
+                            {
+                                "id": 1,
+                                "p2p-sender-sdp": "1",
+                                "p2p-receiver-sdp": "2",
+                                "service-slo-sle-policy": {
+                                    "slo-policy": {
+                                        "metric-bound": [
+                                            {
+                                                "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                                                "metric-unit": "milliseconds",
+                                                "bound": "10"
+                                            },
+                                            {
+                                                "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                                                "metric-unit": "Mbps",
+                                                "bound": "5000"
+                                            },
+                                            {
+                                                "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                                                "metric-unit": "percentage",
+                                                "percentile-value": "0.001"
+                                            }
+                                        ]
+                                    }
+                                }
+                            },
+                            {
+                                "id": 2,
+                                "p2p-sender-sdp": "2",
+                                "p2p-receiver-sdp": "1",
+                                "service-slo-sle-policy": {
+                                    "slo-policy": {
+                                        "metric-bound": [
+                                            {
+                                                "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                                                "metric-unit": "milliseconds",
+                                                "bound": "20"
+                                            },
+                                            {
+                                                "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                                                "metric-unit": "Mbps",
+                                                "bound": "1000"
+                                            },
+                                            {
+                                                "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                                                "metric-unit": "percentage",
+                                                "percentile-value": "0.001"
+                                            }
+                                        ]
+                                    }
+                                }
+                            }
+                        ]
+                    }
+                ]
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/nbi/tests/data/slice/post_network_slice2.json b/src/nbi/tests/data/slice/post_network_slice2.json
new file mode 100644
index 0000000000000000000000000000000000000000..97e6ade27449be0a3816085aa31b707ffbb6f813
--- /dev/null
+++ b/src/nbi/tests/data/slice/post_network_slice2.json
@@ -0,0 +1,189 @@
+{
+    "slice-service": [
+        {
+            "id": "slice2",
+            "description": "network slice 2, connect to VM2",
+            "sdps": {
+                "sdp": [
+                    {
+                        "id": "1",
+                        "node-id": "172.16.204.220",
+                        "sdp-ip-address": [
+                            "172.16.204.220"
+                        ],
+                        "service-match-criteria": {
+                            "match-criterion": [
+                                {
+                                    "index": 1,
+                                    "match-type": [
+                                        {
+                                            "type": "ietf-network-slice-service:vlan",
+                                            "value": [
+                                                "201"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:destination-ip-prefix",
+                                            "value": [
+                                                "172.16.104.221/24"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:destination-tcp-port",
+                                            "value": [
+                                                "10500"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:source-ip-prefix",
+                                            "value": [
+                                                "172.1.201.22/24"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:source-tcp-port",
+                                            "value": [
+                                                "10200"
+                                            ]
+                                        }
+                                    ],
+                                    "target-connection-group-id": "line1"
+                                }
+                            ]
+                        },
+                        "attachment-circuits": {
+                            "attachment-circuit": [
+                                {
+                                    "id": "AC POP to VM2",
+                                    "description": "AC VM2 connected to POP",
+                                    "ac-node-id": "172.16.204.220",
+                                    "ac-tp-id": "201"
+                                }
+                            ]
+                        }
+                    },
+                    {
+                        "id": "2",
+                        "node-id": "172.16.61.10",
+                        "sdp-ip-address": [
+                            "172.16.61.10"
+                        ],
+                        "service-match-criteria": {
+                            "match-criterion": [
+                                {
+                                    "index": 1,
+                                    "match-type": [
+                                        {
+                                            "type": "ietf-network-slice-service:vlan",
+                                            "value": [
+                                                "31"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:source-ip-prefix",
+                                            "value": [
+                                                "172.16.104.221/24"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:source-tcp-port",
+                                            "value": [
+                                                "10500"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:destination-ip-prefix",
+                                            "value": [
+                                                "172.1.201.22/24"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:destination-tcp-port",
+                                            "value": [
+                                                "10200"
+                                            ]
+                                        }
+                                    ],
+                                    "target-connection-group-id": "line1"
+                                }
+                            ]
+                        },
+                        "attachment-circuits": {
+                            "attachment-circuit": [
+                                {
+                                    "id": "AC ONT",
+                                    "description": "AC connected to PC",
+                                    "ac-node-id": "172.16.61.10",
+                                    "ac-tp-id": "200",
+                                    "ac-ipv4-address": "172.16.61.10"
+                                }
+                            ]
+                        }
+                    }
+                ]
+            },
+            "connection-groups": {
+                "connection-group": [
+                    {
+                        "id": "line1",
+                        "connectivity-type": "point-to-point",
+                        "connectivity-construct": [
+                            {
+                                "id": 1,
+                                "p2p-sender-sdp": "1",
+                                "p2p-receiver-sdp": "2",
+                                "service-slo-sle-policy": {
+                                    "slo-policy": {
+                                        "metric-bound": [
+                                            {
+                                                "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                                                "metric-unit": "milliseconds",
+                                                "bound": "10"
+                                            },
+                                            {
+                                                "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                                                "metric-unit": "Mbps",
+                                                "bound": "5000"
+                                            },
+                                            {
+                                                "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                                                "metric-unit": "percentage",
+                                                "percentile-value": "0.001"
+                                            }
+                                        ]
+                                    }
+                                }
+                            },
+                            {
+                                "id": 2,
+                                "p2p-sender-sdp": "2",
+                                "p2p-receiver-sdp": "1",
+                                "service-slo-sle-policy": {
+                                    "slo-policy": {
+                                        "metric-bound": [
+                                            {
+                                                "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                                                "metric-unit": "milliseconds",
+                                                "bound": "20"
+                                            },
+                                            {
+                                                "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                                                "metric-unit": "Mbps",
+                                                "bound": "1000"
+                                            },
+                                            {
+                                                "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                                                "metric-unit": "percentage",
+                                                "percentile-value": "0.001"
+                                            }
+                                        ]
+                                    }
+                                }
+                            }
+                        ]
+                    }
+                ]
+            }
+        }
+    ]
+}
diff --git a/src/nbi/tests/data/slice/post_sdp_to_network_slice1.json b/src/nbi/tests/data/slice/post_sdp_to_network_slice1.json
new file mode 100644
index 0000000000000000000000000000000000000000..bd3895fc4ae5a9a0b2059be3f6b31a05451abd22
--- /dev/null
+++ b/src/nbi/tests/data/slice/post_sdp_to_network_slice1.json
@@ -0,0 +1,61 @@
+{
+    "sdp": [
+        {
+            "id": "3",
+            "node-id": "172.16.61.11",
+            "sdp-ip-address": [
+                "172.16.61.11"
+            ],
+            "service-match-criteria": {
+                "match-criterion": [
+                    {
+                        "index": 1,
+                        "match-type": [
+                            {
+                                "type": "ietf-network-slice-service:vlan",
+                                "value": [
+                                    "21"
+                                ]
+                            },
+                            {
+                                "type": "ietf-network-slice-service:source-ip-prefix",
+                                "value": [
+                                    "172.16.104.222/24"
+                                ]
+                            },
+                            {
+                                "type": "ietf-network-slice-service:source-tcp-port",
+                                "value": [
+                                    "10500"
+                                ]
+                            },
+                            {
+                                "type": "ietf-network-slice-service:destination-ip-prefix",
+                                "value": [
+                                    "172.1.101.22/24"
+                                ]
+                            },
+                            {
+                                "type": "ietf-network-slice-service:destination-tcp-port",
+                                "value": [
+                                    "10200"
+                                ]
+                            }
+                        ],
+                        "target-connection-group-id": "line2"
+                    }
+                ]
+            },
+            "attachment-circuits": {
+                "attachment-circuit": [
+                    {
+                        "id": "AC ONT",
+                        "description": "AC connected to PC2",
+                        "ac-node-id": "172.16.61.11",
+                        "ac-tp-id": "200"
+                    }
+                ]
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/nbi/tests/data/slice/post_sdp_to_network_slice2.json b/src/nbi/tests/data/slice/post_sdp_to_network_slice2.json
new file mode 100644
index 0000000000000000000000000000000000000000..0b147125bd7eb3efc84c87bebab919639782f760
--- /dev/null
+++ b/src/nbi/tests/data/slice/post_sdp_to_network_slice2.json
@@ -0,0 +1,62 @@
+{
+    "sdp": [
+        {
+            "id": "3",
+            "node-id": "172.16.61.11",
+            "sdp-ip-address": [
+                "172.16.61.11"
+            ],
+            "service-match-criteria": {
+                "match-criterion": [
+                    {
+                        "index": 1,
+                        "match-type": [
+                            {
+                                "type": "ietf-network-slice-service:vlan",
+                                "value": [
+                                    "31"
+                                ]
+                            },
+                            {
+                                "type": "ietf-network-slice-service:source-ip-prefix",
+                                "value": [
+                                    "172.16.104.222/24"
+                                ]
+                            },
+                            {
+                                "type": "ietf-network-slice-service:source-tcp-port",
+                                "value": [
+                                    "10500"
+                                ]
+                            },
+                            {
+                                "type": "ietf-network-slice-service:destination-ip-prefix",
+                                "value": [
+                                    "172.1.201.22/24"
+                                ]
+                            },
+                            {
+                                "type": "ietf-network-slice-service:destination-tcp-port",
+                                "value": [
+                                    "10200"
+                                ]
+                            }
+                        ],
+                        "target-connection-group-id": "line2"
+                    }
+                ]
+            },
+            "attachment-circuits": {
+                "attachment-circuit": [
+                    {
+                        "id": "AC ONT",
+                        "description": "AC connected to PC2",
+                        "ac-node-id": "172.16.61.11",
+                        "ac-tp-id": "200",
+                        "ac-ipv4-address": "172.16.61.11"
+                    }
+                ]
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/nbi/tests/test_slice_2.py b/src/nbi/tests/test_slice_2.py
new file mode 100644
index 0000000000000000000000000000000000000000..5722e3d922a79bd169fc80a5374c4daab4f5d7d9
--- /dev/null
+++ b/src/nbi/tests/test_slice_2.py
@@ -0,0 +1,205 @@
+# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+from typing import Optional
+
+from common.proto.context_pb2 import ConfigRule, ServiceConfig, SliceList
+from context.client.ContextClient import ContextClient
+from nbi.service.rest_server.nbi_plugins.ietf_network_slice.ietf_slice_handler import (
+    IETFSliceHandler,
+)
+
+
+def get_custom_config_rule(
+    service_config: ServiceConfig, resource_key: str
+) -> Optional[ConfigRule]:
+    for cr in service_config.config_rules:
+        if (
+            cr.WhichOneof("config_rule") == "custom"
+            and cr.custom.resource_key == resource_key
+        ):
+            return cr
+
+
+RUNNING_RESOURCE_KEY = "running_ietf_slice"
+CANDIDATE_RESOURCE_KEY = "candidate_ietf_slice"
+
+context_client = ContextClient()
+
+with open("nbi/tests/data/slice/post_network_slice1.json", mode="r") as f:
+    post_slice_request = json.load(f)
+
+with open("nbi/tests/data/slice/post_sdp_to_network_slice1.json", mode="r") as f:
+    post_sdp_request = json.load(f)
+
+with open(
+    "nbi/tests/data/slice/post_connection_group_to_network_slice1.json", mode="r"
+) as f:
+    post_connection_group_request = json.load(f)
+
+with open(
+    "nbi/tests/data/slice/post_match_criteria_to_sdp1_in_slice1.json", mode="r"
+) as f:
+    post_match_criteria_request = json.load(f)
+
+slice_1 = None
+
+
+def select_slice(*args) -> SliceList:
+    slice_list = SliceList()
+    slice_list.slices.extend([slice_1])
+    return slice_list
+
+
+def test_create_slice():
+    global slice_1
+
+    slice_1 = IETFSliceHandler.create_slice_service(post_slice_request)
+    candidate_ietf_data = json.loads(
+        get_custom_config_rule(
+            slice_1.slice_config, CANDIDATE_RESOURCE_KEY
+        ).custom.resource_value
+    )
+    assert candidate_ietf_data["network-slice-services"] == post_slice_request
+    assert slice_1.slice_endpoint_ids[0].device_id.device_uuid.uuid == "172.16.204.220"
+    assert slice_1.slice_endpoint_ids[1].device_id.device_uuid.uuid == "172.16.61.10"
+    assert slice_1.slice_id.slice_uuid.uuid == "slice1"
+
+
+def test_create_sdp(monkeypatch):
+    global slice_1
+
+    monkeypatch.setattr(context_client, "SelectSlice", select_slice)
+
+    slice_1 = IETFSliceHandler.create_sdp(post_sdp_request, "slice1", context_client)
+    candidate_ietf_data = json.loads(
+        get_custom_config_rule(
+            slice_1.slice_config, CANDIDATE_RESOURCE_KEY
+        ).custom.resource_value
+    )
+    slice_services = candidate_ietf_data["network-slice-services"]["slice-service"]
+    slice_service = slice_services[0]
+    slice_sdps = slice_service["sdps"]["sdp"]
+    assert len(slice_sdps) == 3
+
+
+def test_create_connection_group(monkeypatch):
+    global slice_1
+
+    monkeypatch.setattr(context_client, "SelectSlice", select_slice)
+
+    slice_1 = IETFSliceHandler.create_connection_group(
+        post_connection_group_request, "slice1", context_client
+    )
+    candidate_ietf_data = json.loads(
+        get_custom_config_rule(
+            slice_1.slice_config, CANDIDATE_RESOURCE_KEY
+        ).custom.resource_value
+    )
+    slice_services = candidate_ietf_data["network-slice-services"]["slice-service"]
+    slice_service = slice_services[0]
+    slice_connection_groups = slice_service["connection-groups"]["connection-group"]
+
+    assert slice_connection_groups[0]["id"] == "line1"
+    assert slice_connection_groups[1]["id"] == "line2"
+    assert len(slice_connection_groups) == 2
+
+
+def test_create_match_criteria(monkeypatch):
+    global slice_1
+
+    monkeypatch.setattr(context_client, "SelectSlice", select_slice)
+
+    slice_1 = IETFSliceHandler.create_match_criteria(
+        post_match_criteria_request, "slice1", "1", context_client
+    )
+    candidate_ietf_data = json.loads(
+        get_custom_config_rule(
+            slice_1.slice_config, CANDIDATE_RESOURCE_KEY
+        ).custom.resource_value
+    )
+    slice_services = candidate_ietf_data["network-slice-services"]["slice-service"]
+    slice_service = slice_services[0]
+    slice_sdps = slice_service["sdps"]["sdp"]
+    sdp1_match_criteria = slice_sdps[0]["service-match-criteria"]["match-criterion"]
+
+    slice_1 = IETFSliceHandler.copy_candidate_ietf_slice_data_to_running("slice1", context_client)
+    assert len(sdp1_match_criteria) == 2
+    assert sdp1_match_criteria[0]["target-connection-group-id"] == "line1"
+    assert sdp1_match_criteria[1]["target-connection-group-id"] == "line2"
+    assert slice_1.slice_endpoint_ids[0].device_id.device_uuid.uuid == "172.16.204.220"
+    assert slice_1.slice_endpoint_ids[1].device_id.device_uuid.uuid == "172.16.61.11"
+
+
+def test_delete_sdp(monkeypatch):
+    global slice_1
+
+    monkeypatch.setattr(context_client, "SelectSlice", select_slice)
+
+    slice_1 = IETFSliceHandler.delete_sdp("slice1", "3", context_client)
+    candidate_ietf_data = json.loads(
+        get_custom_config_rule(
+            slice_1.slice_config, CANDIDATE_RESOURCE_KEY
+        ).custom.resource_value
+    )
+    slice_services = candidate_ietf_data["network-slice-services"]["slice-service"]
+    slice_service = slice_services[0]
+    slice_sdps = slice_service["sdps"]["sdp"]
+    assert len(slice_sdps) == 2
+    assert "3" not in (sdp["id"] for sdp in slice_sdps)
+
+
+def test_delete_connection_group(monkeypatch):
+    global slice_1
+
+    monkeypatch.setattr(context_client, "SelectSlice", select_slice)
+    running_ietf_data = json.loads(
+        get_custom_config_rule(
+            slice_1.slice_config, RUNNING_RESOURCE_KEY
+        ).custom.resource_value
+    )
+    slice_1 = IETFSliceHandler.delete_connection_group(
+        "slice1", "line2", context_client
+    )
+    
+    candidate_ietf_data = json.loads(
+        get_custom_config_rule(
+            slice_1.slice_config, CANDIDATE_RESOURCE_KEY
+        ).custom.resource_value
+    )
+    slice_services = candidate_ietf_data["network-slice-services"]["slice-service"]
+    slice_service = slice_services[0]
+    slice_connection_groups = slice_service["connection-groups"]["connection-group"]
+    assert len(slice_connection_groups) == 1
+    assert slice_connection_groups[0]["id"] == "line1"
+
+
+def test_delete_match_criteria(monkeypatch):
+    global slice_1
+
+    monkeypatch.setattr(context_client, "SelectSlice", select_slice)
+
+    slice_1 = IETFSliceHandler.delete_match_criteria("slice1", "1", 2, context_client)
+    candidate_ietf_data = json.loads(
+        get_custom_config_rule(
+            slice_1.slice_config, CANDIDATE_RESOURCE_KEY
+        ).custom.resource_value
+    )
+    slice_services = candidate_ietf_data["network-slice-services"]["slice-service"]
+    slice_service = slice_services[0]
+    slice_sdps = slice_service["sdps"]["sdp"]
+    sdp1_match_criteria = slice_sdps[0]["service-match-criteria"]["match-criterion"]
+    assert len(sdp1_match_criteria) == 1
+    assert sdp1_match_criteria[0]["target-connection-group-id"] == "line1"
diff --git a/src/pathcomp/frontend/service/algorithms/tools/ComposeConfigRules.py b/src/pathcomp/frontend/service/algorithms/tools/ComposeConfigRules.py
index f0775371d0f3fea01411ce4049226377feebc27e..9eac4d353ef48f6e75b478d137e6e9bb9c3e1c03 100644
--- a/src/pathcomp/frontend/service/algorithms/tools/ComposeConfigRules.py
+++ b/src/pathcomp/frontend/service/algorithms/tools/ComposeConfigRules.py
@@ -22,6 +22,8 @@ LOGGER = logging.getLogger(__name__)
 
 SETTINGS_RULE_NAME = '/settings'
 STATIC_ROUTING_RULE_NAME = '/static_routing'
+RUNNING_RESOURCE_KEY = "running_ietf_slice"
+CANDIDATE_RESOURCE_KEY = "candidate_ietf_slice"
 
 RE_UUID = re.compile(r'([0-9a-fA-F]{8})\-([0-9a-fA-F]{4})\-([0-9a-fA-F]{4})\-([0-9a-fA-F]{4})\-([0-9a-fA-F]{12})')
 
@@ -93,6 +95,8 @@ def compose_l3nm_config_rules(main_service_config_rules : List, subservice_confi
     CONFIG_RULES = [
         (SETTINGS_RULE_NAME, L3NM_SETTINGS_FIELD_DEFAULTS),
         (STATIC_ROUTING_RULE_NAME, {}),
+        (RUNNING_RESOURCE_KEY, {}),
+        (CANDIDATE_RESOURCE_KEY, {}),
     ]
     for rule_name, defaults in CONFIG_RULES:
         compose_config_rules(main_service_config_rules, subservice_config_rules, rule_name, defaults)
diff --git a/src/pathcomp/frontend/service/algorithms/tools/ResourceGroups.py b/src/pathcomp/frontend/service/algorithms/tools/ResourceGroups.py
index b08830332f7fc6f526a19516b120e94a1a98b232..db0c552487363e4bb283832c7e40a4e7623e994c 100644
--- a/src/pathcomp/frontend/service/algorithms/tools/ResourceGroups.py
+++ b/src/pathcomp/frontend/service/algorithms/tools/ResourceGroups.py
@@ -28,6 +28,9 @@ DEVICE_TYPE_TO_DEEPNESS = {
     DeviceTypeEnum.TERAFLOWSDN_CONTROLLER.value          : 80,
     DeviceTypeEnum.EMULATED_IP_SDN_CONTROLLER.value      : 80,
     DeviceTypeEnum.IP_SDN_CONTROLLER.value               : 80,
+    DeviceTypeEnum.IETF_SLICE.value                      : 80,
+    DeviceTypeEnum.NCE.value                             : 80,
+
 
     DeviceTypeEnum.EMULATED_PACKET_ROUTER.value          : 70,
     DeviceTypeEnum.PACKET_ROUTER.value                   : 70,
diff --git a/src/pathcomp/frontend/service/algorithms/tools/ServiceTypes.py b/src/pathcomp/frontend/service/algorithms/tools/ServiceTypes.py
index 8230092c2decc0b2c988f63a2677f879f7ec944f..ae567d9d65e4d971930fecb0971672f5bdb1ab73 100644
--- a/src/pathcomp/frontend/service/algorithms/tools/ServiceTypes.py
+++ b/src/pathcomp/frontend/service/algorithms/tools/ServiceTypes.py
@@ -22,6 +22,7 @@ NETWORK_DEVICE_TYPES = {
 
 PACKET_DEVICE_TYPES = {
     DeviceTypeEnum.TERAFLOWSDN_CONTROLLER,
+    DeviceTypeEnum.IETF_SLICE, DeviceTypeEnum.NCE,
     DeviceTypeEnum.IP_SDN_CONTROLLER, DeviceTypeEnum.EMULATED_IP_SDN_CONTROLLER,
     DeviceTypeEnum.PACKET_ROUTER, DeviceTypeEnum.EMULATED_PACKET_ROUTER,
     DeviceTypeEnum.PACKET_SWITCH, DeviceTypeEnum.EMULATED_PACKET_SWITCH,
diff --git a/src/service/requirements.in b/src/service/requirements.in
index 3f8d2a35453691420a9469dfffd0a0d2648c6397..d0dd6dcfe13610fc315a50437fb5f3e094b4ee5e 100644
--- a/src/service/requirements.in
+++ b/src/service/requirements.in
@@ -13,6 +13,7 @@
 # limitations under the License.
 
 
+deepdiff==6.7.*
 anytree==2.8.0
 geopy==2.3.0
 netaddr==0.9.0
diff --git a/src/service/service/service_handler_api/FilterFields.py b/src/service/service/service_handler_api/FilterFields.py
index 78f084605bcd759825975cb7f11abc659506755b..e47fd635f0c02667a052ebb9cff0569496c5fbec 100644
--- a/src/service/service/service_handler_api/FilterFields.py
+++ b/src/service/service/service_handler_api/FilterFields.py
@@ -42,8 +42,12 @@ DEVICE_DRIVER_VALUES = {
     DeviceDriverEnum.DEVICEDRIVER_GNMI_OPENCONFIG,
     DeviceDriverEnum.DEVICEDRIVER_OPTICAL_TFS,
     DeviceDriverEnum.DEVICEDRIVER_IETF_ACTN,
+    DeviceDriverEnum.DEVICEDRIVER_NCE,
+    DeviceDriverEnum.DEVICEDRIVER_IETF_SLICE,
+    DeviceDriverEnum.DEVICEDRIVER_IETF_L3VPN,
     DeviceDriverEnum.DEVICEDRIVER_OC,
     DeviceDriverEnum.DEVICEDRIVER_QKD,
+    DeviceDriverEnum.DEVICEDRIVER_IETF_L3VPN,
 }
 
 # Map allowed filter fields to allowed values per Filter field. If no restriction (free text) None is specified
diff --git a/src/service/service/service_handlers/__init__.py b/src/service/service/service_handlers/__init__.py
index f93cf011fe02139ae350b91eab52eb71ded0574d..85545d238f2b93bd77b1beb1fce2d46b01b06800 100644
--- a/src/service/service/service_handlers/__init__.py
+++ b/src/service/service/service_handlers/__init__.py
@@ -16,11 +16,14 @@ from common.proto.context_pb2 import DeviceDriverEnum, ServiceTypeEnum
 from ..service_handler_api.FilterFields import FilterFieldEnum
 from .l2nm_emulated.L2NMEmulatedServiceHandler import L2NMEmulatedServiceHandler
 from .l2nm_ietfl2vpn.L2NM_IETFL2VPN_ServiceHandler import L2NM_IETFL2VPN_ServiceHandler
+from .l3nm_ietfl3vpn.L3NM_IETFL3VPN_ServiceHandler import L3NM_IETFL3VPN_ServiceHandler
 from .l2nm_openconfig.L2NMOpenConfigServiceHandler import L2NMOpenConfigServiceHandler
 from .l3nm_emulated.L3NMEmulatedServiceHandler import L3NMEmulatedServiceHandler
 from .l3nm_openconfig.L3NMOpenConfigServiceHandler import L3NMOpenConfigServiceHandler
 from .l3nm_gnmi_openconfig.L3NMGnmiOpenConfigServiceHandler import L3NMGnmiOpenConfigServiceHandler
 from .l3nm_ietf_actn.L3NMIetfActnServiceHandler import L3NMIetfActnServiceHandler
+from .l3nm_nce.L3NMNCEServiceHandler import L3NMNCEServiceHandler
+from .l3slice_ietfslice.L3SliceIETFSliceServiceHandler import L3NMSliceIETFSliceServiceHandler
 from .microwave.MicrowaveServiceHandler import MicrowaveServiceHandler
 from .p4.p4_service_handler import P4ServiceHandler
 from .tapi_tapi.TapiServiceHandler import TapiServiceHandler
@@ -66,6 +69,24 @@ SERVICE_HANDLERS = [
             FilterFieldEnum.DEVICE_DRIVER : DeviceDriverEnum.DEVICEDRIVER_IETF_ACTN,
         }
     ]),
+    (L3NM_IETFL3VPN_ServiceHandler, [
+        {
+            FilterFieldEnum.SERVICE_TYPE  : ServiceTypeEnum.SERVICETYPE_L3NM,
+            FilterFieldEnum.DEVICE_DRIVER : DeviceDriverEnum.DEVICEDRIVER_IETF_L3VPN,
+        }
+    ]),
+    (L3NMNCEServiceHandler, [
+        {
+            FilterFieldEnum.SERVICE_TYPE  : ServiceTypeEnum.SERVICETYPE_L3NM,
+            FilterFieldEnum.DEVICE_DRIVER : DeviceDriverEnum.DEVICEDRIVER_NCE,
+        }
+    ]),
+    (L3NMSliceIETFSliceServiceHandler, [
+        {
+            FilterFieldEnum.SERVICE_TYPE  : ServiceTypeEnum.SERVICETYPE_L3NM,
+            FilterFieldEnum.DEVICE_DRIVER : DeviceDriverEnum.DEVICEDRIVER_IETF_SLICE,
+        }
+    ]),
     (TapiServiceHandler, [
         {
             FilterFieldEnum.SERVICE_TYPE  : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
diff --git a/src/service/service/service_handlers/l3nm_emulated/ConfigRules.py b/src/service/service/service_handlers/l3nm_emulated/ConfigRules.py
index 1d6764619e81864e9b048319a087f1a10f17d601..f1b02eab564c6a2eb38f25e4567a2a04ca0156ed 100644
--- a/src/service/service/service_handlers/l3nm_emulated/ConfigRules.py
+++ b/src/service/service/service_handlers/l3nm_emulated/ConfigRules.py
@@ -43,7 +43,7 @@ def setup_config_rules(
     vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
     address_ip          = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
     address_prefix      = json_endpoint_settings.get('address_prefix',      24       )  # 30
-    if_subif_name       = '{:s}.{:d}'.format(endpoint_name, vlan_id)
+    if_subif_name       = '{:s}.{:s}'.format(endpoint_name, str(vlan_id))
 
     json_config_rules = [
         json_config_rule_set(
@@ -57,7 +57,7 @@ def setup_config_rules(
                 'name': endpoint_name, 'description': network_interface_desc, 'mtu': mtu,
         }),
         json_config_rule_set(
-            '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_name, sub_interface_index), {
+            '/interface[{:s}]/subinterface[{:s}]'.format(endpoint_name, str(sub_interface_index)), {
                 'name': endpoint_name, 'index': sub_interface_index,
                 'description': network_subinterface_desc, 'vlan_id': vlan_id,
                 'address_ip': address_ip, 'address_prefix': address_prefix,
@@ -163,7 +163,7 @@ def teardown_config_rules(
     #address_ip          = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
     #address_prefix      = json_endpoint_settings.get('address_prefix',      24       )  # 30
 
-    if_subif_name             = '{:s}.{:d}'.format(endpoint_name, vlan_id)
+    if_subif_name             = '{:s}.{:s}'.format(endpoint_name, str(vlan_id))
     service_short_uuid        = service_uuid.split('-')[-1]
     network_instance_name     = '{:s}-NetInst'.format(service_short_uuid)
     #network_interface_desc    = '{:s}-NetIf'.format(service_uuid)
@@ -175,7 +175,7 @@ def teardown_config_rules(
                 'name': network_instance_name, 'id': if_subif_name,
         }),
         json_config_rule_delete(
-            '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_name, sub_interface_index), {
+            '/interface[{:s}]/subinterface[{:s}]'.format(endpoint_name, str(sub_interface_index)), {
                 'name': endpoint_name, 'index': sub_interface_index,
         }),
         json_config_rule_delete(
diff --git a/src/service/service/service_handlers/l3nm_ietfl3vpn/ConfigRules.py b/src/service/service/service_handlers/l3nm_ietfl3vpn/ConfigRules.py
new file mode 100644
index 0000000000000000000000000000000000000000..c5638fc104c253be20ef1bbeb6c69a4392095ad2
--- /dev/null
+++ b/src/service/service/service_handlers/l3nm_ietfl3vpn/ConfigRules.py
@@ -0,0 +1,316 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from typing import Dict, List, Tuple, TypedDict
+
+from common.proto.context_pb2 import Link
+from common.tools.object_factory.ConfigRule import (
+    json_config_rule_delete,
+    json_config_rule_set,
+)
+from context.client.ContextClient import ContextClient
+
+
+class LANPrefixesDict(TypedDict):
+    lan: str
+    lan_tag: str
+
+
+SITE_NETWORK_ACCESS_TYPE = "ietf-l3vpn-svc:multipoint"
+
+
+def create_site_dict(
+    site_id: str,
+    site_location: str,
+    device_uuid: str,
+    endpoint_uuid: str,
+    service_uuid: str,
+    role: str,
+    management_type: str,
+    ce_address: str,
+    pe_address: str,
+    ce_pe_network_prefix: int,
+    mtu: int,
+    input_bw: int,
+    output_bw: int,
+    qos_profile_id: str,
+    qos_profile_direction: str,
+    qos_profile_latency: int,
+    qos_profile_bw_guarantee: int,
+    lan_prefixes: List[LANPrefixesDict],
+) -> Dict:
+    """
+    Helper function that creates a dictionary representing a single 'site'
+    entry (including management, locations, devices, routing-protocols, and
+    site-network-accesses).
+    """
+    site_lan_prefixes = [
+        {
+            "lan": lp["lan"],
+            "lan-tag": lp["lan_tag"],
+            "next-hop": ce_address,
+        }
+        for lp in lan_prefixes
+    ]
+
+    return {
+        "site-id": site_id,
+        "management": {"type": management_type},
+        "locations": {"location": [{"location-id": site_location}]},
+        "devices": {
+            "device": [
+                {
+                    "device-id": device_uuid,
+                    "location": site_location,
+                }
+            ]
+        },
+        "routing-protocols": {
+            "routing-protocol": [
+                {
+                    "type": "ietf-l3vpn-svc:static",
+                    "static": {
+                        "cascaded-lan-prefixes": {
+                            "ipv4-lan-prefixes": site_lan_prefixes
+                        }
+                    },
+                }
+            ]
+        },
+        "site-network-accesses": {
+            "site-network-access": [
+                {
+                    "site-network-access-id": endpoint_uuid,
+                    "site-network-access-type": SITE_NETWORK_ACCESS_TYPE,
+                    "device-reference": device_uuid,
+                    "vpn-attachment": {
+                        "vpn-id": service_uuid,
+                        "site-role": role,
+                    },
+                    "ip-connection": {
+                        "ipv4": {
+                            "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                            "addresses": {
+                                "provider-address": pe_address,
+                                "customer-address": ce_address,
+                                "prefix-length": ce_pe_network_prefix,
+                            },
+                        }
+                    },
+                    "service": {
+                        "svc-mtu": mtu,
+                        "svc-input-bandwidth": input_bw,
+                        "svc-output-bandwidth": output_bw,
+                        "qos": {
+                            "qos-profile": {
+                                "classes": {
+                                    "class": [
+                                        {
+                                            "class-id": qos_profile_id,
+                                            "direction": qos_profile_direction,
+                                            "latency": {
+                                                "latency-boundary": qos_profile_latency
+                                            },
+                                            "bandwidth": {
+                                                "guaranteed-bw-percent": qos_profile_bw_guarantee
+                                            },
+                                        }
+                                    ]
+                                }
+                            }
+                        },
+                    },
+                }
+            ]
+        },
+    }
+
+
+def setup_config_rules(
+    service_uuid: str, json_settings: Dict, operation_type: str
+) -> List[Dict]:
+    # --- Extract common or required fields for the source site ---
+    src_device_uuid: str = json_settings["src_device_name"]
+    src_endpoint_uuid: str = json_settings["src_endpoint_name"]
+    src_site_location: str = json_settings["src_site_location"]
+    src_ipv4_lan_prefixes: list[LANPrefixesDict] = json_settings.get(
+        "src_ipv4_lan_prefixes"
+    )
+    src_site_id: str = json_settings.get("src_site_id", f"site_{src_site_location}")
+    src_management_type: str = json_settings.get(
+        "src_management_type", "ietf-l3vpn-svc:provider-managed"
+    )
+    if src_management_type != "ietf-l3vpn-svc:provider-managed":
+        raise Exception("management type %s not supported", src_management_type)
+
+    src_role: str = "ietf-l3vpn-svc:hub-role"
+    src_ce_address: str = json_settings["src_ce_address"]
+    src_pe_address: str = json_settings["src_pe_address"]
+    src_ce_pe_network_prefix: int = json_settings["src_ce_pe_network_prefix"]
+    src_mtu: int = json_settings["src_mtu"]
+    src_input_bw: int = json_settings["src_input_bw"]
+    src_output_bw: int = json_settings["src_output_bw"]
+    src_qos_profile_id = "qos-realtime"
+    src_qos_profile_direction = "ietf-l3vpn-svc:both"
+    src_qos_profile_latency: int = json_settings["src_qos_profile_latency"]
+    src_qos_profile_bw_guarantee: int = json_settings.get(
+        "src_qos_profile_bw_guarantee", 100
+    )
+
+    # --- Extract common or required fields for the destination site ---
+    dst_device_uuid = json_settings["dst_device_name"]
+    dst_endpoint_uuid = json_settings["dst_endpoint_name"]
+    dst_site_location: str = json_settings["dst_site_location"]
+    dst_ipv4_lan_prefixes: list[LANPrefixesDict] = json_settings[
+        "dst_ipv4_lan_prefixes"
+    ]
+    dst_site_id: str = json_settings.get("dst_site_id", f"site_{dst_site_location}")
+    dst_management_type: str = json_settings.get(
+        "dst_management_type", "ietf-l3vpn-svc:provider-managed"
+    )
+    if dst_management_type != "ietf-l3vpn-svc:provider-managed":
+        raise Exception("management type %s not supported", dst_management_type)
+
+    dst_role: str = "ietf-l3vpn-svc:spoke-role"
+    dst_ce_address: str = json_settings["dst_ce_address"]
+    dst_pe_address: str = json_settings["dst_pe_address"]
+    dst_ce_pe_network_prefix: int = json_settings["dst_ce_pe_network_prefix"]
+    dst_mtu: int = json_settings["dst_mtu"]
+    dst_input_bw: int = json_settings["dst_input_bw"]
+    dst_output_bw: int = json_settings["dst_output_bw"]
+    dst_qos_profile_id = "qos-realtime"
+    dst_qos_profile_direction = "ietf-l3vpn-svc:both"
+    dst_qos_profile_latency: int = json_settings["dst_qos_profile_latency"]
+    dst_qos_profile_bw_guarantee: int = json_settings.get(
+        "dst_qos_profile_bw_guarantee", 100
+    )
+
+    # --- Build site dictionaries using the helper function ---
+    src_site_dict = create_site_dict(
+        site_id=src_site_id,
+        site_location=src_site_location,
+        device_uuid=src_device_uuid,
+        endpoint_uuid=src_endpoint_uuid,
+        service_uuid=service_uuid,
+        role=src_role,
+        management_type=src_management_type,
+        ce_address=src_ce_address,
+        pe_address=src_pe_address,
+        ce_pe_network_prefix=src_ce_pe_network_prefix,
+        mtu=src_mtu,
+        input_bw=src_input_bw,
+        output_bw=src_output_bw,
+        qos_profile_id=src_qos_profile_id,
+        qos_profile_direction=src_qos_profile_direction,
+        qos_profile_latency=src_qos_profile_latency,
+        qos_profile_bw_guarantee=src_qos_profile_bw_guarantee,
+        lan_prefixes=src_ipv4_lan_prefixes,
+    )
+
+    dst_site_dict = create_site_dict(
+        site_id=dst_site_id,
+        site_location=dst_site_location,
+        device_uuid=dst_device_uuid,
+        endpoint_uuid=dst_endpoint_uuid,
+        service_uuid=service_uuid,
+        role=dst_role,
+        management_type=dst_management_type,
+        ce_address=dst_ce_address,
+        pe_address=dst_pe_address,
+        ce_pe_network_prefix=dst_ce_pe_network_prefix,
+        mtu=dst_mtu,
+        input_bw=dst_input_bw,
+        output_bw=dst_output_bw,
+        qos_profile_id=dst_qos_profile_id,
+        qos_profile_direction=dst_qos_profile_direction,
+        qos_profile_latency=dst_qos_profile_latency,
+        qos_profile_bw_guarantee=dst_qos_profile_bw_guarantee,
+        lan_prefixes=dst_ipv4_lan_prefixes,
+    )
+
+    # --- Combine both sites into one structure ---
+    sites = {
+        "site": [
+            src_site_dict,
+            dst_site_dict,
+        ]
+    }
+
+    l3_vpn_data_model = {
+        "ietf-l3vpn-svc:l3vpn-svc": {
+            "vpn-services": {"vpn-service": [{"vpn-id": service_uuid}]},
+            "sites": sites,
+        }
+    }
+
+    json_config_rules = [
+        json_config_rule_set(
+            "/service[{:s}]/IETFL3VPN".format(service_uuid),
+            l3_vpn_data_model,
+        ),
+        json_config_rule_set(
+            "/service[{:s}]/IETFL3VPN/operation".format(service_uuid),
+            {"type": operation_type},
+        ),
+    ]
+
+    return json_config_rules
+
+
+def teardown_config_rules(service_uuid: str) -> List[Dict]:
+    json_config_rules = [
+        json_config_rule_delete(
+            "/service[{:s}]/IETFL3VPN".format(service_uuid),
+            {"id": service_uuid},
+        ),
+        json_config_rule_delete(
+            "/service[{:s}]/IETFL3VPN/operation".format(service_uuid),
+            {},
+        ),
+    ]
+    return json_config_rules
+
+
+def get_link_ep_device_names(
+    link: Link, context_client: ContextClient
+) -> Tuple[str, str, str, str]:
+    ep_ids = link.link_endpoint_ids
+    ep_device_id_1 = ep_ids[0].device_id
+    ep_uuid_1 = ep_ids[0].endpoint_uuid.uuid
+    device_obj_1 = context_client.GetDevice(ep_device_id_1)
+    for d_ep in device_obj_1.device_endpoints:
+        if d_ep.endpoint_id.endpoint_uuid.uuid == ep_uuid_1:
+            ep_name_1 = d_ep.name
+            break
+    else:
+        raise Exception("endpoint not found")
+    device_obj_name_1 = device_obj_1.name
+    ep_device_id_2 = ep_ids[1].device_id
+    ep_uuid_2 = ep_ids[1].endpoint_uuid.uuid
+    device_obj_2 = context_client.GetDevice(ep_device_id_2)
+    for d_ep in device_obj_2.device_endpoints:
+        if d_ep.endpoint_id.endpoint_uuid.uuid == ep_uuid_2:
+            ep_name_2 = d_ep.name
+            break
+    else:
+        raise Exception("endpoint not found")
+    device_obj_name_2 = device_obj_2.name
+    return (
+        device_obj_name_1,
+        ep_name_1,
+        device_obj_1,
+        device_obj_name_2,
+        ep_name_2,
+        device_obj_2,
+    )
diff --git a/src/service/service/service_handlers/l3nm_ietfl3vpn/L3NM_IETFL3VPN_ServiceHandler.py b/src/service/service/service_handlers/l3nm_ietfl3vpn/L3NM_IETFL3VPN_ServiceHandler.py
new file mode 100644
index 0000000000000000000000000000000000000000..aa650c8096b9443b85114166ad1d0bc5b6f2fc55
--- /dev/null
+++ b/src/service/service/service_handlers/l3nm_ietfl3vpn/L3NM_IETFL3VPN_ServiceHandler.py
@@ -0,0 +1,546 @@
+# Copyright 2022-2025 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+import logging
+from typing import Any, List, Optional, Tuple, TypedDict, Union
+
+from deepdiff import DeepDiff
+
+from common.DeviceTypes import DeviceTypeEnum
+from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method
+from common.proto.context_pb2 import (
+    ConfigRule,
+    Device,
+    DeviceId,
+    Service,
+    ServiceConfig,
+)
+from common.tools.object_factory.Device import json_device_id
+from common.type_checkers.Checkers import chk_type
+from service.service.service_handler_api._ServiceHandler import _ServiceHandler
+from service.service.service_handler_api.SettingsHandler import SettingsHandler
+from service.service.service_handler_api.Tools import (
+    get_device_endpoint_uuids,
+    get_endpoint_matching,
+)
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
+
+from .ConfigRules import setup_config_rules, teardown_config_rules
+
+RUNNING_RESOURCE_KEY = "running_ietf_slice"
+CANDIDATE_RESOURCE_KEY = "candidate_ietf_slice"
+MTU = 1500
+
+LOGGER = logging.getLogger(__name__)
+
+METRICS_POOL = MetricsPool("Service", "Handler", labels={"handler": "l3nm_ietf_l3vpn"})
+
+
+class LANPrefixesDict(TypedDict):
+    lan: str
+    lan_tag: str
+
+
+class Ipv4Info(TypedDict):
+    src_lan: str
+    dst_lan: str
+    src_port: str
+    dst_port: str
+    vlan: str
+
+
+class QoSInfo(TypedDict):
+    src_qos_profile_latency: int
+    src_input_bw: int
+    src_output_bw: int
+    dst_qos_profile_latency: int
+    dst_input_bw: int
+    dst_output_bw: int
+
+
+def get_custom_config_rule(
+    service_config: ServiceConfig, resource_key: str
+) -> Optional[ConfigRule]:
+    """
+    Return the custom ConfigRule from the ServiceConfig matching the given resource_key,
+    or None if not found.
+    """
+    for cr in service_config.config_rules:
+        if (
+            cr.WhichOneof("config_rule") == "custom"
+            and cr.custom.resource_key == resource_key
+        ):
+            return cr
+    return None
+
+
+def load_json_rule_data(service_config: ServiceConfig) -> Tuple[dict, dict]:
+    """
+    Loads the running/candidate JSON data from the service_config for IETF slice data.
+    Raises an exception if either is missing.
+    """
+    running_cr = get_custom_config_rule(service_config, RUNNING_RESOURCE_KEY)
+    candidate_cr = get_custom_config_rule(service_config, CANDIDATE_RESOURCE_KEY)
+
+    if not running_cr or not candidate_cr:
+        raise ValueError("Missing running/candidate IETF slice config rules.")
+
+    running_data = json.loads(running_cr.custom.resource_value)
+    candidate_data = json.loads(candidate_cr.custom.resource_value)
+    return running_data, candidate_data
+
+
+def extract_match_criterion_ipv4_info(match_criterion: dict) -> Ipv4Info:
+    """
+    Extracts IPv4 match criteria data (src/dst IP, ports, VLAN) from a match_criterion dict.
+    """
+    src_lan = dst_lan = src_port = dst_port = vlan = ""
+    for type_value in match_criterion["match-type"]:
+        value = type_value["value"][0]
+        if type_value["type"] == "ietf-network-slice-service:source-ip-prefix":
+            src_lan = value
+        elif type_value["type"] == "ietf-network-slice-service:destination-ip-prefix":
+            dst_lan = value
+        elif type_value["type"] == "ietf-network-slice-service:source-tcp-port":
+            src_port = value
+        elif type_value["type"] == "ietf-network-slice-service:destination-tcp-port":
+            dst_port = value
+        elif type_value["type"] == "ietf-network-slice-service:vlan":
+            vlan = value
+
+    return Ipv4Info(
+        src_lan=src_lan,
+        dst_lan=dst_lan,
+        src_port=src_port,
+        dst_port=dst_port,
+        vlan=vlan,
+    )
+
+
+def extract_qos_info_from_connection_group(
+    src_sdp_id: str, dst_sdp_id: str, connectivity_constructs: list
+) -> QoSInfo:
+    """
+    Given a pair of SDP ids and a list of connectivity constructs, extract QoS info
+    such as latency and bandwidth (for both directions).
+    """
+
+    def _extract_qos_fields(cc: dict) -> Tuple[int, int]:
+        max_delay = 0
+        bandwidth = 0
+        metric_bounds = cc["service-slo-sle-policy"]["slo-policy"]["metric-bound"]
+        for metric_bound in metric_bounds:
+            if (
+                metric_bound["metric-type"]
+                == "ietf-network-slice-service:one-way-delay-maximum"
+                and metric_bound["metric-unit"] == "milliseconds"
+            ):
+                max_delay = int(metric_bound["bound"])
+            elif (
+                metric_bound["metric-type"]
+                == "ietf-network-slice-service:one-way-bandwidth"
+                and metric_bound["metric-unit"] == "Mbps"
+            ):
+                # Convert from Mbps to bps
+                bandwidth = int(metric_bound["bound"]) * 1000000
+        return max_delay, bandwidth
+
+    src_cc = next(
+        cc
+        for cc in connectivity_constructs
+        if cc["p2p-sender-sdp"] == src_sdp_id and cc["p2p-receiver-sdp"] == dst_sdp_id
+    )
+    dst_cc = next(
+        cc
+        for cc in connectivity_constructs
+        if cc["p2p-sender-sdp"] == dst_sdp_id and cc["p2p-receiver-sdp"] == src_sdp_id
+    )
+    src_max_delay, src_bandwidth = _extract_qos_fields(src_cc)
+    dst_max_delay, dst_bandwidth = _extract_qos_fields(dst_cc)
+
+    return QoSInfo(
+        src_qos_profile_latency=src_max_delay,
+        src_input_bw=src_bandwidth,
+        src_output_bw=dst_bandwidth,
+        dst_qos_profile_latency=dst_max_delay,
+        dst_input_bw=dst_bandwidth,
+        dst_output_bw=src_bandwidth,
+    )
+
+
+def get_endpoint_settings(device_obj: Device, endpoint_name: str) -> dict:
+    """
+    Helper to retrieve endpoint settings from a device's config rules given an endpoint name.
+    Raises an exception if not found.
+    """
+    for rule in device_obj.device_config.config_rules:
+        if (
+            rule.WhichOneof("config_rule") == "custom"
+            and rule.custom.resource_key == f"/endpoints/endpoint[{endpoint_name}]"
+        ):
+            return json.loads(rule.custom.resource_value)
+    raise ValueError(f"Endpoint settings not found for endpoint {endpoint_name}")
+
+
+class L3NM_IETFL3VPN_ServiceHandler(_ServiceHandler):
+    def __init__(  # pylint: disable=super-init-not-called
+        self, service: Service, task_executor: TaskExecutor, **settings
+    ) -> None:
+        self.__service = service
+        self.__task_executor = task_executor
+        self.__settings_handler = SettingsHandler(service.service_config, **settings)
+
+    def __find_IP_transport_edge_endpoints(
+        self, endpoints
+    ) -> Tuple[str, str, str, str, Device]:
+        """
+        Searches for two endpoints whose device controllers are IP_SDN_CONTROLLER.
+        Returns (src_device_uuid, src_endpoint_uuid, dst_device_uuid, dst_endpoint_uuid, controller_device).
+        Raises an exception if not found or if the two IP devices differ.
+        """
+
+        # Find the first IP transport edge endpoint from the head of endpoints
+        for ep in endpoints:
+            device_uuid, endpoint_uuid = get_device_endpoint_uuids(ep)
+            device_obj = self.__task_executor.get_device(
+                DeviceId(**json_device_id(device_uuid))
+            )
+            device_controller = self.__task_executor.get_device_controller(device_obj)
+            if device_controller.device_type == DeviceTypeEnum.IP_SDN_CONTROLLER.value:
+                src_device_uuid, src_endpoint_uuid = device_uuid, endpoint_uuid
+                src_device_controller = device_controller
+                break
+        else:
+            raise Exception("No IP transport edge endpoints found")
+
+        # Find the second IP transport edge endpoint from the tail of endpoints
+        for ep in reversed(endpoints):
+            device_uuid, endpoint_uuid = get_device_endpoint_uuids(ep)
+            device_obj = self.__task_executor.get_device(
+                DeviceId(**json_device_id(device_uuid))
+            )
+            device_controller = self.__task_executor.get_device_controller(device_obj)
+            if device_controller.device_type == DeviceTypeEnum.IP_SDN_CONTROLLER.value:
+                dst_device_uuid, dst_endpoint_uuid = device_uuid, endpoint_uuid
+                dst_device_controller = device_controller
+                break
+        else:
+            raise Exception("No IP transport edge endpoints found")
+
+        if src_device_controller != dst_device_controller:
+            raise Exception("Different Src-Dst devices not supported by now")
+
+        return (
+            src_device_uuid,
+            src_endpoint_uuid,
+            dst_device_uuid,
+            dst_endpoint_uuid,
+            src_device_controller,
+        )
+
+    def __build_resource_value_dict(
+        self,
+        service_id: str,
+        src_device_obj: Device,
+        dst_device_obj: Device,
+        src_endpoint_name: str,
+        dst_endpoint_name: str,
+        qos_info: QoSInfo,
+        src_endpoint_settings: dict,
+        dst_endpoint_settings: dict,
+        src_match_criterion_ipv4_info: Ipv4Info,
+        dst_match_criterion_ipv4_info: Ipv4Info,
+    ) -> dict:
+        """
+        Builds the final resource-value dict to be used when calling setup_config_rules().
+        """
+        # Prepare data for source
+        src_device_name = src_device_obj.name
+        src_ce_ip = src_endpoint_settings["address_ip"]
+        src_ce_prefix = src_endpoint_settings["address_prefix"]
+        src_lan_prefixes = [
+            LANPrefixesDict(
+                lan=src_match_criterion_ipv4_info["dst_lan"],
+                lan_tag=src_match_criterion_ipv4_info["vlan"],
+            )
+        ]
+
+        # Prepare data for destination
+        dst_device_name = dst_device_obj.name
+        dst_ce_ip = dst_endpoint_settings["address_ip"]
+        dst_ce_prefix = dst_endpoint_settings["address_prefix"]
+        dst_lan_prefixes = [
+            LANPrefixesDict(
+                lan=dst_match_criterion_ipv4_info["dst_lan"],
+                lan_tag=dst_match_criterion_ipv4_info["vlan"],
+            )
+        ]
+
+        return {
+            "uuid": service_id,
+            "src_device_name": src_device_name,
+            "src_endpoint_name": src_endpoint_name,
+            "src_site_location": src_endpoint_settings["site_location"],
+            "src_ipv4_lan_prefixes": src_lan_prefixes,
+            "src_ce_address": src_ce_ip,
+            "src_pe_address": src_ce_ip,
+            "src_ce_pe_network_prefix": src_ce_prefix,
+            "src_mtu": MTU,
+            "src_qos_profile_latency": qos_info["src_qos_profile_latency"],
+            "src_input_bw": qos_info["src_input_bw"],
+            "src_output_bw": qos_info["src_output_bw"],
+            "dst_device_name": dst_device_name,
+            "dst_endpoint_name": dst_endpoint_name,
+            "dst_site_location": dst_endpoint_settings["site_location"],
+            "dst_ipv4_lan_prefixes": dst_lan_prefixes,
+            "dst_ce_address": dst_ce_ip,
+            "dst_pe_address": dst_ce_ip,
+            "dst_ce_pe_network_prefix": dst_ce_prefix,
+            "dst_mtu": MTU,
+            "dst_qos_profile_latency": qos_info["dst_qos_profile_latency"],
+            "dst_input_bw": qos_info["dst_input_bw"],
+            "dst_output_bw": qos_info["dst_output_bw"],
+        }
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetEndpoint(
+        self,
+        endpoints: List[Tuple[str, str, Optional[str]]],
+        connection_uuid: Optional[str] = None,
+    ) -> List[Union[bool, Exception]]:
+        chk_type("endpoints", endpoints, list)
+        if len(endpoints) < 2:
+            return []
+
+        results = []
+        service_config = self.__service.service_config
+
+        try:
+            # Identify IP transport edge endpoints
+            (
+                src_device_uuid,
+                src_endpoint_uuid,
+                dst_device_uuid,
+                dst_endpoint_uuid,
+                controller,
+            ) = self.__find_IP_transport_edge_endpoints(endpoints)
+
+            # Retrieve device objects
+            src_device_obj = self.__task_executor.get_device(
+                DeviceId(**json_device_id(src_device_uuid))
+            )
+            src_endpoint_obj = get_endpoint_matching(src_device_obj, src_endpoint_uuid)
+
+            dst_device_obj = self.__task_executor.get_device(
+                DeviceId(**json_device_id(dst_device_uuid))
+            )
+            dst_endpoint_obj = get_endpoint_matching(dst_device_obj, dst_endpoint_uuid)
+
+            # Obtain endpoint settings
+            src_endpoint_settings = get_endpoint_settings(
+                src_device_obj, src_endpoint_obj.name
+            )
+            dst_endpoint_settings = get_endpoint_settings(
+                dst_device_obj, dst_endpoint_obj.name
+            )
+
+            # Load running & candidate data, compute diff
+            running_data, candidate_data = load_json_rule_data(service_config)
+            running_candidate_diff = DeepDiff(running_data, candidate_data)
+
+            # Determine service_id and operation_type
+            slice_service = candidate_data["network-slice-services"]["slice-service"][0]
+            service_id = slice_service["id"]
+            if not running_candidate_diff:
+                operation_type = "create"
+            elif "values_changed" in running_candidate_diff:
+                operation_type = "update"
+
+            # Parse relevant connectivity data
+            sdps = slice_service["sdps"]["sdp"]
+            connection_group = slice_service["connection-groups"]["connection-group"][0]
+            connecitivity_constructs = connection_group["connectivity-construct"]
+
+            # The code below assumes a single connectivity construct or
+            # that the relevant one is the first in the list:
+            connecitivity_construct = connecitivity_constructs[0]
+            src_sdp_idx = connecitivity_construct["p2p-sender-sdp"]
+            dst_sdp_idx = connecitivity_construct["p2p-receiver-sdp"]
+
+            # QoS
+            qos_info = extract_qos_info_from_connection_group(
+                src_sdp_idx, dst_sdp_idx, connecitivity_constructs
+            )
+
+            # Retrieve match-criterion info
+            src_sdp = next(sdp for sdp in sdps if sdp["id"] == src_sdp_idx)
+            dst_sdp = next(sdp for sdp in sdps if sdp["id"] == dst_sdp_idx)
+
+            src_match_criterion = src_sdp["service-match-criteria"]["match-criterion"][
+                0
+            ]
+            dst_match_criterion = dst_sdp["service-match-criteria"]["match-criterion"][
+                0
+            ]
+            src_match_criterion_ipv4_info = extract_match_criterion_ipv4_info(
+                src_match_criterion
+            )
+            dst_match_criterion_ipv4_info = extract_match_criterion_ipv4_info(
+                dst_match_criterion
+            )
+
+            # Build resource dict & config rules
+            resource_value_dict = self.__build_resource_value_dict(
+                service_id=service_id,
+                src_device_obj=src_device_obj,
+                dst_device_obj=dst_device_obj,
+                src_endpoint_name=src_endpoint_obj.name,
+                dst_endpoint_name=dst_endpoint_obj.name,
+                qos_info=qos_info,
+                src_endpoint_settings=src_endpoint_settings,
+                dst_endpoint_settings=dst_endpoint_settings,
+                src_match_criterion_ipv4_info=src_match_criterion_ipv4_info,
+                dst_match_criterion_ipv4_info=dst_match_criterion_ipv4_info,
+            )
+            json_config_rules = setup_config_rules(
+                service_id, resource_value_dict, operation_type
+            )
+
+            # Configure device
+            del controller.device_config.config_rules[:]
+            for jcr in json_config_rules:
+                controller.device_config.config_rules.append(ConfigRule(**jcr))
+            self.__task_executor.configure_device(controller)
+        except Exception as e:  # pylint: disable=broad-except
+            LOGGER.exception(
+                "Unable to SetEndpoint for Service({:s})".format(str(service_id))
+            )
+            results.append(e)
+
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def DeleteEndpoint(
+        self,
+        endpoints: List[Tuple[str, str, Optional[str]]],
+        connection_uuid: Optional[str] = None,
+    ) -> List[Union[bool, Exception]]:
+        chk_type("endpoints", endpoints, list)
+        if len(endpoints) < 2:
+            return []
+        service_config = self.__service.service_config
+        ietf_slice_candidate_cr = get_custom_config_rule(
+            service_config, CANDIDATE_RESOURCE_KEY
+        )
+        candidate_resource_value_dict = json.loads(
+            ietf_slice_candidate_cr.custom.resource_value
+        )
+        service_id = candidate_resource_value_dict["network-slice-services"][
+            "slice-service"
+        ][0]["id"]
+        results = []
+        try:
+            src_device_uuid, _ = get_device_endpoint_uuids(endpoints[0])
+            src_device = self.__task_executor.get_device(
+                DeviceId(**json_device_id(src_device_uuid))
+            )
+            src_controller = self.__task_executor.get_device_controller(src_device)
+
+            dst_device_uuid, _ = get_device_endpoint_uuids(endpoints[1])
+            dst_device = self.__task_executor.get_device(
+                DeviceId(**json_device_id(dst_device_uuid))
+            )
+            dst_controller = self.__task_executor.get_device_controller(dst_device)
+            if (
+                src_controller.device_id.device_uuid.uuid
+                != dst_controller.device_id.device_uuid.uuid
+            ):
+                raise Exception("Different Src-Dst devices not supported by now")
+            controller = src_controller
+            json_config_rules = teardown_config_rules(service_id)
+            del controller.device_config.config_rules[:]
+            for jcr in json_config_rules:
+                controller.device_config.config_rules.append(ConfigRule(**jcr))
+            self.__task_executor.configure_device(controller)
+            results.append(True)
+        except Exception as e:  # pylint: disable=broad-except
+            LOGGER.exception(
+                "Unable to DeleteEndpoint for Service({:s})".format(str(service_id))
+            )
+            results.append(e)
+
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetConstraint(
+        self, constraints: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        chk_type("constraints", constraints, list)
+        if len(constraints) == 0:
+            return []
+
+        msg = "[SetConstraint] Method not implemented. Constraints({:s}) are being ignored."
+        LOGGER.warning(msg.format(str(constraints)))
+        return [True for _ in range(len(constraints))]
+
+    @metered_subclass_method(METRICS_POOL)
+    def DeleteConstraint(
+        self, constraints: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        chk_type("constraints", constraints, list)
+        if len(constraints) == 0:
+            return []
+
+        msg = "[DeleteConstraint] Method not implemented. Constraints({:s}) are being ignored."
+        LOGGER.warning(msg.format(str(constraints)))
+        return [True for _ in range(len(constraints))]
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetConfig(
+        self, resources: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        chk_type("resources", resources, list)
+        if len(resources) == 0:
+            return []
+
+        results = []
+        for resource in resources:
+            try:
+                resource_value = json.loads(resource[1])
+                self.__settings_handler.set(resource[0], resource_value)
+                results.append(True)
+            except Exception as e:  # pylint: disable=broad-except
+                LOGGER.exception("Unable to SetConfig({:s})".format(str(resource)))
+                results.append(e)
+
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def DeleteConfig(
+        self, resources: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        chk_type("resources", resources, list)
+        if len(resources) == 0:
+            return []
+
+        results = []
+        for resource in resources:
+            try:
+                self.__settings_handler.delete(resource[0])
+            except Exception as e:  # pylint: disable=broad-except
+                LOGGER.exception("Unable to DeleteConfig({:s})".format(str(resource)))
+                results.append(e)
+
+        return results
diff --git a/src/service/service/service_handlers/l3nm_ietfl3vpn/__init__.py b/src/service/service/service_handlers/l3nm_ietfl3vpn/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..906dd19f3c948b03263251f60addb49e2fb522dc
--- /dev/null
+++ b/src/service/service/service_handlers/l3nm_ietfl3vpn/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2025 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/service/service/service_handlers/l3nm_nce/ConfigRules.py b/src/service/service/service_handlers/l3nm_nce/ConfigRules.py
new file mode 100644
index 0000000000000000000000000000000000000000..0544d897606afe950725349bfeb68c365189aa21
--- /dev/null
+++ b/src/service/service/service_handlers/l3nm_nce/ConfigRules.py
@@ -0,0 +1,120 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from typing import Dict, List
+
+from common.tools.object_factory.ConfigRule import (
+    json_config_rule_delete,
+    json_config_rule_set,
+)
+
+
+def setup_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]:
+    operation_type: str = json_settings["operation_type"]
+    app_flow_id: str = json_settings["app_flow_id"]
+    app_flow_user_id: str = json_settings["app_flow_user_id"]
+    max_latency: int = json_settings["max_latency"]
+    max_jitter: int = json_settings["max_jitter"]
+    max_loss: float = json_settings["max_loss"]
+    upstream_assure_bw: str = json_settings["upstream_assure_bw"]
+    upstream_max_bw: str = json_settings["upstream_max_bw"]
+    downstream_assure_bw: str = json_settings["downstream_assure_bw"]
+    downstream_max_bw: str = json_settings["downstream_max_bw"]
+    src_ip: str = json_settings["src_ip"]
+    src_port: str = json_settings["src_port"]
+    dst_ip: str = json_settings["dst_ip"]
+    dst_port: str = json_settings["dst_port"]
+
+    app_flow_app_name: str = f"App_Flow_{app_flow_id}"
+    app_flow_service_profile: str = f"service_{app_flow_id}"
+    app_id: str = f"app_{app_flow_id}"
+    app_feature_id: str = f"feature_{app_flow_id}"
+    app_flow_name: str = f"App_Flow_{app_flow_id}"
+    app_flow_max_online_users: int = json_settings.get("app_flow_max_online_users", 1)
+    app_flow_stas: str = json_settings.get("stas", "00:3D:E1:18:82:9E")
+    qos_profile_name: str = json_settings.get("app_flow_qos_profile", "AR_VR_Gaming")
+    app_flow_duration: int = json_settings.get("app_flow_duration", 9999)
+    protocol: str = json_settings.get("protocol", "tcp")
+
+    app_flow = {
+        "name": app_flow_name,
+        "user-id": app_flow_user_id,
+        "app-name": app_flow_app_name,
+        "max-online-users": app_flow_max_online_users,
+        "stas": app_flow_stas,
+        "qos-profile": qos_profile_name,
+        "service-profile": app_flow_service_profile,
+        "duration": app_flow_duration,
+    }
+    qos_profile = {
+        "name": qos_profile_name,
+        "max-latency": max_latency,
+        "max-jitter": max_jitter,
+        "max-loss": max_loss,
+        "upstream": {
+            "assure-bandwidth": upstream_assure_bw,
+            "max-bandwidth": upstream_max_bw,
+        },
+        "downstream": {
+            "assure-bandwidth": downstream_assure_bw,
+            "max-bandwidth": downstream_max_bw,
+        },
+    }
+    application = {
+        "name": app_flow_app_name,
+        "app-id": app_id,
+        "app-features": {
+            "app-feature": [
+                {
+                    "id": app_feature_id,
+                    "dest-ip": dst_ip,
+                    "dest-port": dst_port,
+                    "src-ip": src_ip,
+                    "src-port": src_port,
+                    "protocol": protocol,
+                }
+            ]
+        },
+    }
+    app_flow_datamodel = {
+        "huawei-nce-app-flow:app-flows": {
+            "app-flow": [app_flow],
+            "qos-profiles": {"qos-profile": [qos_profile]},
+            "applications": {"application": [application]},
+        }
+    }
+    json_config_rules = [
+        json_config_rule_set(
+            "/service[{:s}]/AppFlow".format(service_uuid), app_flow_datamodel
+        ),
+        json_config_rule_set(
+            "/service[{:s}]/AppFlow/operation".format(service_uuid),
+            {"type": operation_type},
+        ),
+    ]
+    return json_config_rules
+
+
+def teardown_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]:
+    json_config_rules = [
+        json_config_rule_delete(
+            "/service[{:s}]/AppFlow".format(service_uuid),
+            {},
+        ),
+        json_config_rule_delete(
+            "/service[{:s}]/AppFlow/operation".format(service_uuid),
+            {},
+        ),
+    ]
+    return json_config_rules
diff --git a/src/service/service/service_handlers/l3nm_nce/L3NMNCEServiceHandler.py b/src/service/service/service_handlers/l3nm_nce/L3NMNCEServiceHandler.py
new file mode 100644
index 0000000000000000000000000000000000000000..1317bd0615e4789d7ba76e8c0c6b0923d8f2dec7
--- /dev/null
+++ b/src/service/service/service_handlers/l3nm_nce/L3NMNCEServiceHandler.py
@@ -0,0 +1,564 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+import logging
+import re
+from typing import Any, List, Optional, Tuple, Union, TypedDict, Dict
+from uuid import uuid4
+
+from deepdiff import DeepDiff
+
+from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method
+from common.proto.context_pb2 import ConfigRule, DeviceId, Empty, Service, ServiceConfig
+from common.tools.object_factory.Device import json_device_id
+from common.type_checkers.Checkers import chk_type
+from context.client.ContextClient import ContextClient
+from service.service.service_handler_api._ServiceHandler import _ServiceHandler
+from service.service.service_handler_api.SettingsHandler import SettingsHandler
+from service.service.service_handler_api.Tools import (
+    get_device_endpoint_uuids,
+)
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
+
+from .ConfigRules import setup_config_rules, teardown_config_rules
+
+RUNNING_RESOURCE_KEY = "running_ietf_slice"
+CANDIDATE_RESOURCE_KEY = "candidate_ietf_slice"
+
+LOGGER = logging.getLogger(__name__)
+
+METRICS_POOL = MetricsPool("Service", "Handler", labels={"handler": "l3nm_nce"})
+
+SDP_DIFF_RE = re.compile(
+    r"^root\[\'network-slice-services\'\]\[\'slice-service\'\]\[0\]\[\'sdps\'\]\[\'sdp\'\]\[(\d)\]$"
+)
+CONNECTION_GROUP_DIFF_RE = re.compile(
+    r"^root\[\'network-slice-services\'\]\[\'slice-service\'\]\[0\]\[\'connection-groups\'\]\[\'connection-group\'\]\[(\d)\]$"
+)
+MATCH_CRITERION_DIFF_RE = re.compile(
+    r"^root\[\'network-slice-services\'\]\[\'slice-service\'\]\[0\]\[\'sdps\'\]\[\'sdp\'\]\[(\d)\]\[\'service-match-criteria\'\]\[\'match-criterion\'\]\[(\d)\]$"
+)
+
+
+class Ipv4Info(TypedDict):
+    src_ip: str
+    dst_ip: str
+    src_port: str
+    dst_port: str
+
+
+def get_removed_items(
+    candidate_ietf_slice_dict: dict, running_ietf_slice_dict: dict
+) -> dict:
+    """
+    For the 'iterable_item_removed' scenario, returns dict with removed sdp / connection_group / match_criterion info.
+    Raises an exception if there's inconsistent data or multiple items removed (which is not supported).
+    """
+    removed_items = {
+        "sdp": {"sdp_idx": None, "value": {}},
+        "connection_group": {"connection_group_idx": None, "value": {}},
+        "match_criterion": {
+            "sdp_idx": None,
+            "match_criterion_idx": None,
+            "value": {},
+        },
+    }
+
+    running_slice_services = running_ietf_slice_dict["network-slice-services"][
+        "slice-service"
+    ][0]
+    candidate_slice_services = candidate_ietf_slice_dict["network-slice-services"][
+        "slice-service"
+    ][0]
+
+    running_slice_sdps = [sdp["id"] for sdp in running_slice_services["sdps"]["sdp"]]
+    candidiate_slice_sdps = [
+        sdp["id"] for sdp in candidate_slice_services["sdps"]["sdp"]
+    ]
+    removed_sdps = set(running_slice_sdps) - set(candidiate_slice_sdps)
+
+    if len(removed_sdps) > 1:
+        raise Exception("Multiple SDPs removed - not supported.")
+    removed_sdp_id = removed_sdps.pop()
+
+    removed_items["sdp"]["sdp_idx"] = running_slice_sdps.index(removed_sdp_id)
+    removed_items["sdp"]["value"] = next(
+        sdp
+        for sdp in running_slice_services["sdps"]["sdp"]
+        if sdp["id"] == removed_sdp_id
+    )
+
+    match_criteria = removed_items["sdp"]["value"]["service-match-criteria"][
+        "match-criterion"
+    ]
+    if len(match_criteria) > 1:
+        raise Exception("Multiple match criteria found - not supported")
+    match_criterion = match_criteria[0]
+    connection_grp_id = match_criterion["target-connection-group-id"]
+    connection_groups = running_slice_services["connection-groups"]["connection-group"]
+    connection_group = next(
+        (idx, cg)
+        for idx, cg in enumerate(connection_groups)
+        if cg["id"] == connection_grp_id
+    )
+    removed_items["connection_group"]["connection_group_idx"] = connection_group[0]
+    removed_items["connection_group"]["value"] = connection_group[1]
+
+    for sdp in running_slice_services["sdps"]["sdp"]:
+        if sdp["id"] == removed_sdp_id:
+            continue
+        for mc in sdp["service-match-criteria"]["match-criterion"]:
+            if mc["target-connection-group-id"] == connection_grp_id:
+                removed_items["match_criterion"]["sdp_idx"] = running_slice_sdps.index(
+                    sdp["id"]
+                )
+                removed_items["match_criterion"]["match_criterion_idx"] = sdp[
+                    "service-match-criteria"
+                ]["match-criterion"].index(mc)
+                removed_items["match_criterion"]["value"] = mc
+                break
+
+    if (
+        removed_items["match_criterion"]["sdp_idx"] is None
+        or removed_items["sdp"]["sdp_idx"] is None
+        or removed_items["connection_group"]["connection_group_idx"] is None
+    ):
+        raise Exception("sdp, connection group or match criterion not found")
+
+    return removed_items
+
+
+def get_custom_config_rule(
+    service_config: ServiceConfig, resource_key: str
+) -> Optional[ConfigRule]:
+    """
+    Returns the ConfigRule from service_config matching the provided resource_key
+    if found, otherwise returns None.
+    """
+    for cr in service_config.config_rules:
+        if (
+            cr.WhichOneof("config_rule") == "custom"
+            and cr.custom.resource_key == resource_key
+        ):
+            return cr
+    return None
+
+
+def get_running_candidate_ietf_slice_data_diff(service_config: ServiceConfig) -> Dict:
+    """
+    Loads the JSON from the running/candidate resource ConfigRules and returns
+    their DeepDiff comparison.
+    """
+    running_cr = get_custom_config_rule(service_config, RUNNING_RESOURCE_KEY)
+    candidate_cr = get_custom_config_rule(service_config, CANDIDATE_RESOURCE_KEY)
+
+    running_value_dict = json.loads(running_cr.custom.resource_value)
+    candidate_value_dict = json.loads(candidate_cr.custom.resource_value)
+
+    return DeepDiff(running_value_dict, candidate_value_dict)
+
+
+def extract_qos_info(
+    connection_groups: List, connection_grp_id: str, src_sdp_idx: str, dst_sdp_idx: str
+) -> Dict:
+    """
+    Extract QoS information from connection groups based on the connection group ID.
+    """
+    qos_info = {
+        "upstream": {"max_delay": "0", "bw": "0", "packet_loss": "0"},
+        "downstream": {"max_delay": "0", "bw": "0", "packet_loss": "0"},
+    }
+    connection_group = next(
+        (cg for cg in connection_groups if cg["id"] == connection_grp_id), None
+    )
+
+    if not connection_group:
+        return qos_info
+
+    for cc in connection_group["connectivity-construct"]:
+        if (
+            cc["p2p-sender-sdp"] == src_sdp_idx
+            and cc["p2p-receiver-sdp"] == dst_sdp_idx
+        ):
+            direction = "upstream"
+        elif (
+            cc["p2p-sender-sdp"] == dst_sdp_idx
+            and cc["p2p-receiver-sdp"] == src_sdp_idx
+        ):
+            direction = "downstream"
+        else:
+            raise Exception("invalid sender and receiver sdp ids")
+        for metric_bound in cc["service-slo-sle-policy"]["slo-policy"]["metric-bound"]:
+            if (
+                metric_bound["metric-type"]
+                == "ietf-network-slice-service:one-way-delay-maximum"
+                and metric_bound["metric-unit"] == "milliseconds"
+            ):
+                qos_info[direction]["max_delay"] = metric_bound["bound"]
+            elif (
+                metric_bound["metric-type"]
+                == "ietf-network-slice-service:one-way-bandwidth"
+                and metric_bound["metric-unit"] == "Mbps"
+            ):
+                qos_info[direction]["bw"] = metric_bound["bound"]
+            elif (
+                metric_bound["metric-type"]
+                == "ietf-network-slice-service:two-way-packet-loss"
+                and metric_bound["metric-unit"] == "percentage"
+            ):
+                qos_info[direction]["packet_loss"] = metric_bound["percentile-value"]
+
+    return qos_info
+
+
+def extract_match_criterion_ipv4_info(match_criterion: Dict) -> Ipv4Info:
+    """
+    Extracts IPv4 info from the match criterion dictionary.
+    """
+    src_ip = dst_ip = src_port = dst_port = ""
+
+    for type_value in match_criterion["match-type"]:
+        m_type = type_value["type"]
+        val = type_value["value"][0]
+        if m_type == "ietf-network-slice-service:source-ip-prefix":
+            src_ip = val.split("/")[0]
+        elif m_type == "ietf-network-slice-service:destination-ip-prefix":
+            dst_ip = val.split("/")[0]
+        elif m_type == "ietf-network-slice-service:source-tcp-port":
+            src_port = val
+        elif m_type == "ietf-network-slice-service:destination-tcp-port":
+            dst_port = val
+
+    return Ipv4Info(
+        src_ip=src_ip,
+        dst_ip=dst_ip,
+        src_port=src_port,
+        dst_port=dst_port,
+    )
+
+
+class L3NMNCEServiceHandler(_ServiceHandler):
+    def __init__(  # pylint: disable=super-init-not-called
+        self, service: Service, task_executor: TaskExecutor, **settings
+    ) -> None:
+        self.__service = service
+        self.__task_executor = task_executor
+        self.__settings_handler = SettingsHandler(service.service_config, **settings)
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetEndpoint(
+        self,
+        endpoints: List[Tuple[str, str, Optional[str]]],
+        connection_uuid: Optional[str] = None,
+    ) -> List[Union[bool, Exception]]:
+        chk_type("endpoints", endpoints, list)
+        if len(endpoints) == 0:
+            return []
+
+        results = []
+        try:
+            context_client = ContextClient()
+            service_config = self.__service.service_config
+            settings = self.__settings_handler.get("/settings")
+
+            src_device_uuid, src_endpoint_uuid = get_device_endpoint_uuids(endpoints[0])
+            src_device_obj = self.__task_executor.get_device(
+                DeviceId(**json_device_id(src_device_uuid))
+            )
+            controller = self.__task_executor.get_device_controller(src_device_obj)
+
+            list_devices = context_client.ListDevices(Empty())
+            devices = list_devices.devices
+            device_name_map = {d.name: d for d in devices}
+
+            running_candidate_diff = get_running_candidate_ietf_slice_data_diff(
+                service_config
+            )
+            candidate_ietf_slice_cr = get_custom_config_rule(
+                service_config, CANDIDATE_RESOURCE_KEY
+            )
+            candidate_resource_value_dict = json.loads(
+                candidate_ietf_slice_cr.custom.resource_value
+            )
+            running_ietf_slice_cr = get_custom_config_rule(
+                service_config, RUNNING_RESOURCE_KEY
+            )
+            running_resource_value_dict = json.loads(
+                running_ietf_slice_cr.custom.resource_value
+            )
+
+            service_name = running_resource_value_dict["network-slice-services"][
+                "slice-service"
+            ][0]["id"]
+
+            if not running_candidate_diff:  # Slice Creation
+                operation_type = "create"
+
+                slice_service = candidate_resource_value_dict["network-slice-services"][
+                    "slice-service"
+                ][0]
+                sdps = slice_service["sdps"]["sdp"]
+                connection_groups = slice_service["connection-groups"][
+                    "connection-group"
+                ]
+                sdp_ids = [sdp["id"] for sdp in sdps]
+                for sdp in sdps:
+                    node_id = sdp["node-id"]
+                    device_obj = device_name_map[node_id]
+                    device_controller = self.__task_executor.get_device_controller(
+                        device_obj
+                    )
+                    if (
+                        device_controller is None
+                        or controller.name != device_controller.name
+                    ):
+                        continue
+                    src_sdp_idx = sdp_ids.pop(sdp_ids.index(sdp["id"]))
+                    dst_sdp_idx = sdp_ids[0]
+                    match_criteria = sdp["service-match-criteria"]["match-criterion"]
+                    match_criterion = match_criteria[0]
+                    connection_grp_id = match_criterion["target-connection-group-id"]
+                    break
+                else:
+                    raise Exception("connection group id not found")
+            elif "iterable_item_added" in running_candidate_diff:  # new SDP added
+                operation_type = "create"
+
+                slice_service = candidate_resource_value_dict["network-slice-services"][
+                    "slice-service"
+                ][0]
+                sdps = slice_service["sdps"]["sdp"]
+                connection_groups = slice_service["connection-groups"][
+                    "connection-group"
+                ]
+                added_items = {
+                    "sdp": {"sdp_idx": None, "value": {}},
+                    "connection_group": {"connection_group_idx": None, "value": {}},
+                    "match_criterion": {
+                        "sdp_idx": None,
+                        "match_criterion_idx": None,
+                        "value": {},
+                    },
+                }
+                for added_key, added_value in running_candidate_diff[
+                    "iterable_item_added"
+                ].items():
+                    sdp_match = SDP_DIFF_RE.match(added_key)
+                    connection_group_match = CONNECTION_GROUP_DIFF_RE.match(added_key)
+                    match_criterion_match = MATCH_CRITERION_DIFF_RE.match(added_key)
+                    if sdp_match:
+                        added_items["sdp"] = {
+                            "sdp_idx": int(sdp_match.groups()[0]),
+                            "value": added_value,
+                        }
+                    elif connection_group_match:
+                        added_items["connection_group"] = {
+                            "connection_group_idx": int(
+                                connection_group_match.groups()[0]
+                            ),
+                            "value": added_value,
+                        }
+                    elif match_criterion_match:
+                        added_items["match_criterion"] = {
+                            "sdp_idx": int(match_criterion_match.groups()[0]),
+                            "match_criterion_idx": int(
+                                match_criterion_match.groups()[1]
+                            ),
+                            "value": added_value,
+                        }
+                new_sdp = sdps[added_items["sdp"]["sdp_idx"]]
+                src_sdp_idx = new_sdp["id"]
+                dst_sdp_idx = sdps[added_items["match_criterion"]["sdp_idx"]]["id"]
+                connection_grp_id = connection_groups[
+                    added_items["connection_group"]["connection_group_idx"]
+                ]["id"]
+
+                if (
+                    connection_grp_id
+                    != added_items["match_criterion"]["value"][
+                        "target-connection-group-id"
+                    ]
+                ):
+                    raise Exception(
+                        "connection group missmatch in destination sdp and added connection group"
+                    )
+                match_criteria = new_sdp["service-match-criteria"]["match-criterion"]
+                match_criterion = match_criteria[0]
+            elif "iterable_item_removed" in running_candidate_diff:  # new SDP added
+                operation_type = "delete"
+
+                slice_service = running_resource_value_dict["network-slice-services"][
+                    "slice-service"
+                ][0]
+                sdps = slice_service["sdps"]["sdp"]
+                connection_groups = slice_service["connection-groups"][
+                    "connection-group"
+                ]
+                removed_items = get_removed_items(
+                    candidate_resource_value_dict, running_resource_value_dict
+                )
+                removed_sdp = sdps[removed_items["sdp"]["sdp_idx"]]
+                src_sdp_idx = removed_sdp["id"]
+                dst_sdp_idx = sdps[removed_items["match_criterion"]["sdp_idx"]]["id"]
+                connection_grp_id = connection_groups[
+                    removed_items["connection_group"]["connection_group_idx"]
+                ]["id"]
+
+                if (
+                    connection_grp_id
+                    != removed_items["match_criterion"]["value"][
+                        "target-connection-group-id"
+                    ]
+                ):
+                    raise Exception(
+                        "connection group missmatch in destination sdp and added connection group"
+                    )
+                match_criteria = removed_sdp["service-match-criteria"][
+                    "match-criterion"
+                ]
+                match_criterion = match_criteria[0]
+            else:
+                raise Exception(
+                    "transition from candidate to running info not supported"
+                )
+
+            ip_info = extract_match_criterion_ipv4_info(match_criterion)
+
+            qos_info = extract_qos_info(
+                connection_groups, connection_grp_id, src_sdp_idx, dst_sdp_idx
+            )
+
+            resource_value_dict = {
+                "uuid": service_name,
+                "operation_type": operation_type,
+                "app_flow_id": f"{src_sdp_idx}_{dst_sdp_idx}_{service_name}",
+                "app_flow_user_id": str(uuid4()),
+                "max_latency": int(qos_info["upstream"]["max_delay"]),
+                "max_jitter": 10,
+                "max_loss": float(qos_info["upstream"]["packet_loss"]),
+                "upstream_assure_bw": int(qos_info["upstream"]["bw"]) * 1e6,
+                "upstream_max_bw": 2 * int(qos_info["upstream"]["bw"]) * 1e6,
+                "downstream_assure_bw": int(qos_info["downstream"]["bw"]) * 1e6,
+                "downstream_max_bw": 2 * int(qos_info["downstream"]["bw"]) * 1e6,
+                "src_ip": ip_info["src_ip"],
+                "src_port": ip_info["src_port"],
+                "dst_ip": ip_info["dst_ip"],
+                "dst_port": ip_info["dst_port"],
+            }
+            json_config_rules = setup_config_rules(service_name, resource_value_dict)
+
+            del controller.device_config.config_rules[:]
+            for jcr in json_config_rules:
+                controller.device_config.config_rules.append(ConfigRule(**jcr))
+
+            self.__task_executor.configure_device(controller)
+            LOGGER.debug('Configured device "{:s}"'.format(controller.name))
+
+        except Exception as e:  # pylint: disable=broad-except
+            results.append(e)
+
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def DeleteEndpoint(
+        self,
+        endpoints: List[Tuple[str, str, Optional[str]]],
+        connection_uuid: Optional[str] = None,
+    ) -> List[Union[bool, Exception]]:
+        chk_type("endpoints", endpoints, list)
+        if len(endpoints) == 0:
+            return []
+        service_uuid = self.__service.service_id.service_uuid.uuid
+        results = []
+        try:
+            src_device_uuid, src_endpoint_uuid = get_device_endpoint_uuids(endpoints[0])
+            src_device_obj = self.__task_executor.get_device(
+                DeviceId(**json_device_id(src_device_uuid))
+            )
+            controller = self.__task_executor.get_device_controller(src_device_obj)
+            json_config_rules = teardown_config_rules(service_uuid, {})
+            if len(json_config_rules) > 0:
+                del controller.device_config.config_rules[:]
+                for json_config_rule in json_config_rules:
+                    controller.device_config.config_rules.append(
+                        ConfigRule(**json_config_rule)
+                    )
+                self.__task_executor.configure_device(controller)
+            results.append(True)
+        except Exception as e:  # pylint: disable=broad-except
+            results.append(e)
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetConstraint(
+        self, constraints: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        chk_type("constraints", constraints, list)
+        if len(constraints) == 0:
+            return []
+
+        msg = "[SetConstraint] Method not implemented. Constraints({:s}) are being ignored."
+        LOGGER.warning(msg.format(str(constraints)))
+        return [True for _ in range(len(constraints))]
+
+    @metered_subclass_method(METRICS_POOL)
+    def DeleteConstraint(
+        self, constraints: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        chk_type("constraints", constraints, list)
+        if len(constraints) == 0:
+            return []
+
+        msg = "[DeleteConstraint] Method not implemented. Constraints({:s}) are being ignored."
+        LOGGER.warning(msg.format(str(constraints)))
+        return [True for _ in range(len(constraints))]
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetConfig(
+        self, resources: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        chk_type("resources", resources, list)
+        if len(resources) == 0:
+            return []
+
+        results = []
+        for resource in resources:
+            try:
+                resource_value = json.loads(resource[1])
+                self.__settings_handler.set(resource[0], resource_value)
+                results.append(True)
+            except Exception as e:  # pylint: disable=broad-except
+                LOGGER.exception("Unable to SetConfig({:s})".format(str(resource)))
+                results.append(e)
+
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def DeleteConfig(
+        self, resources: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        chk_type("resources", resources, list)
+        if len(resources) == 0:
+            return []
+
+        results = []
+        for resource in resources:
+            try:
+                self.__settings_handler.delete(resource[0])
+            except Exception as e:  # pylint: disable=broad-except
+                LOGGER.exception("Unable to DeleteConfig({:s})".format(str(resource)))
+                results.append(e)
+
+        return results
diff --git a/src/service/service/service_handlers/l3nm_nce/__init__.py b/src/service/service/service_handlers/l3nm_nce/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ccc21c7db78aac26daa1f8c5ff8e1ffd3f35460
--- /dev/null
+++ b/src/service/service/service_handlers/l3nm_nce/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/service/service/service_handlers/l3slice_ietfslice/ConfigRules.py b/src/service/service/service_handlers/l3slice_ietfslice/ConfigRules.py
new file mode 100644
index 0000000000000000000000000000000000000000..173d4ba10dbf1f6a8aead912a2a1435632f94569
--- /dev/null
+++ b/src/service/service/service_handlers/l3slice_ietfslice/ConfigRules.py
@@ -0,0 +1,301 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from typing import Dict, List, Tuple
+
+from common.proto.context_pb2 import Link
+from common.tools.object_factory.ConfigRule import (
+    json_config_rule_delete,
+    json_config_rule_set,
+)
+from context.client.ContextClient import ContextClient
+
+
+def build_match_criterion(
+    vlan: str,
+    src_ip: str,
+    src_port: str,
+    dst_ip: str,
+    dst_port: str,
+    target_conn_group_id: str = "line1",
+    index: int = 1,
+) -> Dict:
+    """
+    Build the match-criterion structure used in the 'service-match-criteria'.
+    """
+    return {
+        "index": index,
+        "match-type": [
+            {"type": "ietf-network-slice-service:vlan", "value": [vlan]},
+            {
+                "type": "ietf-network-slice-service:source-ip-prefix",
+                "value": [src_ip],
+            },
+            {
+                "type": "ietf-network-slice-service:source-tcp-port",
+                "value": [src_port],
+            },
+            {
+                "type": "ietf-network-slice-service:destination-ip-prefix",
+                "value": [dst_ip],
+            },
+            {
+                "type": "ietf-network-slice-service:destination-tcp-port",
+                "value": [dst_port],
+            },
+        ],
+        "target-connection-group-id": target_conn_group_id,
+    }
+
+
+def build_sdp(
+    sdp_id: str,
+    node_id: str,
+    mgmt_ip: str,
+    ac_node_id: str,
+    ac_ep_id: str,
+    match_criterion: Dict,
+    attachment_id: str = "0",
+    attachment_description: str = "dsc",
+) -> Dict:
+    """
+    Build the sdp structure used in the 'slice_service' dictionary.
+    """
+    return {
+        "id": sdp_id,
+        "node-id": node_id,
+        "sdp-ip-address": [mgmt_ip],
+        "service-match-criteria": {"match-criterion": [match_criterion]},
+        "attachment-circuits": {
+            "attachment-circuit": [
+                {
+                    "id": attachment_id,
+                    "description": attachment_description,
+                    "ac-node-id": ac_node_id,
+                    "ac-tp-id": ac_ep_id,
+                }
+            ]
+        },
+    }
+
+
+def build_slo_policy_bound(
+    one_way_delay: int, one_way_bandwidth: int, one_way_packet_loss: float
+) -> List[Dict]:
+    """
+    Build the 'metric-bound' portion of the 'slo-policy' dictionary.
+    """
+    return [
+        {
+            "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+            "metric-unit": "milliseconds",
+            "bound": one_way_delay,
+        },
+        {
+            "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+            "metric-unit": "Mbps",
+            "bound": one_way_bandwidth,
+        },
+        {
+            "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+            "metric-unit": "percentage",
+            "percentile-value": one_way_packet_loss,
+        },
+    ]
+
+
+def _get_device_endpoint_name(device_obj, endpoint_uuid: str) -> str:
+    """
+    Given a device object and an endpoint UUID, return the device endpoint name.
+    Raises an exception if not found.
+    """
+    for d_ep in device_obj.device_endpoints:
+        if d_ep.endpoint_id.endpoint_uuid.uuid == endpoint_uuid:
+            return d_ep.name
+    raise Exception("Endpoint not found")
+
+
+def setup_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]:
+    operation_type: str = json_settings["operation_type"]
+
+    # Source parameters
+    src_node_id: str = json_settings["src_node_id"]
+    src_mgmt_ip_address: str = json_settings["src_mgmt_ip_address"]
+    src_ac_node_id: str = json_settings["src_ac_node_id"]
+    src_ac_ep_id: str = json_settings["src_ac_ep_id"]
+    src_vlan: str = json_settings["src_vlan"]
+    src_source_ip_prefix: str = json_settings["src_source_ip_prefix"]
+    src_source_tcp_port: str = json_settings["src_source_tcp_port"]
+    src_destination_ip_prefix: str = json_settings["src_destination_ip_prefix"]
+    src_destination_tcp_port: str = json_settings["src_destination_tcp_port"]
+    source_one_way_delay: int = int(json_settings["source_one_way_delay"])
+    source_one_way_bandwidth: int = int(json_settings["source_one_way_bandwidth"])
+    source_one_way_packet_loss: float = float(
+        json_settings["source_one_way_packet_loss"]
+    )
+
+    # Destination parameters
+    dst_node_id: str = json_settings["dst_node_id"]
+    dst_mgmt_ip_address: str = json_settings["dst_mgmt_ip_address"]
+    dst_ac_node_id: str = json_settings["dst_ac_node_id"]
+    dst_ac_ep_id: str = json_settings["dst_ac_ep_id"]
+    dst_vlan: str = json_settings["dst_vlan"]
+    dst_source_ip_prefix: str = json_settings["dst_source_ip_prefix"]
+    dst_source_tcp_port: str = json_settings["dst_source_tcp_port"]
+    dst_destination_ip_prefix: str = json_settings["dst_destination_ip_prefix"]
+    dst_destination_tcp_port: str = json_settings["dst_destination_tcp_port"]
+    destination_one_way_delay: int = int(json_settings["destination_one_way_delay"])
+    destination_one_way_bandwidth: int = int(
+        json_settings["destination_one_way_bandwidth"]
+    )
+    destination_one_way_packet_loss: float = float(
+        json_settings["destination_one_way_packet_loss"]
+    )
+
+    # Slice ID
+    slice_id: str = json_settings["slice_id"]
+
+    # build source & destination match criteria
+    src_match_criterion = build_match_criterion(
+        vlan=src_vlan,
+        src_ip=src_source_ip_prefix,
+        src_port=src_source_tcp_port,
+        dst_ip=src_destination_ip_prefix,
+        dst_port=src_destination_tcp_port,
+    )
+    dst_match_criterion = build_match_criterion(
+        vlan=dst_vlan,
+        src_ip=dst_source_ip_prefix,
+        src_port=dst_source_tcp_port,
+        dst_ip=dst_destination_ip_prefix,
+        dst_port=dst_destination_tcp_port,
+    )
+
+    # Build SDPs
+    sdp_src = build_sdp(
+        sdp_id="1",
+        node_id=src_node_id,
+        mgmt_ip=src_mgmt_ip_address,
+        ac_node_id=src_ac_node_id,
+        ac_ep_id=src_ac_ep_id,
+        match_criterion=src_match_criterion,
+    )
+    sdp_dst = build_sdp(
+        sdp_id="2",
+        node_id=dst_node_id,
+        mgmt_ip=dst_mgmt_ip_address,
+        ac_node_id=dst_ac_node_id,
+        ac_ep_id=dst_ac_ep_id,
+        match_criterion=dst_match_criterion,
+    )
+
+    sdps = [sdp_src, sdp_dst]
+
+    # Build connection-groups
+    connection_groups = [
+        {
+            "id": "line1",
+            "connectivity-type": "point-to-point",
+            "connectivity-construct": [
+                {
+                    "id": 1,
+                    "p2p-sender-sdp": "1",
+                    "p2p-receiver-sdp": "2",
+                    "service-slo-sle-policy": {
+                        "slo-policy": {
+                            "metric-bound": build_slo_policy_bound(
+                                one_way_delay=source_one_way_delay,
+                                one_way_bandwidth=source_one_way_bandwidth,
+                                one_way_packet_loss=source_one_way_packet_loss,
+                            )
+                        }
+                    },
+                },
+                {
+                    "id": 2,
+                    "p2p-sender-sdp": "2",
+                    "p2p-receiver-sdp": "1",
+                    "service-slo-sle-policy": {
+                        "slo-policy": {
+                            "metric-bound": build_slo_policy_bound(
+                                one_way_delay=destination_one_way_delay,
+                                one_way_bandwidth=destination_one_way_bandwidth,
+                                one_way_packet_loss=destination_one_way_packet_loss,
+                            )
+                        }
+                    },
+                },
+            ],
+        }
+    ]
+
+    slice_service = {
+        "id": slice_id,
+        "description": "dsc",
+        "sdps": {"sdp": sdps},
+        "connection-groups": {"connection-group": connection_groups},
+    }
+    slice_data_model = {"network-slice-services": {"slice-service": [slice_service]}}
+
+    json_config_rules = [
+        json_config_rule_set(
+            "/service[{:s}]/IETFSlice".format(service_uuid),
+            slice_data_model,
+        ),
+        json_config_rule_set(
+            "/service[{:s}]/IETFSlice/operation".format(service_uuid),
+            {"type": operation_type},
+        ),
+    ]
+    return json_config_rules
+
+
+def teardown_config_rules(service_uuid: str, json_settings: Dict) -> List[Dict]:
+    json_config_rules = [
+        json_config_rule_delete(
+            "/service[{:s}]/IETFSlice".format(service_uuid),
+            {},
+        ),
+        json_config_rule_delete(
+            "/service[{:s}]/IETFSlice/operation".format(service_uuid),
+            {},
+        ),
+    ]
+    return json_config_rules
+
+
+def get_link_ep_device_names(
+    link: Link, context_client: ContextClient
+) -> Tuple[str, str, str, str]:
+    ep_ids = link.link_endpoint_ids
+    ep_device_id_1 = ep_ids[0].device_id
+    ep_uuid_1 = ep_ids[0].endpoint_uuid.uuid
+    device_obj_1 = context_client.GetDevice(ep_device_id_1)
+    ep_name_1 = _get_device_endpoint_name(device_obj_1, ep_uuid_1)
+    device_obj_name_1 = device_obj_1.name
+
+    ep_device_id_2 = ep_ids[1].device_id
+    ep_uuid_2 = ep_ids[1].endpoint_uuid.uuid
+    device_obj_2 = context_client.GetDevice(ep_device_id_2)
+    ep_name_2 = _get_device_endpoint_name(device_obj_2, ep_uuid_2)
+    device_obj_name_2 = device_obj_2.name
+
+    return (
+        device_obj_name_1,
+        ep_name_1,
+        device_obj_1,
+        device_obj_name_2,
+        ep_name_2,
+        device_obj_2,
+    )
diff --git a/src/service/service/service_handlers/l3slice_ietfslice/L3SliceIETFSliceServiceHandler.py b/src/service/service/service_handlers/l3slice_ietfslice/L3SliceIETFSliceServiceHandler.py
new file mode 100644
index 0000000000000000000000000000000000000000..0df8b56e3495dcf70dcfd78b8e3ea83bef93dc46
--- /dev/null
+++ b/src/service/service/service_handlers/l3slice_ietfslice/L3SliceIETFSliceServiceHandler.py
@@ -0,0 +1,959 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+import logging
+import re
+from typing import Any, Dict, List, Optional, Tuple, TypedDict, Union
+
+from deepdiff import DeepDiff
+from dataclasses import dataclass
+
+from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method
+from common.proto.context_pb2 import ConfigRule, DeviceId, Empty, Service, ServiceConfig
+from common.tools.object_factory.Device import json_device_id
+from common.type_checkers.Checkers import chk_type
+from context.client.ContextClient import ContextClient
+from service.service.service_handler_api._ServiceHandler import _ServiceHandler
+from service.service.service_handler_api.SettingsHandler import SettingsHandler
+from service.service.service_handler_api.Tools import (
+    get_device_endpoint_uuids,
+)
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
+
+from .ConfigRules import (
+    get_link_ep_device_names,
+    setup_config_rules,
+    teardown_config_rules,
+)
+
+RUNNING_RESOURCE_KEY = "running_ietf_slice"
+CANDIDATE_RESOURCE_KEY = "candidate_ietf_slice"
+
+SDP_DIFF_RE = re.compile(
+    r"^root\[\'network-slice-services\'\]\[\'slice-service\'\]\[0\]\[\'sdps\'\]\[\'sdp\'\]\[(\d)\]$"
+)
+CONNECTION_GROUP_DIFF_RE = re.compile(
+    r"^root\[\'network-slice-services\'\]\[\'slice-service\'\]\[0\]\[\'connection-groups\'\]\[\'connection-group\'\]\[(\d)\]$"
+)
+MATCH_CRITERION_DIFF_RE = re.compile(
+    r"^root\[\'network-slice-services\'\]\[\'slice-service\'\]\[0\]\[\'sdps\'\]\[\'sdp\'\]\[(\d)\]\[\'service-match-criteria\'\]\[\'match-criterion\'\]\[(\d)\]$"
+)
+
+RE_GET_ENDPOINT_FROM_INTERFACE = re.compile(r"^\/interface\[([^\]]+)\].*")
+
+LOGGER = logging.getLogger(__name__)
+
+METRICS_POOL = MetricsPool(
+    "Service", "Handler", labels={"handler": "l3slice_ietfslice"}
+)
+
+
+RAISE_IF_DIFFERS = True
+
+
+class Ipv4Info(TypedDict):
+    src_lan: str
+    dst_lan: str
+    src_port: str
+    dst_port: str
+    vlan: str
+
+
+class DeviceEpInfo(TypedDict):
+    ipv4_info: Ipv4Info
+    node_name: str
+    endpoint_name: str
+    one_way_delay: int
+    one_way_bandwidth: int
+    one_way_packet_loss: float
+
+
+@dataclass
+class ConnectivityConstructInfo:
+    bandwidth: int = 0
+    delay: int = 0
+    packet_loss: float = 0.0
+
+
+def get_custom_config_rule(
+    service_config: ServiceConfig, resource_key: str
+) -> Optional[ConfigRule]:
+    """
+    Returns the ConfigRule from service_config matching the provided resource_key
+    if found, otherwise returns None.
+    """
+    for cr in service_config.config_rules:
+        if (
+            cr.WhichOneof("config_rule") == "custom"
+            and cr.custom.resource_key == resource_key
+        ):
+            return cr
+    return None
+
+
+def get_running_candidate_ietf_slice_data_diff(service_config: ServiceConfig) -> Dict:
+    """
+    Loads the JSON from the running/candidate resource ConfigRules and returns
+    their DeepDiff comparison.
+    """
+    running_cr = get_custom_config_rule(service_config, RUNNING_RESOURCE_KEY)
+    candidate_cr = get_custom_config_rule(service_config, CANDIDATE_RESOURCE_KEY)
+    running_value_dict = json.loads(running_cr.custom.resource_value)
+    candidate_value_dict = json.loads(candidate_cr.custom.resource_value)
+    return DeepDiff(running_value_dict, candidate_value_dict)
+
+
+def extract_match_criterion_ipv4_info(match_criterion: Dict) -> Ipv4Info:
+    """
+    Extracts IPv4 info from the match criterion dictionary.
+    """
+    src_lan = dst_lan = src_port = dst_port = vlan = ""
+    for type_value in match_criterion["match-type"]:
+        m_type = type_value["type"]
+        val = type_value["value"][0]
+        if m_type == "ietf-network-slice-service:source-ip-prefix":
+            src_lan = val
+        elif m_type == "ietf-network-slice-service:destination-ip-prefix":
+            dst_lan = val
+        elif m_type == "ietf-network-slice-service:source-tcp-port":
+            src_port = val
+        elif m_type == "ietf-network-slice-service:destination-tcp-port":
+            dst_port = val
+        elif m_type == "ietf-network-slice-service:vlan":
+            vlan = val
+    return Ipv4Info(
+        src_lan=src_lan,
+        dst_lan=dst_lan,
+        src_port=src_port,
+        dst_port=dst_port,
+        vlan=vlan,
+    )
+
+
+def get_removed_items(
+    candidate_ietf_slice_dict: dict, running_ietf_slice_dict: dict
+) -> dict:
+    """
+    For the 'iterable_item_removed' scenario, returns dict with removed sdp / connection_group / match_criterion info.
+    Raises an exception if there's inconsistent data or multiple items removed (which is not supported).
+    """
+    removed_items = {
+        "sdp": {"sdp_idx": None, "value": {}},
+        "connection_group": {"connection_group_idx": None, "value": {}},
+        "match_criterion": {
+            "sdp_idx": None,
+            "match_criterion_idx": None,
+            "value": {},
+        },
+    }
+
+    running_slice_services = running_ietf_slice_dict["network-slice-services"][
+        "slice-service"
+    ][0]
+    candidate_slice_services = candidate_ietf_slice_dict["network-slice-services"][
+        "slice-service"
+    ][0]
+
+    running_slice_sdps = [sdp["id"] for sdp in running_slice_services["sdps"]["sdp"]]
+    candidiate_slice_sdps = [
+        sdp["id"] for sdp in candidate_slice_services["sdps"]["sdp"]
+    ]
+    removed_sdps = set(running_slice_sdps) - set(candidiate_slice_sdps)
+
+    if len(removed_sdps) > 1:
+        raise Exception("Multiple SDPs removed - not supported.")
+    removed_sdp_id = removed_sdps.pop()
+
+    removed_items["sdp"]["sdp_idx"] = running_slice_sdps.index(removed_sdp_id)
+    removed_items["sdp"]["value"] = next(
+        sdp
+        for sdp in running_slice_services["sdps"]["sdp"]
+        if sdp["id"] == removed_sdp_id
+    )
+
+    match_criteria = removed_items["sdp"]["value"]["service-match-criteria"][
+        "match-criterion"
+    ]
+    if len(match_criteria) > 1:
+        raise Exception("Multiple match criteria found - not supported")
+    match_criterion = match_criteria[0]
+    connection_grp_id = match_criterion["target-connection-group-id"]
+    connection_groups = running_slice_services["connection-groups"]["connection-group"]
+    connection_group = next(
+        (idx, cg)
+        for idx, cg in enumerate(connection_groups)
+        if cg["id"] == connection_grp_id
+    )
+    removed_items["connection_group"]["connection_group_idx"] = connection_group[0]
+    removed_items["connection_group"]["value"] = connection_group[1]
+
+    for sdp in running_slice_services["sdps"]["sdp"]:
+        if sdp["id"] == removed_sdp_id:
+            continue
+        for mc in sdp["service-match-criteria"]["match-criterion"]:
+            if mc["target-connection-group-id"] == connection_grp_id:
+                removed_items["match_criterion"]["sdp_idx"] = running_slice_sdps.index(
+                    sdp["id"]
+                )
+                removed_items["match_criterion"]["match_criterion_idx"] = sdp[
+                    "service-match-criteria"
+                ]["match-criterion"].index(mc)
+                removed_items["match_criterion"]["value"] = mc
+                break
+
+    if (
+        removed_items["match_criterion"]["sdp_idx"] is None
+        or removed_items["sdp"]["sdp_idx"] is None
+        or removed_items["connection_group"]["connection_group_idx"] is None
+    ):
+        raise Exception("sdp, connection group or match criterion not found")
+    return removed_items
+
+
+def gather_connectivity_construct_info(
+    candidate_connection_groups: List[Dict],
+) -> Dict[Tuple[str, str], ConnectivityConstructInfo]:
+    """
+    Creates a dict mapping (sender_sdp, receiver_sdp) -> ConnectivityConstructInfo
+    from the given list of candidate connection groups.
+    """
+    cc_info: Dict[Tuple[str, str], ConnectivityConstructInfo] = {}
+    for cg in candidate_connection_groups:
+        for cc in cg["connectivity-construct"]:
+            cc_sender = cc["p2p-sender-sdp"]
+            cc_receiver = cc["p2p-receiver-sdp"]
+            cc_key = (cc_sender, cc_receiver)
+            cc_info[cc_key] = ConnectivityConstructInfo()
+            for metric_bound in cc["service-slo-sle-policy"]["slo-policy"][
+                "metric-bound"
+            ]:
+                if (
+                    metric_bound["metric-type"]
+                    == "ietf-network-slice-service:one-way-delay-maximum"
+                    and metric_bound["metric-unit"] == "milliseconds"
+                ):
+                    cc_info[cc_key].delay = int(metric_bound["bound"])
+                elif (
+                    metric_bound["metric-type"]
+                    == "ietf-network-slice-service:two-way-packet-loss"
+                    and metric_bound["metric-unit"] == "percentage"
+                ):
+                    cc_info[cc_key].packet_loss = float(
+                        metric_bound["percentile-value"]
+                    )
+                elif (
+                    metric_bound["metric-type"]
+                    == "ietf-network-slice-service:one-way-bandwidth"
+                    and metric_bound["metric-unit"] == "Mbps"
+                ):
+                    cc_info[cc_key].bandwidth = int(metric_bound["bound"])
+    return cc_info
+
+
+def extract_source_destination_device_endpoint_info(
+    device_ep_pairs: list, connection_group: Dict, candidate_connection_groups: List
+) -> Tuple[DeviceEpInfo, DeviceEpInfo]:
+    """
+    Given device_ep_pairs, the relevant connection_group data, and all candidate
+    connection groups, figure out the final DeviceEpInfo for source and destination.
+    This includes computing the combined bandwidth, min delay, etc.
+    """
+    connectivity_construct = connection_group["connectivity-construct"][0]
+    sender_sdp = connectivity_construct["p2p-sender-sdp"]
+    receiver_sdp = connectivity_construct["p2p-receiver-sdp"]
+
+    # If the first pair is not the sender, we invert them
+    if sender_sdp == device_ep_pairs[0][4]:
+        ...
+    elif sender_sdp == device_ep_pairs[1][4]:
+        device_ep_pairs = device_ep_pairs[::-1]
+    else:
+        raise Exception("Sender SDP not found in device_ep_pairs")
+
+    # Gather info from candidate connection groups
+    cc_info = gather_connectivity_construct_info(candidate_connection_groups)
+
+    source_delay = int(1e6)
+    source_bandwidth = 0
+    source_packet_loss = 1.0
+    destination_delay = int(1e6)
+    destination_bandwidth = 0
+    destination_packet_loss = 1.0
+
+    if cc_info:
+        common_sdps = set.intersection(*[set(key) for key in cc_info.keys()])
+        if len(cc_info) > 2 and len(common_sdps) != 1:
+            raise Exception(
+                "There should be one common sdp in all connectivity constructs, otherwise, it is not supported"
+            )
+        if len(common_sdps) == 1:
+            common_sdp = common_sdps.pop()
+        elif len(common_sdps) == 2:
+            # Fallback if intersection is 2 => pick sender_sdp
+            common_sdp = sender_sdp
+        else:
+            raise Exception("Invalid number of common sdps")
+
+    for (sender, receiver), metrics in cc_info.items():
+        cc_bandwidth = metrics.bandwidth
+        cc_max_delay = metrics.delay
+        cc_packet_loss = metrics.packet_loss
+        if sender == common_sdp:
+            source_bandwidth += cc_bandwidth
+            if cc_max_delay < source_delay:
+                source_delay = cc_max_delay
+            if cc_packet_loss < source_packet_loss:
+                source_packet_loss = cc_packet_loss
+        else:
+            destination_bandwidth += cc_bandwidth
+            if cc_max_delay < destination_delay:
+                destination_delay = cc_max_delay
+            if cc_packet_loss < destination_packet_loss:
+                destination_packet_loss = cc_packet_loss
+
+    source_device_ep_info = DeviceEpInfo(
+        ipv4_info=device_ep_pairs[0][5],
+        node_name=device_ep_pairs[0][2],
+        endpoint_name=device_ep_pairs[0][3],
+        one_way_delay=source_delay,
+        one_way_bandwidth=source_bandwidth,
+        one_way_packet_loss=source_packet_loss,
+    )
+    destination_device_ep_info = DeviceEpInfo(
+        ipv4_info=device_ep_pairs[1][5],
+        node_name=device_ep_pairs[1][2],
+        endpoint_name=device_ep_pairs[1][3],
+        one_way_delay=destination_delay,
+        one_way_bandwidth=destination_bandwidth,
+        one_way_packet_loss=destination_packet_loss,
+    )
+
+    return source_device_ep_info, destination_device_ep_info
+
+
+def _parse_item_added(diff: Dict) -> dict:
+    """
+    Helper to parse 'iterable_item_added' from the running_candidate_diff
+    and return the relevant items for sdp, connection_group, match_criterion, etc.
+    """
+    added_items = {
+        "sdp": {"sdp_idx": None, "value": {}},
+        "connection_group": {"connection_group_idx": None, "value": {}},
+        "match_criterion": {
+            "sdp_idx": None,
+            "match_criterion_idx": None,
+            "value": {},
+        },
+    }
+    for added_key, added_value in diff["iterable_item_added"].items():
+        sdp_match = SDP_DIFF_RE.match(added_key)
+        connection_group_match = CONNECTION_GROUP_DIFF_RE.match(added_key)
+        match_criterion_match = MATCH_CRITERION_DIFF_RE.match(added_key)
+        if sdp_match:
+            added_items["sdp"] = {
+                "sdp_idx": int(sdp_match.groups()[0]),
+                "value": added_value,
+            }
+        elif connection_group_match:
+            added_items["connection_group"] = {
+                "connection_group_idx": int(connection_group_match.groups()[0]),
+                "value": added_value,
+            }
+        elif match_criterion_match:
+            added_items["match_criterion"] = {
+                "sdp_idx": int(match_criterion_match.groups()[0]),
+                "match_criterion_idx": int(match_criterion_match.groups()[1]),
+                "value": added_value,
+            }
+    return added_items
+
+
+class L3NMSliceIETFSliceServiceHandler(_ServiceHandler):
+    def __init__(  # pylint: disable=super-init-not-called
+        self, service: Service, task_executor: TaskExecutor, **settings
+    ) -> None:
+        self.__service = service
+        self.__task_executor = task_executor
+        self.__settings_handler = SettingsHandler(service.service_config, **settings)
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetEndpoint(
+        self,
+        endpoints: List[Tuple[str, str, Optional[str]]],
+        connection_uuid: Optional[str] = None,
+    ) -> List[Union[bool, Exception]]:
+        chk_type("endpoints", endpoints, list)
+        if len(endpoints) == 0:
+            return []
+
+        results = []
+        try:
+            service_config = self.__service.service_config
+
+            # 1. Identify source and destination devices
+            src_device_uuid, src_endpoint_uuid = get_device_endpoint_uuids(endpoints[0])
+            src_device_obj = self.__task_executor.get_device(
+                DeviceId(**json_device_id(src_device_uuid))
+            )
+            src_device_name = src_device_obj.name
+            src_controller = self.__task_executor.get_device_controller(src_device_obj)
+
+            dst_device_uuid, dst_endpoint_uuid = get_device_endpoint_uuids(
+                endpoints[-1]
+            )
+            dst_device_obj = self.__task_executor.get_device(
+                DeviceId(**json_device_id(dst_device_uuid))
+            )
+            dst_device_name = dst_device_obj.name
+            dst_controller = self.__task_executor.get_device_controller(dst_device_obj)
+
+            if (
+                src_controller.device_id.device_uuid.uuid
+                != dst_controller.device_id.device_uuid.uuid
+            ):
+                raise Exception("Different Src-Dst devices not supported by now")
+
+            controller = src_controller  # same device controller
+
+            # 2. Determine how the candidate & running resources differ
+            running_candidate_diff = get_running_candidate_ietf_slice_data_diff(
+                service_config
+            )
+            candidate_ietf_slice_cr = get_custom_config_rule(
+                service_config, CANDIDATE_RESOURCE_KEY
+            )
+            candidate_resource_value_dict = json.loads(
+                candidate_ietf_slice_cr.custom.resource_value
+            )
+            running_ietf_slice_cr = get_custom_config_rule(
+                service_config, RUNNING_RESOURCE_KEY
+            )
+            running_resource_value_dict = json.loads(
+                running_ietf_slice_cr.custom.resource_value
+            )
+            slice_name = running_resource_value_dict["network-slice-services"][
+                "slice-service"
+            ][0]["id"]
+
+            # 3. Retrieve the context links for matching endpoints
+            context_client = ContextClient()
+            links = context_client.ListLinks(Empty()).links
+
+            device_ep_pairs = []
+            sdp_ids = []
+            target_connection_group_id = None
+            operation_type = "update"  # default fallback
+
+            # 4. Handle creation vs additions vs removals
+            if not running_candidate_diff:  # Slice Creation
+                # 4a. New Slice Creation
+                operation_type = "create"
+
+                candidate_slice_service = candidate_resource_value_dict[
+                    "network-slice-services"
+                ]["slice-service"][0]
+                full_connection_groups = candidate_slice_service["connection-groups"][
+                    "connection-group"
+                ]
+                sdps = candidate_slice_service["sdps"]["sdp"]
+                sdp_ids = [sdp["node-id"] for sdp in sdps]
+
+                # figure out which device is connected to which link
+                edge_device_names = [src_device_name, dst_device_name]
+                for sdp in sdps:
+                    node_id = sdp["node-id"]
+                    for link in links:
+                        info = get_link_ep_device_names(link, context_client)
+                        dev1, ep1, _, dev2, ep2, _ = info
+                        if dev1 == node_id and dev2 in edge_device_names:
+                            edge_device_names.remove(dev2)
+                            match_criteria = sdp["service-match-criteria"][
+                                "match-criterion"
+                            ]
+                            if len(match_criteria) != 1:
+                                raise Exception(
+                                    "Only one match criteria allowed for initial slice creation"
+                                )
+                            match_criterion = match_criteria[0]
+                            ipv4_info = extract_match_criterion_ipv4_info(
+                                match_criterion
+                            )
+                            device_ep_pairs.append(
+                                (
+                                    node_id,
+                                    ep1,
+                                    dev2,
+                                    ep2,
+                                    sdp["id"],
+                                    ipv4_info,
+                                )
+                            )
+                            target_connection_group_id = match_criterion[
+                                "target-connection-group-id"
+                            ]
+                            sdp_ids.remove(node_id)
+                            break
+
+                # find the second link
+                if not edge_device_names:
+                    raise Exception("Edge device names exhausted unexpectedly.")
+
+                # second link logic
+                for link in links:
+                    info = get_link_ep_device_names(link, context_client)
+                    dev1, ep1, device_obj_1, dev2, ep2, device_obj_2 = info
+                    if (
+                        dev1 == edge_device_names[0]
+                        and device_obj_2.controller_id != device_obj_1.controller_id
+                    ):
+                        for sdp in sdps:
+                            if sdp["node-id"] != sdp_ids[0]:
+                                continue
+                            match_criteria = sdp["service-match-criteria"][
+                                "match-criterion"
+                            ]
+                            if len(match_criteria) != 1:
+                                raise Exception(
+                                    "Only one match criteria allowed for initial slice creation"
+                                )
+                            match_criterion = match_criteria[0]
+                            ipv4_info = extract_match_criterion_ipv4_info(
+                                match_criterion
+                            )
+                            device_ep_pairs.append(
+                                (
+                                    dev2,
+                                    ep2,
+                                    dev1,
+                                    ep1,
+                                    sdp["id"],
+                                    ipv4_info,
+                                )
+                            )
+                            break
+                        else:
+                            raise Exception("No matching sdp found for second link.")
+                        break
+                else:
+                    raise Exception("sdp between the domains not found")
+
+            elif "iterable_item_added" in running_candidate_diff:  # new SDP added
+                # 4b. A new SDP was added
+                operation_type = "update"
+
+                candidate_slice_service = candidate_resource_value_dict[
+                    "network-slice-services"
+                ]["slice-service"][0]
+                sdps = candidate_slice_service["sdps"]["sdp"]
+                full_connection_groups = candidate_slice_service["connection-groups"][
+                    "connection-group"
+                ]
+                added_items = _parse_item_added(running_candidate_diff)
+
+                new_sdp = sdps[added_items["sdp"]["sdp_idx"]]
+                src_sdp_name = new_sdp["node-id"]
+                dst_sdp_idx = sdps[added_items["match_criterion"]["sdp_idx"]]["id"]
+                dst_sdp_name = sdps[added_items["match_criterion"]["sdp_idx"]][
+                    "node-id"
+                ]
+                for link in links:
+                    info = get_link_ep_device_names(link, context_client)
+                    dev1, ep1, device_obj_1, dev2, ep2, device_obj_2 = info
+                    if (
+                        dev1 == src_sdp_name
+                        and device_obj_2.controller_id != device_obj_1.controller_id
+                    ):
+                        for sdp in sdps:
+                            if sdp["node-id"] != src_sdp_name:
+                                continue
+                            match_criteria = sdp["service-match-criteria"][
+                                "match-criterion"
+                            ]
+                            if len(match_criteria) != 1:
+                                raise Exception(
+                                    "Only one match criteria allowed for initial slice creation"
+                                )
+                            match_criterion = match_criteria[0]
+                            ipv4_info = extract_match_criterion_ipv4_info(
+                                match_criterion
+                            )
+                            device_ep_pairs.append(
+                                (
+                                    dev2,
+                                    ep2,
+                                    dev1,
+                                    ep1,
+                                    sdp["id"],
+                                    ipv4_info,
+                                )
+                            )
+                            target_connection_group_id = match_criterion[
+                                "target-connection-group-id"
+                            ]
+                        break
+                else:
+                    raise Exception("sdp between the domains not found")
+                for link in links:
+                    info = get_link_ep_device_names(link, context_client)
+                    dev1, ep1, device_obj_1, dev2, ep2, device_obj_2 = info
+                    if (
+                        dev1 == dst_sdp_name
+                        and device_obj_2.controller_id != device_obj_1.controller_id
+                    ):
+                        for sdp in sdps:
+                            if sdp["node-id"] != dst_sdp_name:
+                                continue
+                            match_criteria = sdp["service-match-criteria"][
+                                "match-criterion"
+                            ]
+                            vlan_id = set()
+                            for match in match_criteria:
+                                for type_value in match["match-type"]:
+                                    if (
+                                        type_value["type"]
+                                        == "ietf-network-slice-service:vlan"
+                                    ):
+                                        vlan_id.add(type_value["value"][0])
+                            if len(vlan_id) != 1:
+                                raise Exception(
+                                    "one vlan id found in SDP match criteria"
+                                )
+                            match_criterion = match_criteria[
+                                added_items["match_criterion"]["match_criterion_idx"]
+                            ]
+                            ipv4_info = extract_match_criterion_ipv4_info(
+                                match_criterion
+                            )
+                            device_ep_pairs.append(
+                                (
+                                    dev2,
+                                    ep2,
+                                    dev1,
+                                    ep1,
+                                    sdp["id"],
+                                    ipv4_info,
+                                )
+                            )
+                        break
+                else:
+                    raise Exception("sdp between the domains not found")
+            elif "iterable_item_removed" in running_candidate_diff:  # an SDP removed
+                # 4c. An existing SDP was removed
+                operation_type = "update"
+
+                slice_services = running_resource_value_dict["network-slice-services"][
+                    "slice-service"
+                ]
+                candidate_slice_services = candidate_resource_value_dict[
+                    "network-slice-services"
+                ]["slice-service"]
+                candidate_slice_service = candidate_slice_services[0]
+                slice_service = slice_services[0]
+                full_connection_groups = slice_service["connection-groups"][
+                    "connection-group"
+                ]
+                sdps = slice_service["sdps"]["sdp"]
+                removed_items = get_removed_items(
+                    candidate_resource_value_dict, running_resource_value_dict
+                )
+                new_sdp = sdps[removed_items["sdp"]["sdp_idx"]]
+                src_sdp_name = new_sdp["node-id"]
+                dst_sdp_idx = sdps[removed_items["match_criterion"]["sdp_idx"]]["id"]
+                dst_sdp_name = sdps[removed_items["match_criterion"]["sdp_idx"]][
+                    "node-id"
+                ]
+                for link in links:
+                    (
+                        device_obj_name_1,
+                        ep_name_1,
+                        device_obj_1,
+                        device_obj_name_2,
+                        ep_name_2,
+                        device_obj_2,
+                    ) = get_link_ep_device_names(link, context_client)
+                    if (
+                        device_obj_name_1 == src_sdp_name
+                        and device_obj_2.controller_id != device_obj_1.controller_id
+                    ):
+                        for sdp in sdps:
+                            if sdp["node-id"] != src_sdp_name:
+                                continue
+                            match_criteria = sdp["service-match-criteria"][
+                                "match-criterion"
+                            ]
+                            if len(match_criteria) != 1:
+                                raise Exception(
+                                    "Only one match criteria allowed for new SDP addition"
+                                )
+                            match_criterion = match_criteria[0]
+                            ipv4_info = extract_match_criterion_ipv4_info(
+                                match_criterion
+                            )
+                            device_ep_pairs.append(
+                                (
+                                    device_obj_name_2,
+                                    ep_name_2,
+                                    device_obj_name_1,
+                                    ep_name_1,
+                                    sdp["id"],
+                                    ipv4_info,
+                                )
+                            )
+                            target_connection_group_id = match_criterion[
+                                "target-connection-group-id"
+                            ]
+                        break
+                else:
+                    raise Exception("sdp between the domains not found")
+                for link in links:
+                    (
+                        device_obj_name_1,
+                        ep_name_1,
+                        device_obj_1,
+                        device_obj_name_2,
+                        ep_name_2,
+                        device_obj_2,
+                    ) = get_link_ep_device_names(link, context_client)
+                    if (
+                        device_obj_name_1 == dst_sdp_name
+                        and device_obj_2.controller_id != device_obj_1.controller_id
+                    ):
+                        for sdp in sdps:
+                            if sdp["node-id"] != dst_sdp_name:
+                                continue
+                            match_criteria = sdp["service-match-criteria"][
+                                "match-criterion"
+                            ]
+                            vlan_id = set()
+                            for match in match_criteria:
+                                for type_value in match["match-type"]:
+                                    if (
+                                        type_value["type"]
+                                        == "ietf-network-slice-service:vlan"
+                                    ):
+                                        vlan_id.add(type_value["value"][0])
+                            if len(vlan_id) != 1:
+                                raise Exception(
+                                    "one vlan id found in SDP match criteria"
+                                )
+                            match_criterion = match_criteria[
+                                removed_items["match_criterion"]["match_criterion_idx"]
+                            ]
+                            ipv4_info = extract_match_criterion_ipv4_info(
+                                match_criterion
+                            )
+                            device_ep_pairs.append(
+                                (
+                                    device_obj_name_2,
+                                    ep_name_2,
+                                    device_obj_name_1,
+                                    ep_name_1,
+                                    sdp["id"],
+                                    ipv4_info,
+                                )
+                            )
+                        break
+                else:
+                    raise Exception("sdp between the domains not found")
+            else:
+                raise Exception(
+                    "transition from candidate to running info not supported"
+                )
+
+            candidate_connection_groups = candidate_slice_service["connection-groups"][
+                "connection-group"
+            ]
+
+            if (
+                len(
+                    candidate_resource_value_dict["network-slice-services"][
+                        "slice-service"
+                    ][0]["connection-groups"]["connection-group"]
+                )
+                == 0
+            ):
+                # 5. If connection_groups is now empty => operation = delete
+                operation_type = "delete"
+
+            # 6. Retrieve actual target connection_group from the full connection groups
+            if not target_connection_group_id:
+                raise Exception("No target_connection_group_id found.")
+            target_connection_group = next(
+                cg
+                for cg in full_connection_groups
+                if cg["id"] == target_connection_group_id
+            )
+
+            # 7. Build source/destination device info
+            source_device_ep_info, destination_device_ep_info = (
+                extract_source_destination_device_endpoint_info(
+                    device_ep_pairs,
+                    target_connection_group,
+                    candidate_connection_groups,
+                )
+            )
+            resource_value_dict = {
+                "uuid": slice_name,
+                "operation_type": operation_type,
+                "src_node_id": source_device_ep_info["node_name"],
+                "src_mgmt_ip_address": source_device_ep_info["node_name"],
+                "src_ac_node_id": source_device_ep_info["node_name"],
+                "src_ac_ep_id": source_device_ep_info["endpoint_name"],
+                "src_vlan": source_device_ep_info["ipv4_info"]["vlan"],
+                "src_source_ip_prefix": source_device_ep_info["ipv4_info"]["src_lan"],
+                "src_source_tcp_port": source_device_ep_info["ipv4_info"]["src_port"],
+                "src_destination_ip_prefix": source_device_ep_info["ipv4_info"][
+                    "dst_lan"
+                ],
+                "src_destination_tcp_port": source_device_ep_info["ipv4_info"][
+                    "dst_port"
+                ],
+                "source_one_way_delay": source_device_ep_info["one_way_delay"],
+                "source_one_way_bandwidth": source_device_ep_info["one_way_bandwidth"],
+                "source_one_way_packet_loss": source_device_ep_info[
+                    "one_way_packet_loss"
+                ],
+                "dst_node_id": destination_device_ep_info["node_name"],
+                "dst_mgmt_ip_address": destination_device_ep_info["node_name"],
+                "dst_ac_node_id": destination_device_ep_info["node_name"],
+                "dst_ac_ep_id": destination_device_ep_info["endpoint_name"],
+                "dst_vlan": destination_device_ep_info["ipv4_info"]["vlan"],
+                "dst_source_ip_prefix": destination_device_ep_info["ipv4_info"][
+                    "src_lan"
+                ],
+                "dst_source_tcp_port": destination_device_ep_info["ipv4_info"][
+                    "src_port"
+                ],
+                "dst_destination_ip_prefix": destination_device_ep_info["ipv4_info"][
+                    "dst_lan"
+                ],
+                "dst_destination_tcp_port": destination_device_ep_info["ipv4_info"][
+                    "dst_port"
+                ],
+                "destination_one_way_delay": destination_device_ep_info[
+                    "one_way_delay"
+                ],
+                "destination_one_way_bandwidth": destination_device_ep_info[
+                    "one_way_bandwidth"
+                ],
+                "destination_one_way_packet_loss": destination_device_ep_info[
+                    "one_way_packet_loss"
+                ],
+                "slice_id": slice_name,
+            }
+
+            # 9. Create config rules and configure device
+            json_config_rules = setup_config_rules(slice_name, resource_value_dict)
+            del controller.device_config.config_rules[:]
+            for jcr in json_config_rules:
+                controller.device_config.config_rules.append(ConfigRule(**jcr))
+
+            self.__task_executor.configure_device(controller)
+        except Exception as e:  # pylint: disable=broad-except
+            raise e
+            results.append(e)
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def DeleteEndpoint(
+        self,
+        endpoints: List[Tuple[str, str, Optional[str]]],
+        connection_uuid: Optional[str] = None,
+    ) -> List[Union[bool, Exception]]:
+        chk_type("endpoints", endpoints, list)
+        if len(endpoints) == 0:
+            return []
+        service_uuid = self.__service.service_id.service_uuid.uuid
+        results = []
+        try:
+            src_device_uuid, src_endpoint_uuid = get_device_endpoint_uuids(endpoints[0])
+            src_device_obj = self.__task_executor.get_device(
+                DeviceId(**json_device_id(src_device_uuid))
+            )
+            controller = self.__task_executor.get_device_controller(src_device_obj)
+            json_config_rules = teardown_config_rules(service_uuid, {})
+            if len(json_config_rules) > 0:
+                del controller.device_config.config_rules[:]
+                for json_config_rule in json_config_rules:
+                    controller.device_config.config_rules.append(
+                        ConfigRule(**json_config_rule)
+                    )
+                self.__task_executor.configure_device(controller)
+            results.append(True)
+        except Exception as e:  # pylint: disable=broad-except
+            results.append(e)
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetConstraint(
+        self, constraints: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        chk_type("constraints", constraints, list)
+        if len(constraints) == 0:
+            return []
+
+        msg = "[SetConstraint] Method not implemented. Constraints({:s}) are being ignored."
+        LOGGER.warning(msg.format(str(constraints)))
+        return [True for _ in range(len(constraints))]
+
+    @metered_subclass_method(METRICS_POOL)
+    def DeleteConstraint(
+        self, constraints: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        chk_type("constraints", constraints, list)
+        if len(constraints) == 0:
+            return []
+
+        msg = "[DeleteConstraint] Method not implemented. Constraints({:s}) are being ignored."
+        LOGGER.warning(msg.format(str(constraints)))
+        return [True for _ in range(len(constraints))]
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetConfig(
+        self, resources: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        chk_type("resources", resources, list)
+        if len(resources) == 0:
+            return []
+
+        results = []
+        for resource in resources:
+            try:
+                resource_value = json.loads(resource[1])
+                self.__settings_handler.set(resource[0], resource_value)
+                results.append(True)
+            except Exception as e:  # pylint: disable=broad-except
+                LOGGER.exception("Unable to SetConfig({:s})".format(str(resource)))
+                results.append(e)
+
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def DeleteConfig(
+        self, resources: List[Tuple[str, Any]]
+    ) -> List[Union[bool, Exception]]:
+        chk_type("resources", resources, list)
+        if len(resources) == 0:
+            return []
+
+        results = []
+        for resource in resources:
+            try:
+                self.__settings_handler.delete(resource[0])
+            except Exception as e:  # pylint: disable=broad-except
+                LOGGER.exception("Unable to DeleteConfig({:s})".format(str(resource)))
+                results.append(e)
+
+        return results
diff --git a/src/service/service/service_handlers/l3slice_ietfslice/__init__.py b/src/service/service/service_handlers/l3slice_ietfslice/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ccc21c7db78aac26daa1f8c5ff8e1ffd3f35460
--- /dev/null
+++ b/src/service/service/service_handlers/l3slice_ietfslice/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/service/service/task_scheduler/TaskExecutor.py b/src/service/service/task_scheduler/TaskExecutor.py
index 6fb1eca3497fef311605e2cd202ca74bd9cb730f..51fc42a5a5ea06d5abaa49946a154d0c38f6de8b 100644
--- a/src/service/service/task_scheduler/TaskExecutor.py
+++ b/src/service/service/task_scheduler/TaskExecutor.py
@@ -287,8 +287,12 @@ class TaskExecutor:
                 devices.setdefault(device_type, dict())[device_uuid] = device
             else:
                 if not exclude_managed_by_controller:
-                    device_type = DeviceTypeEnum._value2member_map_[device.device_type]
-                    devices.setdefault(device_type, dict())[device_uuid] = device
+                    controller_device_type_enum = DeviceTypeEnum._value2member_map_[controller.device_type]
+                    if controller_device_type_enum == DeviceTypeEnum.IETF_SLICE:
+                        devices.setdefault(controller_device_type_enum, dict())[device_uuid] = device
+                    else:
+                        device_type = DeviceTypeEnum._value2member_map_[device.device_type]
+                        devices.setdefault(device_type, dict())[device_uuid] = device
                 device_type = DeviceTypeEnum._value2member_map_[controller.device_type]
                 devices.setdefault(device_type, dict())[controller.device_id.device_uuid.uuid] = controller
         return devices
@@ -321,7 +325,7 @@ class TaskExecutor:
         self, connection : Connection, service : Service, **service_handler_settings
     ) -> Dict[DeviceTypeEnum, Tuple['_ServiceHandler', Dict[str, Device]]]:
         connection_device_types : Dict[DeviceTypeEnum, Dict[str, Device]] = self.get_devices_from_connection(
-            connection, exclude_managed_by_controller=True
+            connection, exclude_managed_by_controller=False
         )
         service_handlers : Dict[DeviceTypeEnum, Tuple['_ServiceHandler', Dict[str, Device]]] = dict()
         for device_type, connection_devices in connection_device_types.items():
diff --git a/src/slice/service/SliceServiceServicerImpl.py b/src/slice/service/SliceServiceServicerImpl.py
index 007d012ed432a6d4ab589f6dfe28648a9a6d2a85..68bd0aef153d2b784605abfe03b891b6990d23d5 100644
--- a/src/slice/service/SliceServiceServicerImpl.py
+++ b/src/slice/service/SliceServiceServicerImpl.py
@@ -19,7 +19,7 @@ from common.proto.context_pb2 import (
 from common.proto.slice_pb2_grpc import SliceServiceServicer
 from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method
 from common.tools.context_queries.InterDomain import is_inter_domain #, is_multi_domain
-from common.tools.context_queries.Slice import get_slice_by_id
+from common.tools.context_queries.Slice import get_slice_by_defualt_id, get_slice_by_id
 from common.tools.grpc.ConfigRules import copy_config_rules
 from common.tools.grpc.Constraints import copy_constraints
 from common.tools.grpc.EndPointIds import copy_endpoint_ids
@@ -45,6 +45,8 @@ class SliceServiceServicerImpl(SliceServiceServicer):
         # being modified.
         context_client = ContextClient()
         slice_ro : Optional[Slice] = get_slice_by_id(context_client, request.slice_id, rw_copy=False)
+        if not slice_ro:
+            slice_ro : Optional[Slice] = get_slice_by_defualt_id(context_client, request.slice_id, rw_copy=False)
 
         slice_rw = Slice()
         slice_rw.CopyFrom(request if slice_ro is None else slice_ro)
@@ -52,9 +54,9 @@ class SliceServiceServicerImpl(SliceServiceServicer):
         slice_rw.slice_owner.CopyFrom(request.slice_owner)                          # pylint: disable=no-member
         slice_rw.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED    # pylint: disable=no-member
 
-        copy_endpoint_ids(request.slice_endpoint_ids,        slice_rw.slice_endpoint_ids       ) # pylint: disable=no-member
-        copy_constraints (request.slice_constraints,         slice_rw.slice_constraints        ) # pylint: disable=no-member
-        copy_config_rules(request.slice_config.config_rules, slice_rw.slice_config.config_rules) # pylint: disable=no-member
+        copy_endpoint_ids(request.slice_endpoint_ids,        slice_rw.slice_endpoint_ids       )        # pylint: disable=no-member
+        copy_constraints (request.slice_constraints,         slice_rw.slice_constraints        )        # pylint: disable=no-member
+        copy_config_rules(request.slice_config.config_rules, slice_rw.slice_config.config_rules, False) # pylint: disable=no-member
 
         slice_id_with_uuids = context_client.SetSlice(slice_rw)
 
@@ -112,7 +114,7 @@ class SliceServiceServicerImpl(SliceServiceServicer):
         # pylint: disable=no-member
         copy_endpoint_ids(request.slice_endpoint_ids, service_request.service_endpoint_ids)
         copy_constraints(request.slice_constraints, service_request.service_constraints)
-        copy_config_rules(request.slice_config.config_rules, service_request.service_config.config_rules)
+        copy_config_rules(request.slice_config.config_rules, service_request.service_config.config_rules, False)
 
         service_request.service_type = ServiceTypeEnum.SERVICETYPE_UNKNOWN
         for config_rule in request.slice_config.config_rules:
diff --git a/src/tests/.gitlab-ci.yml b/src/tests/.gitlab-ci.yml
index fdc86805ba4824f64844a9b4bc78c3e27b606945..b49d40c1142522ab0fb3fa1936395f2aadc80baf 100644
--- a/src/tests/.gitlab-ci.yml
+++ b/src/tests/.gitlab-ci.yml
@@ -21,4 +21,6 @@ include:
   #- local: '/src/tests/ofc23/.gitlab-ci.yml'
   - local: '/src/tests/ofc24/.gitlab-ci.yml'
   - local: '/src/tests/eucnc24/.gitlab-ci.yml'
+  - local: '/src/tests/ofc25-camara-agg-net-controller/.gitlab-ci.yml'
+  - local: '/src/tests/ofc25-camara-e2e-controller/.gitlab-ci.yml'
   #- local: '/src/tests/ecoc24/.gitlab-ci.yml'
diff --git a/src/tests/eucnc24/.gitlab-ci.yml b/src/tests/eucnc24/.gitlab-ci.yml
index 02c4cced3981f4c12042e636652dca95c384a169..1ae05f27469220711344728429c135858e3a345e 100644
--- a/src/tests/eucnc24/.gitlab-ci.yml
+++ b/src/tests/eucnc24/.gitlab-ci.yml
@@ -46,7 +46,7 @@ end2end_test eucnc24:
   before_script:
     - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
     - docker rm -f ${TEST_NAME} || true
-    - sudo containerlab destroy --all --cleanup || true
+    - containerlab destroy --all --cleanup || true
 
   script:
     # Download Docker image to run the test
@@ -63,7 +63,7 @@ end2end_test eucnc24:
     - cp -R src/tests/${TEST_NAME}/clab/* /tmp/clab/${TEST_NAME}
     - tree -la /tmp/clab/${TEST_NAME}
     - cd /tmp/clab/${TEST_NAME}
-    - sudo containerlab deploy --reconfigure --topo eucnc24.clab.yml
+    - containerlab deploy --reconfigure --topo eucnc24.clab.yml
     - cd $RUNNER_PATH
 
     # Wait for initialization of Device NOSes
@@ -71,9 +71,9 @@ end2end_test eucnc24:
     - docker ps -a
 
     # Dump configuration of the routers (before any configuration)
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
 
     # Configure TeraFlowSDN deployment
     # Uncomment if DEBUG log level is needed for the components
@@ -132,27 +132,27 @@ end2end_test eucnc24:
       $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-service-tfs-create.sh
 
     # Dump configuration of the routers (after configure TFS service)
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
 
     # Run end-to-end test: test connectivity with ping
-    - export TEST1_10=$(sudo containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.1.10' --format json)
+    - export TEST1_10=$(containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.1.10' --format json)
     - echo $TEST1_10
     - echo $TEST1_10 | grep -E '3 packets transmitted, 3 received, 0\% packet loss'
-    - export TEST1_1=$(sudo containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.1.1' --format json)
+    - export TEST1_1=$(containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.1.1' --format json)
     - echo $TEST1_1
     - echo $TEST1_1 | grep -E '3 packets transmitted, 3 received, 0\% packet loss'
-    - export TEST2_1=$(sudo containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.2.1' --format json)
+    - export TEST2_1=$(containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.2.1' --format json)
     - echo $TEST2_1
     - echo $TEST2_1 | grep -E '3 packets transmitted, 3 received, 0\% packet loss'
-    - export TEST2_10=$(sudo containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.2.10' --format json)
+    - export TEST2_10=$(containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.2.10' --format json)
     - echo $TEST2_10
     - echo $TEST2_10 | grep -E '3 packets transmitted, 3 received, 0\% packet loss'
-    - export TEST3_1=$(sudo containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.3.1' --format json)
+    - export TEST3_1=$(containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.3.1' --format json)
     - echo $TEST3_1
     - echo $TEST3_1 | grep -E '3 packets transmitted, 0 received, 100\% packet loss'
-    - export TEST3_10=$(sudo containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.3.10' --format json)
+    - export TEST3_10=$(containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.3.10' --format json)
     - echo $TEST3_10
     - echo $TEST3_10 | grep -E '3 packets transmitted, 0 received, 100\% packet loss'
 
@@ -164,9 +164,9 @@ end2end_test eucnc24:
       $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-service-tfs-remove.sh
 
     # Dump configuration of the routers (after deconfigure TFS service)
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
 
     # Run end-to-end test: configure service IETF
     - >
@@ -176,27 +176,27 @@ end2end_test eucnc24:
       $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-service-ietf-create.sh
 
     # Dump configuration of the routers (after configure IETF service)
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
 
     # Run end-to-end test: test connectivity with ping
-    - export TEST1_10=$(sudo containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.1.10' --format json)
+    - export TEST1_10=$(containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.1.10' --format json)
     - echo $TEST1_10
     - echo $TEST1_10 | grep -E '3 packets transmitted, 3 received, 0\% packet loss'
-    - export TEST1_1=$(sudo containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.1.1' --format json)
+    - export TEST1_1=$(containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.1.1' --format json)
     - echo $TEST1_1
     - echo $TEST1_1 | grep -E '3 packets transmitted, 3 received, 0\% packet loss'
-    - export TEST2_1=$(sudo containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.2.1' --format json)
+    - export TEST2_1=$(containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.2.1' --format json)
     - echo $TEST2_1
     - echo $TEST2_1 | grep -E '3 packets transmitted, 3 received, 0\% packet loss'
-    - export TEST2_10=$(sudo containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.2.10' --format json)
+    - export TEST2_10=$(containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.2.10' --format json)
     - echo $TEST2_10
     - echo $TEST2_10 | grep -E '3 packets transmitted, 3 received, 0\% packet loss'
-    - export TEST3_1=$(sudo containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.3.1' --format json)
+    - export TEST3_1=$(containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.3.1' --format json)
     - echo $TEST3_1
     - echo $TEST3_1 | grep -E '3 packets transmitted, 0 received, 100\% packet loss'
-    - export TEST3_10=$(sudo containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.3.10' --format json)
+    - export TEST3_10=$(containerlab exec --name eucnc24 --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.3.10' --format json)
     - echo $TEST3_10
     - echo $TEST3_10 | grep -E '3 packets transmitted, 0 received, 100\% packet loss'
 
@@ -208,9 +208,9 @@ end2end_test eucnc24:
       $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-service-ietf-remove.sh
 
     # Dump configuration of the routers (after deconfigure IETF service)
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
 
     # Run end-to-end test: cleanup scenario
     - >
@@ -221,9 +221,9 @@ end2end_test eucnc24:
 
   after_script:
     # Dump configuration of the routers (on after_script)
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
-    - sudo containerlab exec --name eucnc24 --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
+    - containerlab exec --name eucnc24 --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\""
 
     # Dump TeraFlowSDN component logs
     - source src/tests/${TEST_NAME}/deploy_specs.sh
@@ -239,7 +239,7 @@ end2end_test eucnc24:
     - RUNNER_PATH=`pwd`
     #- cd $PWD/src/tests/${TEST_NAME}
     - cd /tmp/clab/${TEST_NAME}
-    - sudo containerlab destroy --topo eucnc24.clab.yml --cleanup || true
+    - containerlab destroy --topo eucnc24.clab.yml --cleanup || true
     - sudo rm -rf clab-eucnc24/ .eucnc24.clab.yml.bak || true
     - cd $RUNNER_PATH
     - kubectl delete namespaces tfs || true
diff --git a/src/tests/ofc25-camara-agg-net-controller/.gitignore b/src/tests/ofc25-camara-agg-net-controller/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..24a4b233365e23a9462f4b64e8b60fef6a62bee4
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/.gitignore
@@ -0,0 +1,5 @@
+clab-*/
+images/
+*.clab.yml.bak
+*.tar
+*.tar.gz
diff --git a/src/tests/ofc25-camara-agg-net-controller/.gitlab-ci.yml b/src/tests/ofc25-camara-agg-net-controller/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f69c37b38a5a4414c2d75f816ed12035cbb0d53c
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/.gitlab-ci.yml
@@ -0,0 +1,90 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Deploy TeraFlowSDN and Execute end-2-end test
+end2end_test ofc25_camara_agg_net:
+  variables:
+    TEST_NAME: 'ofc25-camara-agg-net-controller'
+    IP_NAME: 'ip'
+    IP_PORT: '9092'
+  stage: end2end_test
+  # Disable to force running it after all other tasks
+  before_script:
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+    - HOST_IP=$(kubectl get nodes -o json | jq -r '.items[].status.addresses[] | select(.type=="InternalIP") | .address')
+    - sed -i "s/IP_NET_IP/${HOST_IP}/g" src/tests/${TEST_NAME}/data/agg-net-descriptor.json
+    - sed -i "s/IP_NET_PORT/${IP_PORT}/g" src/tests/${TEST_NAME}/data/agg-net-descriptor.json
+    - docker buildx build -t "${TEST_NAME}:latest" -f ./src/tests/${TEST_NAME}/Dockerfile .
+    - docker buildx build -t "${IP_NAME}:latest" -f ./src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/Dockerfile ./src/tests/tools/mock_ietf_l3vpn_sdn_ctrl
+    - docker rm -f ${TEST_NAME} || true
+    - docker rm -f ${IP_NAME} || true
+    - docker run -d --name ${IP_NAME} -p ${IP_PORT}:8443 ${IP_NAME}:latest
+
+  script:
+    # Check MicroK8s is ready
+    - microk8s status --wait-ready
+    - kubectl get pods --all-namespaces
+
+    - source src/tests/${TEST_NAME}/deploy_specs.sh
+
+    # Deploy TeraFlowSDN
+    - ./deploy/crdb.sh
+    - ./deploy/nats.sh
+    - ./deploy/qdb.sh
+    - ./deploy/kafka.sh
+    - ./deploy/tfs.sh
+    - ./deploy/show.sh
+
+    - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server
+
+    # Run end-to-end test: onboard scenario
+    - >
+      docker run -t --rm --name ${TEST_NAME} --network=host
+      --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh"
+      --volume "$PWD/src/tests/${TEST_NAME}:/opt/results"
+      ${TEST_NAME}:latest /var/teraflow/run-onboarding.sh
+
+    # Run end-to-end test: configure service TFS
+    - >
+      docker run -t --rm --name ${TEST_NAME} --network=host
+      --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh"
+      --volume "$PWD/src/tests/${TEST_NAME}:/opt/results"
+      ${TEST_NAME}:latest /var/teraflow/run-agg-net-ietf-slice-operations.sh
+
+  after_script:
+    - kubectl --namespace tfs logs deployment/contextservice -c server
+    - kubectl --namespace tfs logs deployment/deviceservice -c server
+    - kubectl --namespace tfs logs deployment/pathcompservice -c frontend
+    - kubectl --namespace tfs logs deployment/serviceservice -c server
+    - kubectl --namespace tfs logs deployment/sliceservice -c server
+    - kubectl --namespace tfs logs deployment/nbiservice -c server
+    - docker logs ${IP_NAME}
+
+    # Destroy Scenario
+    - kubectl delete namespaces tfs || true
+
+    - docker rm -f ${TEST_NAME} || true
+    - docker rm -f ${IP_NAME} || true
+
+    # Clean old docker images
+    - docker images --filter="dangling=true" --quiet | xargs -r docker rmi
+
+  #coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
+    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"'
+  artifacts:
+      when: always
+      reports:
+        junit: ./src/tests/${TEST_NAME}/report_*.xml
diff --git a/src/tests/ofc25-camara-agg-net-controller/Dockerfile b/src/tests/ofc25-camara-agg-net-controller/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..36ab9d366bd186f4ac0ade9f9dcea21f0a2a46e8
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/Dockerfile
@@ -0,0 +1,84 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+FROM python:3.9-slim
+
+# Install dependencies
+RUN apt-get --yes --quiet --quiet update && \
+    apt-get --yes --quiet --quiet install wget g++ git && \
+    rm -rf /var/lib/apt/lists/*
+
+# Set Python to show logs as they occur
+ENV PYTHONUNBUFFERED=0
+
+# Get generic Python packages
+RUN python3 -m pip install --upgrade pip
+RUN python3 -m pip install --upgrade setuptools wheel
+RUN python3 -m pip install --upgrade pip-tools
+
+# Get common Python packages
+# Note: this step enables sharing the previous Docker build steps among all the Python components
+WORKDIR /var/teraflow
+COPY common_requirements.in common_requirements.in
+RUN pip-compile --quiet --output-file=common_requirements.txt common_requirements.in
+RUN python3 -m pip install -r common_requirements.txt
+
+# Add common files into working directory
+WORKDIR /var/teraflow/common
+COPY src/common/. ./
+RUN rm -rf proto
+
+# Create proto sub-folder, copy .proto files, and generate Python code
+RUN mkdir -p /var/teraflow/common/proto
+WORKDIR /var/teraflow/common/proto
+RUN touch __init__.py
+COPY proto/*.proto ./
+RUN python3 -m grpc_tools.protoc -I=. --python_out=. --grpc_python_out=. *.proto
+RUN rm *.proto
+RUN find . -type f -exec sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' {} \;
+
+# Create component sub-folders, get specific Python packages
+RUN mkdir -p /var/teraflow/tests/ofc25-camara-agg-net-controller
+WORKDIR /var/teraflow/tests/ofc25-camara-agg-net-controller
+COPY src/tests/ofc25-camara-agg-net-controller/requirements.in requirements.in
+RUN pip-compile --quiet --output-file=requirements.txt requirements.in
+RUN python3 -m pip install -r requirements.txt
+
+# Add component files into working directory
+WORKDIR /var/teraflow
+COPY src/__init__.py ./__init__.py
+COPY src/common/*.py ./common/
+COPY src/common/tests/. ./common/tests/
+COPY src/common/tools/. ./common/tools/
+COPY src/context/__init__.py context/__init__.py
+COPY src/context/client/. context/client/
+COPY src/device/__init__.py device/__init__.py
+COPY src/device/client/. device/client/
+COPY src/monitoring/__init__.py monitoring/__init__.py
+COPY src/monitoring/client/. monitoring/client/
+COPY src/service/__init__.py service/__init__.py
+COPY src/service/client/. service/client/
+COPY src/slice/__init__.py slice/__init__.py
+COPY src/slice/client/. slice/client/
+COPY src/tests/*.py ./tests/
+COPY src/tests/ofc25-camara-agg-net-controller/__init__.py ./tests/ofc25-camara-agg-net-controller/__init__.py
+COPY src/tests/ofc25-camara-agg-net-controller/data/. ./tests/ofc25-camara-agg-net-controller/data/
+COPY src/tests/ofc25-camara-agg-net-controller/tests/. ./tests/ofc25-camara-agg-net-controller/tests/
+COPY src/tests/ofc25-camara-agg-net-controller/scripts/. ./
+
+RUN apt-get --yes --quiet --quiet update && \
+    apt-get --yes --quiet --quiet install tree && \
+    rm -rf /var/lib/apt/lists/*
+
+RUN tree -la /var/teraflow
diff --git a/src/tests/ofc25-camara-agg-net-controller/__init__.py b/src/tests/ofc25-camara-agg-net-controller/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ccc21c7db78aac26daa1f8c5ff8e1ffd3f35460
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/tests/ofc25-camara-agg-net-controller/data/agg-net-descriptor.json b/src/tests/ofc25-camara-agg-net-controller/data/agg-net-descriptor.json
new file mode 100644
index 0000000000000000000000000000000000000000..5e0e612ddb4206974bb7b8b9d37f62365ade0dfa
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/data/agg-net-descriptor.json
@@ -0,0 +1,858 @@
+{
+    "contexts": [
+        {
+            "context_id": {
+                "context_uuid": {
+                    "uuid": "admin"
+                }
+            }
+        }
+    ],
+    "topologies": [
+        {
+            "topology_id": {
+                "context_id": {
+                    "context_uuid": {
+                        "uuid": "admin"
+                    }
+                },
+                "topology_uuid": {
+                    "uuid": "admin"
+                }
+            }
+        }
+    ],
+    "devices": [
+        {
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "ip-net-controller"
+                }
+            },
+            "name": "ip-net-controller",
+            "device_type": "ip-sdn-controller",
+            "device_operational_status": 1,
+            "device_drivers": [
+                13
+            ],
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "IP_NET_IP"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "IP_NET_PORT"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [
+                                    {
+                                        "uuid": "mgmt",
+                                        "name": "mgmt",
+                                        "type": "mgmt"
+                                    }
+                                ],
+                                "scheme": "http",
+                                "username": "admin",
+                                "password": "admin",
+                                "base_url": "/restconf/v2/data",
+                                "timeout": 120,
+                                "verify": false
+                            }
+                        }
+                    }
+                ]
+            },
+            "device_endpoints": []
+        },
+        {
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "172.16.182.25"
+                }
+            },
+            "name": "172.16.182.25",
+            "device_type": "emu-packet-router",
+            "controller_id": {
+                "device_uuid": {
+                    "uuid": "ip-net-controller"
+                }
+            },
+            "device_operational_status": 1,
+            "device_drivers": [
+                13
+            ],
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [
+                                    {
+                                        "uuid": "mgmt",
+                                        "name": "mgmt",
+                                        "type": "mgmt"
+                                    },
+                                    {
+                                        "uuid": "200",
+                                        "name": "200",
+                                        "type": "optical",
+                                        "address_ip": "128.32.33.254",
+                                        "address_prefix": "24",
+                                        "site_location": "access"
+                                    },
+                                    {
+                                        "uuid": "500",
+                                        "name": "500",
+                                        "type": "optical"
+                                    },
+                                    {
+                                        "uuid": "501",
+                                        "name": "501",
+                                        "type": "optical"
+                                    }
+                                ]
+                            }
+                        }
+                    }
+                ]
+            }
+        },
+        {
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "172.16.185.31"
+                }
+            },
+            "name": "172.16.185.31",
+            "device_type": "emu-packet-router",
+            "controller_id": {
+                "device_uuid": {
+                    "uuid": "ip-net-controller"
+                }
+            },
+            "device_operational_status": 1,
+            "device_drivers": [
+                13
+            ],
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [
+                                    {
+                                        "uuid": "mgmt",
+                                        "name": "mgmt",
+                                        "type": "mgmt"
+                                    },
+                                    {
+                                        "uuid": "500",
+                                        "name": "500",
+                                        "type": "optical"
+                                    },
+                                    {
+                                        "uuid": "501",
+                                        "name": "501",
+                                        "type": "optical"
+                                    }
+                                ]
+                            }
+                        }
+                    }
+                ]
+            }
+        },
+        {
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "172.16.185.33"
+                }
+            },
+            "name": "172.16.185.33",
+            "device_type": "emu-packet-router",
+            "controller_id": {
+                "device_uuid": {
+                    "uuid": "ip-net-controller"
+                }
+            },
+            "device_operational_status": 1,
+            "device_drivers": [
+                13
+            ],
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [
+                                    {
+                                        "uuid": "mgmt",
+                                        "name": "mgmt",
+                                        "type": "mgmt"
+                                    },
+                                    {
+                                        "uuid": "500",
+                                        "name": "500",
+                                        "type": "optical"
+                                    },
+                                    {
+                                        "uuid": "501",
+                                        "name": "501",
+                                        "type": "optical"
+                                    }
+                                ]
+                            }
+                        }
+                    }
+                ]
+            }
+        },
+        {
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "172.16.185.32"
+                }
+            },
+            "name": "172.16.185.32",
+            "device_type": "emu-packet-router",
+            "controller_id": {
+                "device_uuid": {
+                    "uuid": "ip-net-controller"
+                }
+            },
+            "device_operational_status": 1,
+            "device_drivers": [
+                13
+            ],
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [
+                                    {
+                                        "uuid": "mgmt",
+                                        "name": "mgmt",
+                                        "type": "mgmt"
+                                    },
+                                    {
+                                        "uuid": "200",
+                                        "name": "200",
+                                        "type": "optical",
+                                        "address_ip": "172.10.33.254",
+                                        "address_prefix": "24",
+                                        "site_location": "cloud"
+                                    },
+                                    {
+                                        "uuid": "500",
+                                        "name": "500",
+                                        "type": "optical"
+                                    },
+                                    {
+                                        "uuid": "501",
+                                        "name": "501",
+                                        "type": "optical"
+                                    }
+                                ]
+                            }
+                        }
+                    }
+                ]
+            }
+        },
+        {
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "172.16.204.220"
+                }
+            },
+            "device_type": "emu-datacenter",
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_operational_status": 1,
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [
+                                    {
+                                        "sample_types": [],
+                                        "type": "optical",
+                                        "uuid": "500"
+                                    },
+                                    {
+                                        "sample_types": [],
+                                        "type": "optical",
+                                        "uuid": "200"
+                                    },
+                                    {
+                                        "sample_types": [],
+                                        "type": "optical",
+                                        "uuid": "201"
+                                    }
+                                ]
+                            }
+                        }
+                    }
+                ]
+            }
+        }
+    ],
+    "links": [
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "ip-net-controller/mgmt==172.16.182.25/mgmt"
+                }
+            },
+            "name": "ip-net-controller/mgmt==172.16.182.25/mgmt",
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "ip-net-controller"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "mgmt"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.182.25"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "mgmt"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "ip-net-controller/mgmt==172.16.185.31/mgmt"
+                }
+            },
+            "name": "ip-net-controller/mgmt==172.16.185.31/mgmt",
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "ip-net-controller"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "mgmt"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.31"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "mgmt"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "ip-net-controller/mgmt==172.16.185.33/mgmt"
+                }
+            },
+            "name": "ip-net-controller/mgmt==172.16.185.33/mgmt",
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "ip-net-controller"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "mgmt"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.33"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "mgmt"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "ip-net-controller/mgmt==172.16.185.32/mgmt"
+                }
+            },
+            "name": "ip-net-controller/mgmt==172.16.185.32/mgmt",
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "ip-net-controller"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "mgmt"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "mgmt"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.182.25-500"
+                }
+            },
+            "name": "172.16.182.25-500",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.182.25"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.33"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.33-500"
+                }
+            },
+            "name": "172.16.185.33-500",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.33"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.182.25"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.182.25-501"
+                }
+            },
+            "name": "172.16.182.25-501",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.182.25"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.31"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.31-501"
+                }
+            },
+            "name": "172.16.185.31-501",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.31"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.182.25"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.31-500"
+                }
+            },
+            "name": "172.16.185.31-500",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.31"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.32-500"
+                }
+            },
+            "name": "172.16.185.32-500",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.31"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.33-501"
+                }
+            },
+            "name": "172.16.185.33-501",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.33"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.32-501"
+                }
+            },
+            "name": "172.16.185.32-501",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.33"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "501"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.185.32-200"
+                }
+            },
+            "name": "172.16.185.32-200",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "200"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.204.220"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                }
+            ]
+        },
+        {
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "172.16.204.220-500"
+                }
+            },
+            "name": "172.16.204.220-500",
+            "attributes": {
+                "total_capacity_gbps": 10,
+                "used_capacity_gbps": 0
+            },
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.204.220"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "500"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "172.16.185.32"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "200"
+                    }
+                }
+            ]
+        }
+    ]
+}
diff --git a/src/tests/ofc25-camara-agg-net-controller/data/pc1_slice1_post_ietf_network_slice.json b/src/tests/ofc25-camara-agg-net-controller/data/pc1_slice1_post_ietf_network_slice.json
new file mode 100644
index 0000000000000000000000000000000000000000..ac1f09dd838d60ab42c64e134203f398179874e7
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/data/pc1_slice1_post_ietf_network_slice.json
@@ -0,0 +1,190 @@
+{
+  "network-slice-services": {
+    "slice-service": [
+      {
+        "connection-groups": {
+          "connection-group": [
+            {
+              "connectivity-construct": [
+                {
+                  "id": 1,
+                  "p2p-receiver-sdp": "2",
+                  "p2p-sender-sdp": "1",
+                  "service-slo-sle-policy": {
+                    "slo-policy": {
+                      "metric-bound": [
+                        {
+                          "bound": 10,
+                          "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                          "metric-unit": "milliseconds"
+                        },
+                        {
+                          "bound": 5000,
+                          "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                          "metric-unit": "Mbps"
+                        },
+                        {
+                          "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                          "metric-unit": "percentage",
+                          "percentile-value": 0.001
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "id": 2,
+                  "p2p-receiver-sdp": "1",
+                  "p2p-sender-sdp": "2",
+                  "service-slo-sle-policy": {
+                    "slo-policy": {
+                      "metric-bound": [
+                        {
+                          "bound": 20,
+                          "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                          "metric-unit": "milliseconds"
+                        },
+                        {
+                          "bound": 1000,
+                          "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                          "metric-unit": "Mbps"
+                        },
+                        {
+                          "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                          "metric-unit": "percentage",
+                          "percentile-value": 0.001
+                        }
+                      ]
+                    }
+                  }
+                }
+              ],
+              "connectivity-type": "point-to-point",
+              "id": "line1"
+            }
+          ]
+        },
+        "description": "dsc",
+        "id": "slice1",
+        "sdps": {
+          "sdp": [
+            {
+              "attachment-circuits": {
+                "attachment-circuit": [
+                  {
+                    "ac-node-id": "172.16.185.32",
+                    "ac-tp-id": "200",
+                    "description": "dsc",
+                    "id": "0"
+                  }
+                ]
+              },
+              "id": "1",
+              "node-id": "172.16.185.32",
+              "sdp-ip-address": [
+                "172.16.185.32"
+              ],
+              "service-match-criteria": {
+                "match-criterion": [
+                  {
+                    "index": 1,
+                    "match-type": [
+                      {
+                        "type": "ietf-network-slice-service:vlan",
+                        "value": [
+                          "101"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-ip-prefix",
+                        "value": [
+                          "172.1.101.22/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-tcp-port",
+                        "value": [
+                          "10200"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-ip-prefix",
+                        "value": [
+                          "172.16.104.221/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-tcp-port",
+                        "value": [
+                          "10500"
+                        ]
+                      }
+                    ],
+                    "target-connection-group-id": "line1"
+                  }
+                ]
+              }
+            },
+            {
+              "attachment-circuits": {
+                "attachment-circuit": [
+                  {
+                    "ac-node-id": "172.16.182.25",
+                    "ac-tp-id": "200",
+                    "description": "dsc",
+                    "id": "0"
+                  }
+                ]
+              },
+              "id": "2",
+              "node-id": "172.16.182.25",
+              "sdp-ip-address": [
+                "172.16.182.25"
+              ],
+              "service-match-criteria": {
+                "match-criterion": [
+                  {
+                    "index": 1,
+                    "match-type": [
+                      {
+                        "type": "ietf-network-slice-service:vlan",
+                        "value": [
+                          "21"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-ip-prefix",
+                        "value": [
+                          "172.16.104.221/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-tcp-port",
+                        "value": [
+                          "10500"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-ip-prefix",
+                        "value": [
+                          "172.1.101.22/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-tcp-port",
+                        "value": [
+                          "10200"
+                        ]
+                      }
+                    ],
+                    "target-connection-group-id": "line1"
+                  }
+                ]
+              }
+            }
+          ]
+        }
+      }
+    ]
+  }
+}
diff --git a/src/tests/ofc25-camara-agg-net-controller/data/pc1_slice1_put_ietf_network_slice.json b/src/tests/ofc25-camara-agg-net-controller/data/pc1_slice1_put_ietf_network_slice.json
new file mode 100644
index 0000000000000000000000000000000000000000..690a84d915620667121cd6893e430576c592322a
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/data/pc1_slice1_put_ietf_network_slice.json
@@ -0,0 +1,58 @@
+{
+      "connectivity-construct": [
+        {
+          "id": 1,
+          "p2p-receiver-sdp": "2",
+          "p2p-sender-sdp": "1",
+          "service-slo-sle-policy": {
+            "slo-policy": {
+              "metric-bound": [
+                {
+                  "bound": 10,
+                  "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                  "metric-unit": "milliseconds"
+                },
+                {
+                  "bound": 5000,
+                  "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                  "metric-unit": "Mbps"
+                },
+                {
+                  "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                  "metric-unit": "percentage",
+                  "percentile-value": 0.001
+                }
+              ]
+            }
+          }
+        },
+        {
+          "id": 2,
+          "p2p-receiver-sdp": "1",
+          "p2p-sender-sdp": "2",
+          "service-slo-sle-policy": {
+            "slo-policy": {
+              "metric-bound": [
+                {
+                  "bound": 20,
+                  "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                  "metric-unit": "milliseconds"
+                },
+                {
+                  "bound": 1000,
+                  "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                  "metric-unit": "Mbps"
+                },
+                {
+                  "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                  "metric-unit": "percentage",
+                  "percentile-value": 0.001
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "connectivity-type": "point-to-point",
+      "id": "line1"
+    }
diff --git a/src/tests/ofc25-camara-agg-net-controller/data/pc1_slice2_post_ietf_network_slice.json b/src/tests/ofc25-camara-agg-net-controller/data/pc1_slice2_post_ietf_network_slice.json
new file mode 100644
index 0000000000000000000000000000000000000000..079239a8bef20c67aaac4a7707a1041650c9bdf9
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/data/pc1_slice2_post_ietf_network_slice.json
@@ -0,0 +1,190 @@
+{
+  "network-slice-services": {
+    "slice-service": [
+      {
+        "connection-groups": {
+          "connection-group": [
+            {
+              "connectivity-construct": [
+                {
+                  "id": 1,
+                  "p2p-receiver-sdp": "2",
+                  "p2p-sender-sdp": "1",
+                  "service-slo-sle-policy": {
+                    "slo-policy": {
+                      "metric-bound": [
+                        {
+                          "bound": 10,
+                          "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                          "metric-unit": "milliseconds"
+                        },
+                        {
+                          "bound": 5000,
+                          "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                          "metric-unit": "Mbps"
+                        },
+                        {
+                          "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                          "metric-unit": "percentage",
+                          "percentile-value": 0.001
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "id": 2,
+                  "p2p-receiver-sdp": "1",
+                  "p2p-sender-sdp": "2",
+                  "service-slo-sle-policy": {
+                    "slo-policy": {
+                      "metric-bound": [
+                        {
+                          "bound": 20,
+                          "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                          "metric-unit": "milliseconds"
+                        },
+                        {
+                          "bound": 1000,
+                          "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                          "metric-unit": "Mbps"
+                        },
+                        {
+                          "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                          "metric-unit": "percentage",
+                          "percentile-value": 0.001
+                        }
+                      ]
+                    }
+                  }
+                }
+              ],
+              "connectivity-type": "point-to-point",
+              "id": "line1"
+            }
+          ]
+        },
+        "description": "dsc",
+        "id": "slice2",
+        "sdps": {
+          "sdp": [
+            {
+              "attachment-circuits": {
+                "attachment-circuit": [
+                  {
+                    "ac-node-id": "172.16.185.32",
+                    "ac-tp-id": "200",
+                    "description": "dsc",
+                    "id": "0"
+                  }
+                ]
+              },
+              "id": "1",
+              "node-id": "172.16.185.32",
+              "sdp-ip-address": [
+                "172.16.185.32"
+              ],
+              "service-match-criteria": {
+                "match-criterion": [
+                  {
+                    "index": 1,
+                    "match-type": [
+                      {
+                        "type": "ietf-network-slice-service:vlan",
+                        "value": [
+                          "201"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-ip-prefix",
+                        "value": [
+                          "172.1.201.22/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-tcp-port",
+                        "value": [
+                          "10200"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-ip-prefix",
+                        "value": [
+                          "172.16.104.221/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-tcp-port",
+                        "value": [
+                          "10500"
+                        ]
+                      }
+                    ],
+                    "target-connection-group-id": "line1"
+                  }
+                ]
+              }
+            },
+            {
+              "attachment-circuits": {
+                "attachment-circuit": [
+                  {
+                    "ac-node-id": "172.16.182.25",
+                    "ac-tp-id": "200",
+                    "description": "dsc",
+                    "id": "0"
+                  }
+                ]
+              },
+              "id": "2",
+              "node-id": "172.16.182.25",
+              "sdp-ip-address": [
+                "172.16.182.25"
+              ],
+              "service-match-criteria": {
+                "match-criterion": [
+                  {
+                    "index": 1,
+                    "match-type": [
+                      {
+                        "type": "ietf-network-slice-service:vlan",
+                        "value": [
+                          "31"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-ip-prefix",
+                        "value": [
+                          "172.16.104.221/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-tcp-port",
+                        "value": [
+                          "10500"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-ip-prefix",
+                        "value": [
+                          "172.1.201.22/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-tcp-port",
+                        "value": [
+                          "10200"
+                        ]
+                      }
+                    ],
+                    "target-connection-group-id": "line1"
+                  }
+                ]
+              }
+            }
+          ]
+        }
+      }
+    ]
+  }
+}
diff --git a/src/tests/ofc25-camara-agg-net-controller/data/pc1_slice2_put_ietf_network_slice.json b/src/tests/ofc25-camara-agg-net-controller/data/pc1_slice2_put_ietf_network_slice.json
new file mode 100644
index 0000000000000000000000000000000000000000..948276a5a79048cf2980c60c57f697b491d19f44
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/data/pc1_slice2_put_ietf_network_slice.json
@@ -0,0 +1,58 @@
+{
+  "connectivity-construct": [
+    {
+      "id": 1,
+      "p2p-receiver-sdp": "2",
+      "p2p-sender-sdp": "1",
+      "service-slo-sle-policy": {
+        "slo-policy": {
+          "metric-bound": [
+            {
+              "bound": 10,
+              "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+              "metric-unit": "milliseconds"
+            },
+            {
+              "bound": 5000,
+              "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+              "metric-unit": "Mbps"
+            },
+            {
+              "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+              "metric-unit": "percentage",
+              "percentile-value": 0.001
+            }
+          ]
+        }
+      }
+    },
+    {
+      "id": 2,
+      "p2p-receiver-sdp": "1",
+      "p2p-sender-sdp": "2",
+      "service-slo-sle-policy": {
+        "slo-policy": {
+          "metric-bound": [
+            {
+              "bound": 20,
+              "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+              "metric-unit": "milliseconds"
+            },
+            {
+              "bound": 1000,
+              "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+              "metric-unit": "Mbps"
+            },
+            {
+              "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+              "metric-unit": "percentage",
+              "percentile-value": 0.001
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "connectivity-type": "point-to-point",
+  "id": "line1"
+}
diff --git a/src/tests/ofc25-camara-agg-net-controller/data/pc2_slice1_put_ietf_network_slice.json b/src/tests/ofc25-camara-agg-net-controller/data/pc2_slice1_put_ietf_network_slice.json
new file mode 100644
index 0000000000000000000000000000000000000000..66e386c483ca1989519ec9ae5c4eef468c41f4bf
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/data/pc2_slice1_put_ietf_network_slice.json
@@ -0,0 +1,58 @@
+{
+  "connectivity-construct": [
+    {
+      "id": 1,
+      "p2p-receiver-sdp": "2",
+      "p2p-sender-sdp": "1",
+      "service-slo-sle-policy": {
+        "slo-policy": {
+          "metric-bound": [
+            {
+              "bound": 10,
+              "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+              "metric-unit": "milliseconds"
+            },
+            {
+              "bound": 10000,
+              "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+              "metric-unit": "Mbps"
+            },
+            {
+              "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+              "metric-unit": "percentage",
+              "percentile-value": 0.001
+            }
+          ]
+        }
+      }
+    },
+    {
+      "id": 2,
+      "p2p-receiver-sdp": "1",
+      "p2p-sender-sdp": "2",
+      "service-slo-sle-policy": {
+        "slo-policy": {
+          "metric-bound": [
+            {
+              "bound": 20,
+              "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+              "metric-unit": "milliseconds"
+            },
+            {
+              "bound": 2000,
+              "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+              "metric-unit": "Mbps"
+            },
+            {
+              "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+              "metric-unit": "percentage",
+              "percentile-value": 0.001
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "connectivity-type": "point-to-point",
+  "id": "line1"
+}
diff --git a/src/tests/ofc25-camara-agg-net-controller/data/pc2_slice2_put_ietf_network_slice.json b/src/tests/ofc25-camara-agg-net-controller/data/pc2_slice2_put_ietf_network_slice.json
new file mode 100644
index 0000000000000000000000000000000000000000..66e386c483ca1989519ec9ae5c4eef468c41f4bf
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/data/pc2_slice2_put_ietf_network_slice.json
@@ -0,0 +1,58 @@
+{
+  "connectivity-construct": [
+    {
+      "id": 1,
+      "p2p-receiver-sdp": "2",
+      "p2p-sender-sdp": "1",
+      "service-slo-sle-policy": {
+        "slo-policy": {
+          "metric-bound": [
+            {
+              "bound": 10,
+              "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+              "metric-unit": "milliseconds"
+            },
+            {
+              "bound": 10000,
+              "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+              "metric-unit": "Mbps"
+            },
+            {
+              "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+              "metric-unit": "percentage",
+              "percentile-value": 0.001
+            }
+          ]
+        }
+      }
+    },
+    {
+      "id": 2,
+      "p2p-receiver-sdp": "1",
+      "p2p-sender-sdp": "2",
+      "service-slo-sle-policy": {
+        "slo-policy": {
+          "metric-bound": [
+            {
+              "bound": 20,
+              "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+              "metric-unit": "milliseconds"
+            },
+            {
+              "bound": 2000,
+              "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+              "metric-unit": "Mbps"
+            },
+            {
+              "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+              "metric-unit": "percentage",
+              "percentile-value": 0.001
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "connectivity-type": "point-to-point",
+  "id": "line1"
+}
diff --git a/src/tests/ofc25-camara-agg-net-controller/data/target-l3vpn-slice1-stages.json b/src/tests/ofc25-camara-agg-net-controller/data/target-l3vpn-slice1-stages.json
new file mode 100644
index 0000000000000000000000000000000000000000..5e75b0ff71eee30c3e73e58e92a5830981a2ef96
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/data/target-l3vpn-slice1-stages.json
@@ -0,0 +1,557 @@
+[
+  {
+    "ietf-l3vpn-svc:l3vpn-svc": {
+      "sites": {
+        "site": [
+          {
+            "devices": {
+              "device": [
+                {
+                  "device-id": "172.16.185.32",
+                  "location": "cloud"
+                }
+              ]
+            },
+            "locations": {
+              "location": [
+                {
+                  "location-id": "cloud"
+                }
+              ]
+            },
+            "management": {
+              "type": "ietf-l3vpn-svc:provider-managed"
+            },
+            "routing-protocols": {
+              "routing-protocol": [
+                {
+                  "static": {
+                    "cascaded-lan-prefixes": {
+                      "ipv4-lan-prefixes": [
+                        {
+                          "lan": "172.16.104.221/24",
+                          "lan-tag": "101",
+                          "next-hop": "172.10.33.254"
+                        }
+                      ]
+                    }
+                  },
+                  "type": "ietf-l3vpn-svc:static"
+                }
+              ]
+            },
+            "site-id": "site_cloud",
+            "site-network-accesses": {
+              "site-network-access": [
+                {
+                  "device-reference": "172.16.185.32",
+                  "ip-connection": {
+                    "ipv4": {
+                      "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                      "addresses": {
+                        "customer-address": "172.10.33.254",
+                        "prefix-length": "24",
+                        "provider-address": "172.10.33.254"
+                      }
+                    }
+                  },
+                  "service": {
+                    "qos": {
+                      "qos-profile": {
+                        "classes": {
+                          "class": [
+                            {
+                              "bandwidth": {
+                                "guaranteed-bw-percent": 100
+                              },
+                              "class-id": "qos-realtime",
+                              "direction": "ietf-l3vpn-svc:both",
+                              "latency": {
+                                "latency-boundary": 10
+                              }
+                            }
+                          ]
+                        }
+                      }
+                    },
+                    "svc-input-bandwidth": 5000000000,
+                    "svc-mtu": 1500,
+                    "svc-output-bandwidth": 1000000000
+                  },
+                  "site-network-access-id": "200",
+                  "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                  "vpn-attachment": {
+                    "site-role": "ietf-l3vpn-svc:hub-role",
+                    "vpn-id": "slice1"
+                  }
+                }
+              ]
+            }
+          },
+          {
+            "devices": {
+              "device": [
+                {
+                  "device-id": "172.16.182.25",
+                  "location": "access"
+                }
+              ]
+            },
+            "locations": {
+              "location": [
+                {
+                  "location-id": "access"
+                }
+              ]
+            },
+            "management": {
+              "type": "ietf-l3vpn-svc:provider-managed"
+            },
+            "routing-protocols": {
+              "routing-protocol": [
+                {
+                  "static": {
+                    "cascaded-lan-prefixes": {
+                      "ipv4-lan-prefixes": [
+                        {
+                          "lan": "172.1.101.22/24",
+                          "lan-tag": "21",
+                          "next-hop": "128.32.33.254"
+                        }
+                      ]
+                    }
+                  },
+                  "type": "ietf-l3vpn-svc:static"
+                }
+              ]
+            },
+            "site-id": "site_access",
+            "site-network-accesses": {
+              "site-network-access": [
+                {
+                  "device-reference": "172.16.182.25",
+                  "ip-connection": {
+                    "ipv4": {
+                      "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                      "addresses": {
+                        "customer-address": "128.32.33.254",
+                        "prefix-length": "24",
+                        "provider-address": "128.32.33.254"
+                      }
+                    }
+                  },
+                  "service": {
+                    "qos": {
+                      "qos-profile": {
+                        "classes": {
+                          "class": [
+                            {
+                              "bandwidth": {
+                                "guaranteed-bw-percent": 100
+                              },
+                              "class-id": "qos-realtime",
+                              "direction": "ietf-l3vpn-svc:both",
+                              "latency": {
+                                "latency-boundary": 20
+                              }
+                            }
+                          ]
+                        }
+                      }
+                    },
+                    "svc-input-bandwidth": 1000000000,
+                    "svc-mtu": 1500,
+                    "svc-output-bandwidth": 5000000000
+                  },
+                  "site-network-access-id": "200",
+                  "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                  "vpn-attachment": {
+                    "site-role": "ietf-l3vpn-svc:spoke-role",
+                    "vpn-id": "slice1"
+                  }
+                }
+              ]
+            }
+          }
+        ]
+      },
+      "vpn-services": {
+        "vpn-service": [
+          {
+            "vpn-id": "slice1"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "ietf-l3vpn-svc:l3vpn-svc": {
+      "sites": {
+        "site": [
+          {
+            "devices": {
+              "device": [
+                {
+                  "device-id": "172.16.185.32",
+                  "location": "cloud"
+                }
+              ]
+            },
+            "locations": {
+              "location": [
+                {
+                  "location-id": "cloud"
+                }
+              ]
+            },
+            "management": {
+              "type": "ietf-l3vpn-svc:provider-managed"
+            },
+            "routing-protocols": {
+              "routing-protocol": [
+                {
+                  "static": {
+                    "cascaded-lan-prefixes": {
+                      "ipv4-lan-prefixes": [
+                        {
+                          "lan": "172.16.104.221/24",
+                          "lan-tag": "101",
+                          "next-hop": "172.10.33.254"
+                        }
+                      ]
+                    }
+                  },
+                  "type": "ietf-l3vpn-svc:static"
+                }
+              ]
+            },
+            "site-id": "site_cloud",
+            "site-network-accesses": {
+              "site-network-access": [
+                {
+                  "device-reference": "172.16.185.32",
+                  "ip-connection": {
+                    "ipv4": {
+                      "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                      "addresses": {
+                        "customer-address": "172.10.33.254",
+                        "prefix-length": "24",
+                        "provider-address": "172.10.33.254"
+                      }
+                    }
+                  },
+                  "service": {
+                    "qos": {
+                      "qos-profile": {
+                        "classes": {
+                          "class": [
+                            {
+                              "bandwidth": {
+                                "guaranteed-bw-percent": 100
+                              },
+                              "class-id": "qos-realtime",
+                              "direction": "ietf-l3vpn-svc:both",
+                              "latency": {
+                                "latency-boundary": 10
+                              }
+                            }
+                          ]
+                        }
+                      }
+                    },
+                    "svc-input-bandwidth": 10000000000,
+                    "svc-mtu": 1500,
+                    "svc-output-bandwidth": 2000000000
+                  },
+                  "site-network-access-id": "200",
+                  "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                  "vpn-attachment": {
+                    "site-role": "ietf-l3vpn-svc:hub-role",
+                    "vpn-id": "slice1"
+                  }
+                }
+              ]
+            }
+          },
+          {
+            "devices": {
+              "device": [
+                {
+                  "device-id": "172.16.182.25",
+                  "location": "access"
+                }
+              ]
+            },
+            "locations": {
+              "location": [
+                {
+                  "location-id": "access"
+                }
+              ]
+            },
+            "management": {
+              "type": "ietf-l3vpn-svc:provider-managed"
+            },
+            "routing-protocols": {
+              "routing-protocol": [
+                {
+                  "static": {
+                    "cascaded-lan-prefixes": {
+                      "ipv4-lan-prefixes": [
+                        {
+                          "lan": "172.1.101.22/24",
+                          "lan-tag": "21",
+                          "next-hop": "128.32.33.254"
+                        }
+                      ]
+                    }
+                  },
+                  "type": "ietf-l3vpn-svc:static"
+                }
+              ]
+            },
+            "site-id": "site_access",
+            "site-network-accesses": {
+              "site-network-access": [
+                {
+                  "device-reference": "172.16.182.25",
+                  "ip-connection": {
+                    "ipv4": {
+                      "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                      "addresses": {
+                        "customer-address": "128.32.33.254",
+                        "prefix-length": "24",
+                        "provider-address": "128.32.33.254"
+                      }
+                    }
+                  },
+                  "service": {
+                    "qos": {
+                      "qos-profile": {
+                        "classes": {
+                          "class": [
+                            {
+                              "bandwidth": {
+                                "guaranteed-bw-percent": 100
+                              },
+                              "class-id": "qos-realtime",
+                              "direction": "ietf-l3vpn-svc:both",
+                              "latency": {
+                                "latency-boundary": 20
+                              }
+                            }
+                          ]
+                        }
+                      }
+                    },
+                    "svc-input-bandwidth": 2000000000,
+                    "svc-mtu": 1500,
+                    "svc-output-bandwidth": 10000000000
+                  },
+                  "site-network-access-id": "200",
+                  "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                  "vpn-attachment": {
+                    "site-role": "ietf-l3vpn-svc:spoke-role",
+                    "vpn-id": "slice1"
+                  }
+                }
+              ]
+            }
+          }
+        ]
+      },
+      "vpn-services": {
+        "vpn-service": [
+          {
+            "vpn-id": "slice1"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "ietf-l3vpn-svc:l3vpn-svc": {
+      "sites": {
+        "site": [
+          {
+            "devices": {
+              "device": [
+                {
+                  "device-id": "172.16.185.32",
+                  "location": "cloud"
+                }
+              ]
+            },
+            "locations": {
+              "location": [
+                {
+                  "location-id": "cloud"
+                }
+              ]
+            },
+            "management": {
+              "type": "ietf-l3vpn-svc:provider-managed"
+            },
+            "routing-protocols": {
+              "routing-protocol": [
+                {
+                  "static": {
+                    "cascaded-lan-prefixes": {
+                      "ipv4-lan-prefixes": [
+                        {
+                          "lan": "172.16.104.221/24",
+                          "lan-tag": "101",
+                          "next-hop": "172.10.33.254"
+                        }
+                      ]
+                    }
+                  },
+                  "type": "ietf-l3vpn-svc:static"
+                }
+              ]
+            },
+            "site-id": "site_cloud",
+            "site-network-accesses": {
+              "site-network-access": [
+                {
+                  "device-reference": "172.16.185.32",
+                  "ip-connection": {
+                    "ipv4": {
+                      "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                      "addresses": {
+                        "customer-address": "172.10.33.254",
+                        "prefix-length": "24",
+                        "provider-address": "172.10.33.254"
+                      }
+                    }
+                  },
+                  "service": {
+                    "qos": {
+                      "qos-profile": {
+                        "classes": {
+                          "class": [
+                            {
+                              "bandwidth": {
+                                "guaranteed-bw-percent": 100
+                              },
+                              "class-id": "qos-realtime",
+                              "direction": "ietf-l3vpn-svc:both",
+                              "latency": {
+                                "latency-boundary": 10
+                              }
+                            }
+                          ]
+                        }
+                      }
+                    },
+                    "svc-input-bandwidth": 5000000000,
+                    "svc-mtu": 1500,
+                    "svc-output-bandwidth": 1000000000
+                  },
+                  "site-network-access-id": "200",
+                  "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                  "vpn-attachment": {
+                    "site-role": "ietf-l3vpn-svc:hub-role",
+                    "vpn-id": "slice1"
+                  }
+                }
+              ]
+            }
+          },
+          {
+            "devices": {
+              "device": [
+                {
+                  "device-id": "172.16.182.25",
+                  "location": "access"
+                }
+              ]
+            },
+            "locations": {
+              "location": [
+                {
+                  "location-id": "access"
+                }
+              ]
+            },
+            "management": {
+              "type": "ietf-l3vpn-svc:provider-managed"
+            },
+            "routing-protocols": {
+              "routing-protocol": [
+                {
+                  "static": {
+                    "cascaded-lan-prefixes": {
+                      "ipv4-lan-prefixes": [
+                        {
+                          "lan": "172.1.101.22/24",
+                          "lan-tag": "21",
+                          "next-hop": "128.32.33.254"
+                        }
+                      ]
+                    }
+                  },
+                  "type": "ietf-l3vpn-svc:static"
+                }
+              ]
+            },
+            "site-id": "site_access",
+            "site-network-accesses": {
+              "site-network-access": [
+                {
+                  "device-reference": "172.16.182.25",
+                  "ip-connection": {
+                    "ipv4": {
+                      "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                      "addresses": {
+                        "customer-address": "128.32.33.254",
+                        "prefix-length": "24",
+                        "provider-address": "128.32.33.254"
+                      }
+                    }
+                  },
+                  "service": {
+                    "qos": {
+                      "qos-profile": {
+                        "classes": {
+                          "class": [
+                            {
+                              "bandwidth": {
+                                "guaranteed-bw-percent": 100
+                              },
+                              "class-id": "qos-realtime",
+                              "direction": "ietf-l3vpn-svc:both",
+                              "latency": {
+                                "latency-boundary": 20
+                              }
+                            }
+                          ]
+                        }
+                      }
+                    },
+                    "svc-input-bandwidth": 1000000000,
+                    "svc-mtu": 1500,
+                    "svc-output-bandwidth": 5000000000
+                  },
+                  "site-network-access-id": "200",
+                  "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                  "vpn-attachment": {
+                    "site-role": "ietf-l3vpn-svc:spoke-role",
+                    "vpn-id": "slice1"
+                  }
+                }
+              ]
+            }
+          }
+        ]
+      },
+      "vpn-services": {
+        "vpn-service": [
+          {
+            "vpn-id": "slice1"
+          }
+        ]
+      }
+    }
+  }
+]
diff --git a/src/tests/ofc25-camara-agg-net-controller/data/target-l3vpn-slice2-stages.json b/src/tests/ofc25-camara-agg-net-controller/data/target-l3vpn-slice2-stages.json
new file mode 100644
index 0000000000000000000000000000000000000000..216287af816b4b8656c9bd386eb6f622c0afe987
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/data/target-l3vpn-slice2-stages.json
@@ -0,0 +1,557 @@
+[
+  {
+    "ietf-l3vpn-svc:l3vpn-svc": {
+      "sites": {
+        "site": [
+          {
+            "devices": {
+              "device": [
+                {
+                  "device-id": "172.16.185.32",
+                  "location": "cloud"
+                }
+              ]
+            },
+            "locations": {
+              "location": [
+                {
+                  "location-id": "cloud"
+                }
+              ]
+            },
+            "management": {
+              "type": "ietf-l3vpn-svc:provider-managed"
+            },
+            "routing-protocols": {
+              "routing-protocol": [
+                {
+                  "static": {
+                    "cascaded-lan-prefixes": {
+                      "ipv4-lan-prefixes": [
+                        {
+                          "lan": "172.16.104.221/24",
+                          "lan-tag": "201",
+                          "next-hop": "172.10.33.254"
+                        }
+                      ]
+                    }
+                  },
+                  "type": "ietf-l3vpn-svc:static"
+                }
+              ]
+            },
+            "site-id": "site_cloud",
+            "site-network-accesses": {
+              "site-network-access": [
+                {
+                  "device-reference": "172.16.185.32",
+                  "ip-connection": {
+                    "ipv4": {
+                      "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                      "addresses": {
+                        "customer-address": "172.10.33.254",
+                        "prefix-length": "24",
+                        "provider-address": "172.10.33.254"
+                      }
+                    }
+                  },
+                  "service": {
+                    "qos": {
+                      "qos-profile": {
+                        "classes": {
+                          "class": [
+                            {
+                              "bandwidth": {
+                                "guaranteed-bw-percent": 100
+                              },
+                              "class-id": "qos-realtime",
+                              "direction": "ietf-l3vpn-svc:both",
+                              "latency": {
+                                "latency-boundary": 10
+                              }
+                            }
+                          ]
+                        }
+                      }
+                    },
+                    "svc-input-bandwidth": 5000000000,
+                    "svc-mtu": 1500,
+                    "svc-output-bandwidth": 1000000000
+                  },
+                  "site-network-access-id": "200",
+                  "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                  "vpn-attachment": {
+                    "site-role": "ietf-l3vpn-svc:hub-role",
+                    "vpn-id": "slice2"
+                  }
+                }
+              ]
+            }
+          },
+          {
+            "devices": {
+              "device": [
+                {
+                  "device-id": "172.16.182.25",
+                  "location": "access"
+                }
+              ]
+            },
+            "locations": {
+              "location": [
+                {
+                  "location-id": "access"
+                }
+              ]
+            },
+            "management": {
+              "type": "ietf-l3vpn-svc:provider-managed"
+            },
+            "routing-protocols": {
+              "routing-protocol": [
+                {
+                  "static": {
+                    "cascaded-lan-prefixes": {
+                      "ipv4-lan-prefixes": [
+                        {
+                          "lan": "172.1.201.22/24",
+                          "lan-tag": "31",
+                          "next-hop": "128.32.33.254"
+                        }
+                      ]
+                    }
+                  },
+                  "type": "ietf-l3vpn-svc:static"
+                }
+              ]
+            },
+            "site-id": "site_access",
+            "site-network-accesses": {
+              "site-network-access": [
+                {
+                  "device-reference": "172.16.182.25",
+                  "ip-connection": {
+                    "ipv4": {
+                      "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                      "addresses": {
+                        "customer-address": "128.32.33.254",
+                        "prefix-length": "24",
+                        "provider-address": "128.32.33.254"
+                      }
+                    }
+                  },
+                  "service": {
+                    "qos": {
+                      "qos-profile": {
+                        "classes": {
+                          "class": [
+                            {
+                              "bandwidth": {
+                                "guaranteed-bw-percent": 100
+                              },
+                              "class-id": "qos-realtime",
+                              "direction": "ietf-l3vpn-svc:both",
+                              "latency": {
+                                "latency-boundary": 20
+                              }
+                            }
+                          ]
+                        }
+                      }
+                    },
+                    "svc-input-bandwidth": 1000000000,
+                    "svc-mtu": 1500,
+                    "svc-output-bandwidth": 5000000000
+                  },
+                  "site-network-access-id": "200",
+                  "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                  "vpn-attachment": {
+                    "site-role": "ietf-l3vpn-svc:spoke-role",
+                    "vpn-id": "slice2"
+                  }
+                }
+              ]
+            }
+          }
+        ]
+      },
+      "vpn-services": {
+        "vpn-service": [
+          {
+            "vpn-id": "slice2"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "ietf-l3vpn-svc:l3vpn-svc": {
+      "sites": {
+        "site": [
+          {
+            "devices": {
+              "device": [
+                {
+                  "device-id": "172.16.185.32",
+                  "location": "cloud"
+                }
+              ]
+            },
+            "locations": {
+              "location": [
+                {
+                  "location-id": "cloud"
+                }
+              ]
+            },
+            "management": {
+              "type": "ietf-l3vpn-svc:provider-managed"
+            },
+            "routing-protocols": {
+              "routing-protocol": [
+                {
+                  "static": {
+                    "cascaded-lan-prefixes": {
+                      "ipv4-lan-prefixes": [
+                        {
+                          "lan": "172.16.104.221/24",
+                          "lan-tag": "201",
+                          "next-hop": "172.10.33.254"
+                        }
+                      ]
+                    }
+                  },
+                  "type": "ietf-l3vpn-svc:static"
+                }
+              ]
+            },
+            "site-id": "site_cloud",
+            "site-network-accesses": {
+              "site-network-access": [
+                {
+                  "device-reference": "172.16.185.32",
+                  "ip-connection": {
+                    "ipv4": {
+                      "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                      "addresses": {
+                        "customer-address": "172.10.33.254",
+                        "prefix-length": "24",
+                        "provider-address": "172.10.33.254"
+                      }
+                    }
+                  },
+                  "service": {
+                    "qos": {
+                      "qos-profile": {
+                        "classes": {
+                          "class": [
+                            {
+                              "bandwidth": {
+                                "guaranteed-bw-percent": 100
+                              },
+                              "class-id": "qos-realtime",
+                              "direction": "ietf-l3vpn-svc:both",
+                              "latency": {
+                                "latency-boundary": 10
+                              }
+                            }
+                          ]
+                        }
+                      }
+                    },
+                    "svc-input-bandwidth": 10000000000,
+                    "svc-mtu": 1500,
+                    "svc-output-bandwidth": 2000000000
+                  },
+                  "site-network-access-id": "200",
+                  "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                  "vpn-attachment": {
+                    "site-role": "ietf-l3vpn-svc:hub-role",
+                    "vpn-id": "slice2"
+                  }
+                }
+              ]
+            }
+          },
+          {
+            "devices": {
+              "device": [
+                {
+                  "device-id": "172.16.182.25",
+                  "location": "access"
+                }
+              ]
+            },
+            "locations": {
+              "location": [
+                {
+                  "location-id": "access"
+                }
+              ]
+            },
+            "management": {
+              "type": "ietf-l3vpn-svc:provider-managed"
+            },
+            "routing-protocols": {
+              "routing-protocol": [
+                {
+                  "static": {
+                    "cascaded-lan-prefixes": {
+                      "ipv4-lan-prefixes": [
+                        {
+                          "lan": "172.1.201.22/24",
+                          "lan-tag": "31",
+                          "next-hop": "128.32.33.254"
+                        }
+                      ]
+                    }
+                  },
+                  "type": "ietf-l3vpn-svc:static"
+                }
+              ]
+            },
+            "site-id": "site_access",
+            "site-network-accesses": {
+              "site-network-access": [
+                {
+                  "device-reference": "172.16.182.25",
+                  "ip-connection": {
+                    "ipv4": {
+                      "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                      "addresses": {
+                        "customer-address": "128.32.33.254",
+                        "prefix-length": "24",
+                        "provider-address": "128.32.33.254"
+                      }
+                    }
+                  },
+                  "service": {
+                    "qos": {
+                      "qos-profile": {
+                        "classes": {
+                          "class": [
+                            {
+                              "bandwidth": {
+                                "guaranteed-bw-percent": 100
+                              },
+                              "class-id": "qos-realtime",
+                              "direction": "ietf-l3vpn-svc:both",
+                              "latency": {
+                                "latency-boundary": 20
+                              }
+                            }
+                          ]
+                        }
+                      }
+                    },
+                    "svc-input-bandwidth": 2000000000,
+                    "svc-mtu": 1500,
+                    "svc-output-bandwidth": 10000000000
+                  },
+                  "site-network-access-id": "200",
+                  "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                  "vpn-attachment": {
+                    "site-role": "ietf-l3vpn-svc:spoke-role",
+                    "vpn-id": "slice2"
+                  }
+                }
+              ]
+            }
+          }
+        ]
+      },
+      "vpn-services": {
+        "vpn-service": [
+          {
+            "vpn-id": "slice2"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "ietf-l3vpn-svc:l3vpn-svc": {
+      "sites": {
+        "site": [
+          {
+            "devices": {
+              "device": [
+                {
+                  "device-id": "172.16.185.32",
+                  "location": "cloud"
+                }
+              ]
+            },
+            "locations": {
+              "location": [
+                {
+                  "location-id": "cloud"
+                }
+              ]
+            },
+            "management": {
+              "type": "ietf-l3vpn-svc:provider-managed"
+            },
+            "routing-protocols": {
+              "routing-protocol": [
+                {
+                  "static": {
+                    "cascaded-lan-prefixes": {
+                      "ipv4-lan-prefixes": [
+                        {
+                          "lan": "172.16.104.221/24",
+                          "lan-tag": "201",
+                          "next-hop": "172.10.33.254"
+                        }
+                      ]
+                    }
+                  },
+                  "type": "ietf-l3vpn-svc:static"
+                }
+              ]
+            },
+            "site-id": "site_cloud",
+            "site-network-accesses": {
+              "site-network-access": [
+                {
+                  "device-reference": "172.16.185.32",
+                  "ip-connection": {
+                    "ipv4": {
+                      "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                      "addresses": {
+                        "customer-address": "172.10.33.254",
+                        "prefix-length": "24",
+                        "provider-address": "172.10.33.254"
+                      }
+                    }
+                  },
+                  "service": {
+                    "qos": {
+                      "qos-profile": {
+                        "classes": {
+                          "class": [
+                            {
+                              "bandwidth": {
+                                "guaranteed-bw-percent": 100
+                              },
+                              "class-id": "qos-realtime",
+                              "direction": "ietf-l3vpn-svc:both",
+                              "latency": {
+                                "latency-boundary": 10
+                              }
+                            }
+                          ]
+                        }
+                      }
+                    },
+                    "svc-input-bandwidth": 5000000000,
+                    "svc-mtu": 1500,
+                    "svc-output-bandwidth": 1000000000
+                  },
+                  "site-network-access-id": "200",
+                  "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                  "vpn-attachment": {
+                    "site-role": "ietf-l3vpn-svc:hub-role",
+                    "vpn-id": "slice2"
+                  }
+                }
+              ]
+            }
+          },
+          {
+            "devices": {
+              "device": [
+                {
+                  "device-id": "172.16.182.25",
+                  "location": "access"
+                }
+              ]
+            },
+            "locations": {
+              "location": [
+                {
+                  "location-id": "access"
+                }
+              ]
+            },
+            "management": {
+              "type": "ietf-l3vpn-svc:provider-managed"
+            },
+            "routing-protocols": {
+              "routing-protocol": [
+                {
+                  "static": {
+                    "cascaded-lan-prefixes": {
+                      "ipv4-lan-prefixes": [
+                        {
+                          "lan": "172.1.201.22/24",
+                          "lan-tag": "31",
+                          "next-hop": "128.32.33.254"
+                        }
+                      ]
+                    }
+                  },
+                  "type": "ietf-l3vpn-svc:static"
+                }
+              ]
+            },
+            "site-id": "site_access",
+            "site-network-accesses": {
+              "site-network-access": [
+                {
+                  "device-reference": "172.16.182.25",
+                  "ip-connection": {
+                    "ipv4": {
+                      "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                      "addresses": {
+                        "customer-address": "128.32.33.254",
+                        "prefix-length": "24",
+                        "provider-address": "128.32.33.254"
+                      }
+                    }
+                  },
+                  "service": {
+                    "qos": {
+                      "qos-profile": {
+                        "classes": {
+                          "class": [
+                            {
+                              "bandwidth": {
+                                "guaranteed-bw-percent": 100
+                              },
+                              "class-id": "qos-realtime",
+                              "direction": "ietf-l3vpn-svc:both",
+                              "latency": {
+                                "latency-boundary": 20
+                              }
+                            }
+                          ]
+                        }
+                      }
+                    },
+                    "svc-input-bandwidth": 1000000000,
+                    "svc-mtu": 1500,
+                    "svc-output-bandwidth": 5000000000
+                  },
+                  "site-network-access-id": "200",
+                  "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                  "vpn-attachment": {
+                    "site-role": "ietf-l3vpn-svc:spoke-role",
+                    "vpn-id": "slice2"
+                  }
+                }
+              ]
+            }
+          }
+        ]
+      },
+      "vpn-services": {
+        "vpn-service": [
+          {
+            "vpn-id": "slice2"
+          }
+        ]
+      }
+    }
+  }
+]
diff --git a/src/tests/ofc25-camara-agg-net-controller/deploy_specs.sh b/src/tests/ofc25-camara-agg-net-controller/deploy_specs.sh
new file mode 100755
index 0000000000000000000000000000000000000000..9ae83e7b126aa2913cd3c30887292b4626dd5855
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/deploy_specs.sh
@@ -0,0 +1,208 @@
+#!/bin/bash
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# ----- TeraFlowSDN ------------------------------------------------------------
+
+# Set the URL of the internal MicroK8s Docker registry where the images will be uploaded to.
+export TFS_REGISTRY_IMAGES="http://localhost:32000/tfs/"
+
+# Set the list of components, separated by spaces, you want to build images for, and deploy.
+#export TFS_COMPONENTS="context device pathcomp service slice nbi webui load_generator"
+export TFS_COMPONENTS="context device pathcomp service slice nbi"
+
+# Uncomment to activate Monitoring (old)
+#export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring"
+
+# Uncomment to activate Monitoring Framework (new)
+#export TFS_COMPONENTS="${TFS_COMPONENTS} kpi_manager kpi_value_writer kpi_value_api telemetry analytics automation"
+
+# Uncomment to activate QoS Profiles
+#export TFS_COMPONENTS="${TFS_COMPONENTS} qos_profile"
+
+# Uncomment to activate BGP-LS Speaker
+#export TFS_COMPONENTS="${TFS_COMPONENTS} bgpls_speaker"
+
+# Uncomment to activate Optical Controller
+#   To manage optical connections, "service" requires "opticalcontroller" to be deployed
+#   before "service", thus we "hack" the TFS_COMPONENTS environment variable prepending the
+#   "opticalcontroller" only if "service" is already in TFS_COMPONENTS, and re-export it.
+#if [[ "$TFS_COMPONENTS" == *"service"* ]]; then
+#    BEFORE="${TFS_COMPONENTS% service*}"
+#    AFTER="${TFS_COMPONENTS#* service}"
+#    export TFS_COMPONENTS="${BEFORE} opticalcontroller service ${AFTER}"
+#fi
+
+# Uncomment to activate ZTP
+#export TFS_COMPONENTS="${TFS_COMPONENTS} ztp"
+
+# Uncomment to activate Policy Manager
+#export TFS_COMPONENTS="${TFS_COMPONENTS} policy"
+
+# Uncomment to activate Optical CyberSecurity
+#export TFS_COMPONENTS="${TFS_COMPONENTS} dbscanserving opticalattackmitigator opticalattackdetector opticalattackmanager"
+
+# Uncomment to activate L3 CyberSecurity
+#export TFS_COMPONENTS="${TFS_COMPONENTS} l3_attackmitigator l3_centralizedattackdetector"
+
+# Uncomment to activate TE
+#export TFS_COMPONENTS="${TFS_COMPONENTS} te"
+
+# Uncomment to activate Forecaster
+#export TFS_COMPONENTS="${TFS_COMPONENTS} forecaster"
+
+# Uncomment to activate E2E Orchestrator
+#export TFS_COMPONENTS="${TFS_COMPONENTS} e2e_orchestrator"
+
+# Uncomment to activate DLT and Interdomain
+#export TFS_COMPONENTS="${TFS_COMPONENTS} interdomain dlt"
+#if [[ "$TFS_COMPONENTS" == *"dlt"* ]]; then
+#    export KEY_DIRECTORY_PATH="src/dlt/gateway/keys/priv_sk"
+#    export CERT_DIRECTORY_PATH="src/dlt/gateway/keys/cert.pem"
+#    export TLS_CERT_PATH="src/dlt/gateway/keys/ca.crt"
+#fi
+
+# Uncomment to activate QKD App
+#   To manage QKD Apps, "service" requires "qkd_app" to be deployed
+#   before "service", thus we "hack" the TFS_COMPONENTS environment variable prepending the
+#   "qkd_app" only if "service" is already in TFS_COMPONENTS, and re-export it.
+#if [[ "$TFS_COMPONENTS" == *"service"* ]]; then
+#    BEFORE="${TFS_COMPONENTS% service*}"
+#    AFTER="${TFS_COMPONENTS#* service}"
+#    export TFS_COMPONENTS="${BEFORE} qkd_app service ${AFTER}"
+#fi
+
+
+# Set the tag you want to use for your images.
+export TFS_IMAGE_TAG="dev"
+
+# Set the name of the Kubernetes namespace to deploy TFS to.
+export TFS_K8S_NAMESPACE="tfs"
+
+# Set additional manifest files to be applied after the deployment
+export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml"
+
+# Uncomment to monitor performance of components
+#export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/servicemonitors.yaml"
+
+# Uncomment when deploying Optical CyberSecurity
+#export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/cachingservice.yaml"
+
+# Set the new Grafana admin password
+export TFS_GRAFANA_PASSWORD="admin123+"
+
+# Disable skip-build flag to rebuild the Docker images.
+export TFS_SKIP_BUILD=""
+
+
+# ----- CockroachDB ------------------------------------------------------------
+
+# Set the namespace where CockroackDB will be deployed.
+export CRDB_NAMESPACE="crdb"
+
+# Set the external port CockroackDB Postgre SQL interface will be exposed to.
+export CRDB_EXT_PORT_SQL="26257"
+
+# Set the external port CockroackDB HTTP Mgmt GUI interface will be exposed to.
+export CRDB_EXT_PORT_HTTP="8081"
+
+# Set the database username to be used by Context.
+export CRDB_USERNAME="tfs"
+
+# Set the database user's password to be used by Context.
+export CRDB_PASSWORD="tfs123"
+
+# Set CockroachDB installation mode to 'single'. This option is convenient for development and testing.
+# See ./deploy/all.sh or ./deploy/crdb.sh for additional details
+export CRDB_DEPLOY_MODE="single"
+
+# Disable flag for dropping database, if it exists.
+export CRDB_DROP_DATABASE_IF_EXISTS="YES"
+
+# Disable flag for re-deploying CockroachDB from scratch.
+export CRDB_REDEPLOY=""
+
+
+# ----- NATS -------------------------------------------------------------------
+
+# Set the namespace where NATS will be deployed.
+export NATS_NAMESPACE="nats"
+
+# Set the external port NATS Client interface will be exposed to.
+export NATS_EXT_PORT_CLIENT="4222"
+
+# Set the external port NATS HTTP Mgmt GUI interface will be exposed to.
+export NATS_EXT_PORT_HTTP="8222"
+
+# Set NATS installation mode to 'single'. This option is convenient for development and testing.
+# See ./deploy/all.sh or ./deploy/nats.sh for additional details
+export NATS_DEPLOY_MODE="single"
+
+# Disable flag for re-deploying NATS from scratch.
+export NATS_REDEPLOY=""
+
+
+# ----- QuestDB ----------------------------------------------------------------
+
+# Set the namespace where QuestDB will be deployed.
+export QDB_NAMESPACE="qdb"
+
+# Set the external port QuestDB Postgre SQL interface will be exposed to.
+export QDB_EXT_PORT_SQL="8812"
+
+# Set the external port QuestDB Influx Line Protocol interface will be exposed to.
+export QDB_EXT_PORT_ILP="9009"
+
+# Set the external port QuestDB HTTP Mgmt GUI interface will be exposed to.
+export QDB_EXT_PORT_HTTP="9000"
+
+# Set the database username to be used for QuestDB.
+export QDB_USERNAME="admin"
+
+# Set the database user's password to be used for QuestDB.
+export QDB_PASSWORD="quest"
+
+# Set the table name to be used by Monitoring for KPIs.
+export QDB_TABLE_MONITORING_KPIS="tfs_monitoring_kpis"
+
+# Set the table name to be used by Slice for plotting groups.
+export QDB_TABLE_SLICE_GROUPS="tfs_slice_groups"
+
+# Disable flag for dropping tables if they exist.
+export QDB_DROP_TABLES_IF_EXIST="YES"
+
+# Disable flag for re-deploying QuestDB from scratch.
+export QDB_REDEPLOY=""
+
+
+# ----- K8s Observability ------------------------------------------------------
+
+# Set the external port Prometheus Mgmt HTTP GUI interface will be exposed to.
+export PROM_EXT_PORT_HTTP="9090"
+
+# Set the external port Grafana HTTP Dashboards will be exposed to.
+export GRAF_EXT_PORT_HTTP="3000"
+
+
+# ----- Apache Kafka -----------------------------------------------------------
+
+# Set the namespace where Apache Kafka will be deployed.
+export KFK_NAMESPACE="kafka"
+
+# Set the port Apache Kafka server will be exposed to.
+export KFK_SERVER_PORT="9092"
+
+# Set the flag to YES for redeploying of Apache Kafka
+export KFK_REDEPLOY=""
diff --git a/src/tests/ofc25-camara-agg-net-controller/redeploy-tfs.sh b/src/tests/ofc25-camara-agg-net-controller/redeploy-tfs.sh
new file mode 100755
index 0000000000000000000000000000000000000000..7f4e0c0f4048348b4b220508d60088e69a3219fb
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/redeploy-tfs.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source ~/tfs-ctrl/src/tests/ofc25-camara-agg-net-controller/deploy_specs.sh
+./deploy/all.sh
diff --git a/src/tests/ofc25-camara-agg-net-controller/requirements.in b/src/tests/ofc25-camara-agg-net-controller/requirements.in
new file mode 100644
index 0000000000000000000000000000000000000000..1bdaec9997da4b83fa89c1bf0d00d4c3a73558a4
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/requirements.in
@@ -0,0 +1,30 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+deepdiff==6.7.*
+requests==2.27.*
+
+coverage==6.3
+grpcio==1.47.*
+grpcio-health-checking==1.47.*
+grpcio-reflection==1.47.*
+grpcio-tools==1.47.*
+grpclib==0.4.4
+prettytable==3.5.0
+prometheus-client==0.13.0
+protobuf==3.20.*
+pytest==6.2.5
+pytest-benchmark==3.4.1
+python-dateutil==2.8.2
+pytest-depends==1.0.1
diff --git a/src/tests/ofc25-camara-agg-net-controller/scripts/run-agg-net-ietf-slice-operations.sh b/src/tests/ofc25-camara-agg-net-controller/scripts/run-agg-net-ietf-slice-operations.sh
new file mode 100755
index 0000000000000000000000000000000000000000..001380ea2fcb88f8546bfd2345fab9431c5e1d03
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/scripts/run-agg-net-ietf-slice-operations.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source /var/teraflow/tfs_runtime_env_vars.sh
+export PYTHONPATH=/var/teraflow
+pytest --verbose --log-level=INFO \
+    --junitxml=/opt/results/report_e2e_ietf_l3vpn_operations.xml \
+    /var/teraflow/tests/ofc25-camara-agg-net-controller/tests/test_agg_net_ietf_slice_operations.py
diff --git a/src/tests/ofc25-camara-agg-net-controller/scripts/run-onboarding.sh b/src/tests/ofc25-camara-agg-net-controller/scripts/run-onboarding.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f62294a934ac4aed1140143d2ffbfe02568a6405
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/scripts/run-onboarding.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source /var/teraflow/tfs_runtime_env_vars.sh
+export PYTHONPATH=/var/teraflow
+pytest --verbose --log-level=INFO \
+    --junitxml=/opt/results/report_onboarding.xml \
+    /var/teraflow/tests/ofc25-camara-agg-net-controller/tests/test_onboarding.py
diff --git a/src/tests/ofc25-camara-agg-net-controller/tests/Fixtures.py b/src/tests/ofc25-camara-agg-net-controller/tests/Fixtures.py
new file mode 100644
index 0000000000000000000000000000000000000000..15978851faae668339fa4eed6db8ab7e1be2eb5e
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/tests/Fixtures.py
@@ -0,0 +1,43 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import pytest
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from monitoring.client.MonitoringClient import MonitoringClient
+from service.client.ServiceClient import ServiceClient
+
+@pytest.fixture(scope='session')
+def context_client():
+    _client = ContextClient()
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def device_client():
+    _client = DeviceClient()
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def monitoring_client():
+    _client = MonitoringClient()
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def service_client():
+    _client = ServiceClient()
+    yield _client
+    _client.close()
diff --git a/src/tests/ofc25-camara-agg-net-controller/tests/Tools.py b/src/tests/ofc25-camara-agg-net-controller/tests/Tools.py
new file mode 100644
index 0000000000000000000000000000000000000000..cd2add49edd23f4c169b5fdc3c5123b2b31daa8d
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/tests/Tools.py
@@ -0,0 +1,109 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import enum, logging, requests
+from typing import Any, Dict, List, Optional, Set, Union
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_host, get_service_port_http
+
+NBI_ADDRESS  = get_service_host(ServiceNameEnum.NBI)
+NBI_PORT     = get_service_port_http(ServiceNameEnum.NBI)
+NBI_USERNAME = 'admin'
+NBI_PASSWORD = 'admin'
+NBI_BASE_URL = ''
+
+class RestRequestMethod(enum.Enum):
+    GET    = 'get'
+    POST   = 'post'
+    PUT    = 'put'
+    PATCH  = 'patch'
+    DELETE = 'delete'
+
+EXPECTED_STATUS_CODES : Set[int] = {
+    requests.codes['OK'        ],
+    requests.codes['CREATED'   ],
+    requests.codes['ACCEPTED'  ],
+    requests.codes['NO_CONTENT'],
+}
+
+def do_rest_request(
+    method : RestRequestMethod, url : str, body : Optional[Any] = None, timeout : int = 10,
+    allow_redirects : bool = True, expected_status_codes : Set[int] = EXPECTED_STATUS_CODES,
+    logger : Optional[logging.Logger] = None
+) -> Optional[Union[Dict, List]]:
+    request_url = 'http://{:s}:{:s}@{:s}:{:d}{:s}{:s}'.format(
+        NBI_USERNAME, NBI_PASSWORD, NBI_ADDRESS, NBI_PORT, str(NBI_BASE_URL), url
+    )
+
+    if logger is not None:
+        msg = 'Request: {:s} {:s}'.format(str(method.value).upper(), str(request_url))
+        if body is not None: msg += ' body={:s}'.format(str(body))
+        logger.warning(msg)
+    reply = requests.request(method.value, request_url, headers={'Content-Type': 'application/json'}, timeout=timeout, json=body, allow_redirects=allow_redirects)
+    if logger is not None:
+        logger.warning('Reply: {:s}'.format(str(reply.text)))
+    assert reply.status_code in expected_status_codes, 'Reply failed with status code {:d}'.format(reply.status_code)
+
+    if reply.content and len(reply.content) > 0: return reply.json()
+    return None
+
+def do_rest_get_request(
+    url : str, body : Optional[Any] = None, timeout : int = 10,
+    allow_redirects : bool = True, expected_status_codes : Set[int] = EXPECTED_STATUS_CODES,
+    logger : Optional[logging.Logger] = None
+) -> Optional[Union[Dict, List]]:
+    return do_rest_request(
+        RestRequestMethod.GET, url, body=body, timeout=timeout, allow_redirects=allow_redirects,
+        expected_status_codes=expected_status_codes, logger=logger
+    )
+
+def do_rest_post_request(
+    url : str, body : Optional[Any] = None, timeout : int = 10,
+    allow_redirects : bool = True, expected_status_codes : Set[int] = EXPECTED_STATUS_CODES,
+    logger : Optional[logging.Logger] = None
+) -> Optional[Union[Dict, List]]:
+    return do_rest_request(
+        RestRequestMethod.POST, url, body=body, timeout=timeout, allow_redirects=allow_redirects,
+        expected_status_codes=expected_status_codes, logger=logger
+    )
+
+def do_rest_put_request(
+    url : str, body : Optional[Any] = None, timeout : int = 10,
+    allow_redirects : bool = True, expected_status_codes : Set[int] = EXPECTED_STATUS_CODES,
+    logger : Optional[logging.Logger] = None
+) -> Optional[Union[Dict, List]]:
+    return do_rest_request(
+        RestRequestMethod.PUT, url, body=body, timeout=timeout, allow_redirects=allow_redirects,
+        expected_status_codes=expected_status_codes, logger=logger
+    )
+
+def do_rest_patch_request(
+    url : str, body : Optional[Any] = None, timeout : int = 10,
+    allow_redirects : bool = True, expected_status_codes : Set[int] = EXPECTED_STATUS_CODES,
+    logger : Optional[logging.Logger] = None
+) -> Optional[Union[Dict, List]]:
+    return do_rest_request(
+        RestRequestMethod.PATCH, url, body=body, timeout=timeout, allow_redirects=allow_redirects,
+        expected_status_codes=expected_status_codes, logger=logger
+    )
+
+def do_rest_delete_request(
+    url : str, body : Optional[Any] = None, timeout : int = 10,
+    allow_redirects : bool = True, expected_status_codes : Set[int] = EXPECTED_STATUS_CODES,
+    logger : Optional[logging.Logger] = None
+) -> Optional[Union[Dict, List]]:
+    return do_rest_request(
+        RestRequestMethod.DELETE, url, body=body, timeout=timeout, allow_redirects=allow_redirects,
+        expected_status_codes=expected_status_codes, logger=logger
+    )
diff --git a/src/tests/ofc25-camara-agg-net-controller/tests/__init__.py b/src/tests/ofc25-camara-agg-net-controller/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ccc21c7db78aac26daa1f8c5ff8e1ffd3f35460
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/tests/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/tests/ofc25-camara-agg-net-controller/tests/test_agg_net_ietf_slice_operations.py b/src/tests/ofc25-camara-agg-net-controller/tests/test_agg_net_ietf_slice_operations.py
new file mode 100644
index 0000000000000000000000000000000000000000..d15a8bbb6d3e9007da24985c6d452e80f9b7db5a
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/tests/test_agg_net_ietf_slice_operations.py
@@ -0,0 +1,206 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json, logging, os
+import requests
+from deepdiff import DeepDiff
+
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+HEADERS = {"Content-Type": "application/json"}
+
+TARGET_L3VPN_SLICE1_STAGES = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "target-l3vpn-slice1-stages.json",
+)
+
+TARGET_L3VPN_SLICE2_STAGES = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "target-l3vpn-slice2-stages.json",
+)
+
+OP1_IETF_SLICE = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "pc1_slice1_post_ietf_network_slice.json",
+)
+
+OP2_IETF_SLICE = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "pc2_slice1_put_ietf_network_slice.json",
+)
+
+OP3_IETF_SLICE = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "pc1_slice2_post_ietf_network_slice.json",
+)
+
+OP4_IETF_SLICE = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "pc2_slice2_put_ietf_network_slice.json",
+)
+
+OP6_IETF_SLICE = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "pc1_slice1_put_ietf_network_slice.json",
+)
+
+OP8_IETF_SLICE = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "pc1_slice2_put_ietf_network_slice.json",
+)
+
+NBI_ADDRESS = "localhost"
+NBI_PORT = "80"
+NBI_USERNAME = "admin"
+NBI_PASSWORD = "admin"
+
+IP_ADDRESS = "localhost"
+IP_PORT = 9092
+
+BASE_IETF_SLICE_URL = f"http://{NBI_ADDRESS}:{NBI_PORT}/restconf/data/ietf-network-slice-service:network-slice-services"
+IP_L3VPN_URL = f"http://{IP_ADDRESS}:{IP_PORT}/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services"
+
+# pylint: disable=redefined-outer-name, unused-argument
+def test_ietf_slice_creation_removal():
+    # Issue service creation request
+    with open(OP1_IETF_SLICE, "r", encoding="UTF-8") as f:
+        op1_ietf_slice = json.load(f)
+    with open(OP2_IETF_SLICE, "r", encoding="UTF-8") as f:
+        op2_ietf_slice = json.load(f)
+    with open(OP3_IETF_SLICE, "r", encoding="UTF-8") as f:
+        op3_ietf_slice = json.load(f)
+    with open(OP4_IETF_SLICE, "r", encoding="UTF-8") as f:
+        op4_ietf_slice = json.load(f)
+    with open(OP6_IETF_SLICE, "r", encoding="UTF-8") as f:
+        op6_ietf_slice = json.load(f)
+    with open(OP8_IETF_SLICE, "r", encoding="UTF-8") as f:
+        op8_ietf_slice = json.load(f)
+    with open(TARGET_L3VPN_SLICE1_STAGES, "r", encoding="UTF-8") as f:
+        target_l3vpn_slice1_stages = json.load(f)
+    with open(TARGET_L3VPN_SLICE2_STAGES, "r", encoding="UTF-8") as f:
+        target_l3vpn_slice2_stages = json.load(f)
+
+    # op 1
+    URL = BASE_IETF_SLICE_URL
+    requests.post(URL, headers=HEADERS, json=op1_ietf_slice)
+
+    URL = IP_L3VPN_URL
+    l3vpns = requests.get(URL).json()
+
+    slice_name = "slice1"
+    diff = DeepDiff(target_l3vpn_slice1_stages[0], l3vpns[slice_name])
+    assert not diff
+
+    # op 2
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice1/connection-groups/connection-group=line1"
+    requests.put(URL, headers=HEADERS, json=op2_ietf_slice)
+
+    URL = IP_L3VPN_URL
+    l3vpns = requests.get(URL).json()
+
+    slice_name = "slice1"
+    diff = DeepDiff(target_l3vpn_slice1_stages[1], l3vpns[slice_name])
+    assert not diff
+
+    # op 3
+    URL = BASE_IETF_SLICE_URL
+    requests.post(URL, headers=HEADERS, json=op3_ietf_slice)
+
+    URL = IP_L3VPN_URL
+    l3vpns = requests.get(URL).json()
+
+    slice_name = "slice2"
+    diff = DeepDiff(target_l3vpn_slice2_stages[0], l3vpns[slice_name])
+    assert not diff
+
+    # op 4
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice2/connection-groups/connection-group=line1"
+    requests.put(URL, headers=HEADERS, json=op4_ietf_slice)
+
+    URL = IP_L3VPN_URL
+    l3vpns = requests.get(URL).json()
+
+    slice_name = "slice2"
+    diff = DeepDiff(target_l3vpn_slice2_stages[1], l3vpns[slice_name])
+    assert not diff
+
+    # op 5
+
+
+    # op 6
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice1/connection-groups/connection-group=line1"
+    requests.put(URL, headers=HEADERS, json=op6_ietf_slice)
+
+    URL = IP_L3VPN_URL
+    l3vpns = requests.get(URL).json()
+
+    slice_name = "slice1"
+    diff = DeepDiff(target_l3vpn_slice1_stages[2], l3vpns[slice_name])
+    assert not diff
+
+    # op 7
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice1"
+    requests.delete(URL)
+
+    URL = IP_L3VPN_URL
+    l3vpns = requests.get(URL).json()
+
+    slice_name = "slice1"
+    assert slice_name not in l3vpns
+
+    # op 8
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice2/connection-groups/connection-group=line1"
+    requests.put(URL, headers=HEADERS, json=op8_ietf_slice)
+
+    URL = IP_L3VPN_URL
+    l3vpns = requests.get(URL).json()
+
+    slice_name = "slice2"
+    diff = DeepDiff(target_l3vpn_slice2_stages[2], l3vpns[slice_name])
+    assert not diff
+
+    # op 9
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice2"
+    requests.delete(URL)
+
+    URL = IP_L3VPN_URL
+    l3vpns = requests.get(URL).json()
+
+    slice_name = "slice2"
+    assert slice_name not in l3vpns
+
+    # op 10
+
+    URL = IP_L3VPN_URL
+    l3vpns = requests.get(URL).json()
+
+    assert not l3vpns
diff --git a/src/tests/ofc25-camara-agg-net-controller/tests/test_onboarding.py b/src/tests/ofc25-camara-agg-net-controller/tests/test_onboarding.py
new file mode 100644
index 0000000000000000000000000000000000000000..7173ddacc6e6a06aad9cba099a2cb26bab56f7a9
--- /dev/null
+++ b/src/tests/ofc25-camara-agg-net-controller/tests/test_onboarding.py
@@ -0,0 +1,67 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging, os, time
+from common.Constants import DEFAULT_CONTEXT_NAME
+from common.proto.context_pb2 import ContextId, DeviceOperationalStatusEnum, Empty
+from common.tools.descriptor.Loader import DescriptorLoader, check_descriptor_load_results, validate_empty_scenario
+from common.tools.object_factory.Context import json_context_id
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from .Fixtures import context_client, device_client # pylint: disable=unused-import
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+DESCRIPTOR_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'data', 'agg-net-descriptor.json')
+ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME))
+
+def test_scenario_onboarding(
+    context_client : ContextClient, # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,   # pylint: disable=redefined-outer-name
+) -> None:
+    validate_empty_scenario(context_client)
+
+    descriptor_loader = DescriptorLoader(
+        descriptors_file=DESCRIPTOR_FILE, context_client=context_client, device_client=device_client)
+    results = descriptor_loader.process()
+    check_descriptor_load_results(results, descriptor_loader)
+    # descriptor_loader.validate()
+
+    # Verify the scenario has no services/slices
+    response = context_client.GetContext(ADMIN_CONTEXT_ID)
+    assert len(response.service_ids) == 0
+    assert len(response.slice_ids) == 0
+
+def test_scenario_devices_enabled(
+    context_client : ContextClient,         # pylint: disable=redefined-outer-name
+) -> None:
+    """
+    This test validates that the devices are enabled.
+    """
+    DEVICE_OP_STATUS_ENABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
+
+    num_devices = -1
+    num_devices_enabled, num_retry = 0, 0
+    while (num_devices != num_devices_enabled) and (num_retry < 10):
+        time.sleep(1.0)
+        response = context_client.ListDevices(Empty())
+        num_devices = len(response.devices)
+        num_devices_enabled = 0
+        for device in response.devices:
+            if device.device_operational_status != DEVICE_OP_STATUS_ENABLED: continue
+            num_devices_enabled += 1
+        LOGGER.info('Num Devices enabled: {:d}/{:d}'.format(num_devices_enabled, num_devices))
+        num_retry += 1
+    assert num_devices_enabled == num_devices
diff --git a/src/tests/ofc25-camara-e2e-controller/.gitignore b/src/tests/ofc25-camara-e2e-controller/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..24a4b233365e23a9462f4b64e8b60fef6a62bee4
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/.gitignore
@@ -0,0 +1,5 @@
+clab-*/
+images/
+*.clab.yml.bak
+*.tar
+*.tar.gz
diff --git a/src/tests/ofc25-camara-e2e-controller/.gitlab-ci.yml b/src/tests/ofc25-camara-e2e-controller/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c78468180ee8fdf855c0dd096031d49bd53ceec3
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/.gitlab-ci.yml
@@ -0,0 +1,101 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Deploy TeraFlowSDN and Execute end-2-end test
+end2end_test ofc25_camara_e2e:
+  variables:
+    TEST_NAME: 'ofc25-camara-e2e-controller'
+    NCE_NAME: 'nce'
+    AGG_NET_NAME: 'agg_net'
+    NCE_PORT: '9090'
+    AGG_NET_PORT: '9091'
+  stage: end2end_test
+  # Disable to force running it after all other tasks
+  before_script:
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+    - HOST_IP=$(kubectl get nodes -o json | jq -r '.items[].status.addresses[] | select(.type=="InternalIP") | .address')
+    - sed -i "s/AGG_NET_IP/${HOST_IP}/g" src/tests/${TEST_NAME}/data/camara-e2e-topology.json
+    - sed -i "s/NCE_IP/${HOST_IP}/g" src/tests/${TEST_NAME}/data/camara-e2e-topology.json
+    - sed -i "s/AGG_NET_PORT/${AGG_NET_PORT}/g" src/tests/${TEST_NAME}/data/camara-e2e-topology.json
+    - sed -i "s/NCE_PORT/${NCE_PORT}/g" src/tests/${TEST_NAME}/data/camara-e2e-topology.json
+    - docker buildx build -t "${TEST_NAME}:latest" -f ./src/tests/${TEST_NAME}/Dockerfile .
+    - docker buildx build -t "${NCE_NAME}:latest" -f ./src/tests/tools/mock_nce_ctrl/Dockerfile ./src/tests/tools/mock_nce_ctrl
+    - docker buildx build -t "${AGG_NET_NAME}:latest" -f ./src/tests/tools/mock_ietf_network_slice_sdn_ctrl/Dockerfile ./src/tests/tools/mock_ietf_network_slice_sdn_ctrl
+    - docker rm -f ${TEST_NAME} || true
+    - docker rm -f ${AGG_NET_NAME} || true
+    - docker rm -f ${NCE_NAME} || true
+    - docker run -d --name ${NCE_NAME} -p ${NCE_PORT}:8443 ${NCE_NAME}:latest
+    - docker run -d --name ${AGG_NET_NAME} -p ${AGG_NET_PORT}:8443 ${AGG_NET_NAME}:latest
+
+  script:
+    # Check MicroK8s is ready
+    - microk8s status --wait-ready
+    - kubectl get pods --all-namespaces
+
+    - source src/tests/${TEST_NAME}/deploy_specs.sh
+
+    # Deploy TeraFlowSDN
+    - ./deploy/crdb.sh
+    - ./deploy/nats.sh
+    - ./deploy/qdb.sh
+    - ./deploy/kafka.sh
+    - ./deploy/tfs.sh
+    - ./deploy/show.sh
+
+    - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server
+
+    # Run end-to-end test: onboard scenario
+    - >
+      docker run -t --rm --name ${TEST_NAME} --network=host
+      --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh"
+      --volume "$PWD/src/tests/${TEST_NAME}:/opt/results"
+      ${TEST_NAME}:latest /var/teraflow/run-onboarding.sh
+
+    # Run end-to-end test: configure service TFS
+    - >
+      docker run -t --rm --name ${TEST_NAME} --network=host
+      --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh"
+      --volume "$PWD/src/tests/${TEST_NAME}:/opt/results"
+      ${TEST_NAME}:latest /var/teraflow/run-e2e-ietf-slice-operations.sh
+
+  after_script:
+    - kubectl --namespace tfs logs deployment/contextservice -c server
+    - kubectl --namespace tfs logs deployment/deviceservice -c server
+    - kubectl --namespace tfs logs deployment/pathcompservice -c frontend
+    - kubectl --namespace tfs logs deployment/serviceservice -c server
+    - kubectl --namespace tfs logs deployment/sliceservice -c server
+    - kubectl --namespace tfs logs deployment/nbiservice -c server
+
+    - docker logs ${NCE_NAME}
+
+    - docker logs ${AGG_NET_NAME}
+
+    # Destroy Scenario
+    - kubectl delete namespaces tfs || true
+
+    - docker rm -f ${TEST_NAME} || true
+    - docker rm -f ${AGG_NET_NAME} || true
+    - docker rm -f ${NCE_NAME} || true
+
+    # Clean old docker images
+    - docker images --filter="dangling=true" --quiet | xargs -r docker rmi
+
+  #coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
+    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"'
+  artifacts:
+      when: always
+      reports:
+        junit: ./src/tests/${TEST_NAME}/report_*.xml
diff --git a/src/tests/ofc25-camara-e2e-controller/Dockerfile b/src/tests/ofc25-camara-e2e-controller/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..79b709c13dc352bb853bbe626183e72d37a074f0
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/Dockerfile
@@ -0,0 +1,84 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+FROM python:3.9-slim
+
+# Install dependencies
+RUN apt-get --yes --quiet --quiet update && \
+    apt-get --yes --quiet --quiet install wget g++ git && \
+    rm -rf /var/lib/apt/lists/*
+
+# Set Python to show logs as they occur
+ENV PYTHONUNBUFFERED=0
+
+# Get generic Python packages
+RUN python3 -m pip install --upgrade pip
+RUN python3 -m pip install --upgrade setuptools wheel
+RUN python3 -m pip install --upgrade pip-tools
+
+# Get common Python packages
+# Note: this step enables sharing the previous Docker build steps among all the Python components
+WORKDIR /var/teraflow
+COPY common_requirements.in common_requirements.in
+RUN pip-compile --quiet --output-file=common_requirements.txt common_requirements.in
+RUN python3 -m pip install -r common_requirements.txt
+
+# Add common files into working directory
+WORKDIR /var/teraflow/common
+COPY src/common/. ./
+RUN rm -rf proto
+
+# Create proto sub-folder, copy .proto files, and generate Python code
+RUN mkdir -p /var/teraflow/common/proto
+WORKDIR /var/teraflow/common/proto
+RUN touch __init__.py
+COPY proto/*.proto ./
+RUN python3 -m grpc_tools.protoc -I=. --python_out=. --grpc_python_out=. *.proto
+RUN rm *.proto
+RUN find . -type f -exec sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' {} \;
+
+# Create component sub-folders, get specific Python packages
+RUN mkdir -p /var/teraflow/tests/ofc25-camara-e2e-controller
+WORKDIR /var/teraflow/tests/ofc25-camara-e2e-controller
+COPY src/tests/ofc25-camara-e2e-controller/requirements.in requirements.in
+RUN pip-compile --quiet --output-file=requirements.txt requirements.in
+RUN python3 -m pip install -r requirements.txt
+
+# Add component files into working directory
+WORKDIR /var/teraflow
+COPY src/__init__.py ./__init__.py
+COPY src/common/*.py ./common/
+COPY src/common/tests/. ./common/tests/
+COPY src/common/tools/. ./common/tools/
+COPY src/context/__init__.py context/__init__.py
+COPY src/context/client/. context/client/
+COPY src/device/__init__.py device/__init__.py
+COPY src/device/client/. device/client/
+COPY src/monitoring/__init__.py monitoring/__init__.py
+COPY src/monitoring/client/. monitoring/client/
+COPY src/service/__init__.py service/__init__.py
+COPY src/service/client/. service/client/
+COPY src/slice/__init__.py slice/__init__.py
+COPY src/slice/client/. slice/client/
+COPY src/tests/*.py ./tests/
+COPY src/tests/ofc25-camara-e2e-controller/__init__.py ./tests/ofc25-camara-e2e-controller/__init__.py
+COPY src/tests/ofc25-camara-e2e-controller/data/. ./tests/ofc25-camara-e2e-controller/data/
+COPY src/tests/ofc25-camara-e2e-controller/tests/. ./tests/ofc25-camara-e2e-controller/tests/
+COPY src/tests/ofc25-camara-e2e-controller/scripts/. ./
+
+RUN apt-get --yes --quiet --quiet update && \
+    apt-get --yes --quiet --quiet install tree && \
+    rm -rf /var/lib/apt/lists/*
+
+RUN tree -la /var/teraflow
diff --git a/src/tests/ofc25-camara-e2e-controller/__init__.py b/src/tests/ofc25-camara-e2e-controller/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ccc21c7db78aac26daa1f8c5ff8e1ffd3f35460
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/tests/ofc25-camara-e2e-controller/data/camara-e2e-topology.json b/src/tests/ofc25-camara-e2e-controller/data/camara-e2e-topology.json
new file mode 100644
index 0000000000000000000000000000000000000000..b2a8617e2c3e211a3e0ef1facb05b40788aa82cf
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/data/camara-e2e-topology.json
@@ -0,0 +1,1725 @@
+{
+  "contexts": [
+    {
+      "context_id": {
+        "context_uuid": {
+          "uuid": "admin"
+        }
+      }
+    }
+  ],
+  "topologies": [
+    {
+      "topology_id": {
+        "context_id": {
+          "context_uuid": {
+            "uuid": "admin"
+          }
+        },
+        "topology_uuid": {
+          "uuid": "admin"
+        }
+      }
+    }
+  ],
+  "devices": [
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "ip-transport-controller"
+        }
+      },
+      "name": "ip-transport-controller",
+      "device_type": "ietf-slice",
+      "device_operational_status": 1,
+      "device_drivers": [
+        14
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "AGG_NET_IP"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "AGG_NET_PORT"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  }
+                ],
+                "scheme": "http",
+                "username": "admin",
+                "password": "admin",
+                "base_url": "/restconf/v2/data",
+                "timeout": 120,
+                "verify": false
+              }
+            }
+          }
+        ]
+      },
+      "device_endpoints": []
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "agg-net-controller"
+        }
+      },
+      "name": "agg-net-controller",
+      "device_type": "ietf-slice",
+      "device_operational_status": 1,
+      "device_drivers": [
+        14
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "AGG_NET_IP"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "AGG_NET_PORT"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  }
+                ],
+                "scheme": "http",
+                "username": "admin",
+                "password": "admin",
+                "base_url": "/restconf/v2/data",
+                "timeout": 120,
+                "verify": false
+              }
+            }
+          }
+        ]
+      },
+      "device_endpoints": []
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "nce-controller"
+        }
+      },
+      "name": "nce-controller",
+      "device_type": "nce",
+      "device_operational_status": 1,
+      "device_drivers": [
+        15
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "NCE_IP"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "NCE_PORT"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  }
+                ],
+                "scheme": "http",
+                "username": "admin",
+                "password": "admin",
+                "base_url": "/restconf/v2/data",
+                "timeout": 120,
+                "verify": false
+              }
+            }
+          }
+        ]
+      },
+      "device_endpoints": []
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.182.25"
+        }
+      },
+      "name": "172.16.182.25",
+      "device_type": "emu-packet-router",
+      "controller_id": {
+        "device_uuid": {
+          "uuid": "ip-transport-controller"
+        }
+      },
+      "device_operational_status": 1,
+      "device_drivers": [
+        0,
+        14
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  },
+                  {
+                    "uuid": "200",
+                    "name": "200",
+                    "type": "optical",
+                    "address_ip": "128.32.33.254",
+                    "address_prefix": "24",
+                    "site_location": "access",
+                    "mtu": "1500"
+                  },
+                  {
+                    "uuid": "500",
+                    "name": "500",
+                    "type": "optical"
+                  },
+                  {
+                    "uuid": "501",
+                    "name": "501",
+                    "type": "optical"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.185.31"
+        }
+      },
+      "name": "172.16.185.31",
+      "device_type": "emu-packet-router",
+      "controller_id": {
+        "device_uuid": {
+          "uuid": "ip-transport-controller"
+        }
+      },
+      "device_operational_status": 1,
+      "device_drivers": [
+        0,
+        14
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  },
+                  {
+                    "uuid": "500",
+                    "name": "500",
+                    "type": "optical"
+                  },
+                  {
+                    "uuid": "501",
+                    "name": "501",
+                    "type": "optical"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.185.33"
+        }
+      },
+      "name": "172.16.185.33",
+      "device_type": "emu-packet-router",
+      "controller_id": {
+        "device_uuid": {
+          "uuid": "ip-transport-controller"
+        }
+      },
+      "device_operational_status": 1,
+      "device_drivers": [
+        0,
+        14
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  },
+                  {
+                    "uuid": "500",
+                    "name": "500",
+                    "type": "optical"
+                  },
+                  {
+                    "uuid": "501",
+                    "name": "501",
+                    "type": "optical"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.185.32"
+        }
+      },
+      "name": "172.16.185.32",
+      "device_type": "emu-packet-router",
+      "controller_id": {
+        "device_uuid": {
+          "uuid": "ip-transport-controller"
+        }
+      },
+      "device_operational_status": 1,
+      "device_drivers": [
+        0,
+        14
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  },
+                  {
+                    "uuid": "200",
+                    "name": "200",
+                    "type": "optical",
+                    "ce-ip": "172.10.33.2",
+                    "address_ip": "172.10.33.254",
+                    "address_prefix": "24",
+                    "site_location": "cloud",
+                    "mtu": "1500"
+                  },
+                  {
+                    "uuid": "500",
+                    "name": "500",
+                    "type": "optical"
+                  },
+                  {
+                    "uuid": "501",
+                    "name": "501",
+                    "type": "optical"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.58.10"
+        }
+      },
+      "name": "172.16.58.10",
+      "device_type": "emu-packet-router",
+      "controller_id": {
+        "device_uuid": {
+          "uuid": "nce-controller"
+        }
+      },
+      "device_operational_status": 1,
+      "device_drivers": [
+        15
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  },
+                  {
+                    "uuid": "200",
+                    "name": "200",
+                    "type": "optical",
+                    "address_ip": "0.0.0.0",
+                    "address_prefix": "24"
+                  },
+                  {
+                    "uuid": "201",
+                    "name": "201",
+                    "type": "optical",
+                    "address_ip": "0.0.0.0",
+                    "address_prefix": "24"
+                  },
+                  {
+                    "uuid": "500",
+                    "name": "500",
+                    "type": "optical",
+                    "address_ip": "128.32.33.2",
+                    "address_prefix": "24"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.61.10"
+        }
+      },
+      "name": "172.16.61.10",
+      "device_type": "emu-packet-router",
+      "controller_id": {
+        "device_uuid": {
+          "uuid": "nce-controller"
+        }
+      },
+      "device_operational_status": 1,
+      "device_drivers": [
+        15
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  },
+                  {
+                    "uuid": "200",
+                    "name": "200",
+                    "type": "optical",
+                    "address_ip": "0.0.0.0",
+                    "address_prefix": "24"
+                  },
+                  {
+                    "uuid": "500",
+                    "name": "500",
+                    "type": "optical",
+                    "address_ip": "128.32.33.2",
+                    "address_prefix": "24"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.61.11"
+        }
+      },
+      "name": "172.16.61.11",
+      "device_type": "emu-packet-router",
+      "controller_id": {
+        "device_uuid": {
+          "uuid": "nce-controller"
+        }
+      },
+      "device_operational_status": 1,
+      "device_drivers": [
+        15
+      ],
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "uuid": "mgmt",
+                    "name": "mgmt",
+                    "type": "mgmt"
+                  },
+                  {
+                    "uuid": "200",
+                    "name": "200",
+                    "type": "optical",
+                    "address_ip": "0.0.0.0",
+                    "address_prefix": "24"
+                  },
+                  {
+                    "uuid": "500",
+                    "name": "500",
+                    "type": "optical",
+                    "address_ip": "128.32.33.2",
+                    "address_prefix": "24"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.104.221"
+        }
+      },
+      "device_type": "emu-datacenter",
+      "device_drivers": [
+        0
+      ],
+      "device_endpoints": [],
+      "device_operational_status": 1,
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "sample_types": [],
+                    "type": "copper",
+                    "uuid": "eth0"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.104.222"
+        }
+      },
+      "device_type": "emu-datacenter",
+      "device_drivers": [
+        0
+      ],
+      "device_endpoints": [],
+      "device_operational_status": 1,
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "sample_types": [],
+                    "type": "copper",
+                    "uuid": "eth0"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "device_id": {
+        "device_uuid": {
+          "uuid": "172.16.204.220"
+        }
+      },
+      "device_type": "emu-datacenter",
+      "device_drivers": [
+        0
+      ],
+      "device_endpoints": [],
+      "device_operational_status": 1,
+      "device_config": {
+        "config_rules": [
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/address",
+              "resource_value": "127.0.0.1"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/port",
+              "resource_value": "0"
+            }
+          },
+          {
+            "action": 1,
+            "custom": {
+              "resource_key": "_connect/settings",
+              "resource_value": {
+                "endpoints": [
+                  {
+                    "sample_types": [],
+                    "type": "optical",
+                    "uuid": "500"
+                  },
+                  {
+                    "sample_types": [],
+                    "type": "optical",
+                    "uuid": "200"
+                  },
+                  {
+                    "sample_types": [],
+                    "type": "optical",
+                    "uuid": "201"
+                  }
+                ]
+              }
+            }
+          }
+        ]
+      }
+    }
+  ],
+  "links": [
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "agg-net-controller/mgmt==ip-transport-controller/mgmt"
+        }
+      },
+      "name": "agg-net-controller/mgmt==ip-transport-controller/mgmt",
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "agg-net-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "ip-transport-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "nce-controller/mgmt==172.16.61.11/mgmt"
+        }
+      },
+      "name": "nce-controller/mgmt==172.16.61.11/mgmt",
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "nce-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.11"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "nce-controller/mgmt==172.16.61.10/mgmt"
+        }
+      },
+      "name": "nce-controller/mgmt==172.16.61.10/mgmt",
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "nce-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "nce-controller/mgmt==172.16.58.10/mgmt"
+        }
+      },
+      "name": "nce-controller/mgmt==172.16.58.10/mgmt",
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "nce-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.58.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "ip-transport-controller/mgmt==172.16.185.33/mgmt"
+        }
+      },
+      "name": "ip-transport-controller/mgmt==172.16.185.33/mgmt",
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "ip-transport-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.33"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "ip-transport-controller/mgmt==172.16.185.31/mgmt"
+        }
+      },
+      "name": "ip-transport-controller/mgmt==172.16.185.31/mgmt",
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "ip-transport-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.31"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "ip-transport-controller/mgmt==172.16.185.32/mgmt"
+        }
+      },
+      "name": "ip-transport-controller/mgmt==172.16.185.32/mgmt",
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "ip-transport-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.32"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "ip-transport-controller/mgmt==172.16.182.25/mgmt"
+        }
+      },
+      "name": "ip-transport-controller/mgmt==172.16.182.25/mgmt",
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "ip-transport-controller"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.182.25"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "mgmt"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.182.25-500"
+        }
+      },
+      "name": "172.16.182.25-500",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.182.25"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.33"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.185.33-500"
+        }
+      },
+      "name": "172.16.185.33-500",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.33"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.182.25"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.182.25-501"
+        }
+      },
+      "name": "172.16.182.25-501",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.182.25"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "501"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.31"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "501"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.185.31-501"
+        }
+      },
+      "name": "172.16.185.31-501",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.31"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "501"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.182.25"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "501"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.185.31-500"
+        }
+      },
+      "name": "172.16.185.31-500",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.31"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.32"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.185.32-500"
+        }
+      },
+      "name": "172.16.185.32-500",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.32"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.31"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.185.33-501"
+        }
+      },
+      "name": "172.16.185.33-501",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.33"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "501"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.32"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "501"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.185.32-501"
+        }
+      },
+      "name": "172.16.185.32-501",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.32"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "501"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.33"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "501"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.185.32-200"
+        }
+      },
+      "name": "172.16.185.32-200",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.32"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.204.220"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.204.220-500"
+        }
+      },
+      "name": "172.16.204.220-500",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.204.220"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.185.32"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.182.25-200"
+        }
+      },
+      "name": "172.16.182.25-200",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.182.25"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.58.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.58.10-500"
+        }
+      },
+      "name": "172.16.58.10-500",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.58.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.182.25"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.58.10-200"
+        }
+      },
+      "name": "172.16.58.10-200",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.58.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.61.10-500"
+        }
+      },
+      "name": "172.16.61.10-500",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.58.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.58.10-201"
+        }
+      },
+      "name": "172.16.58.10-201",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.58.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "201"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.11"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.61.11-500"
+        }
+      },
+      "name": "172.16.61.11-500",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.11"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "500"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.58.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "201"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.61.10-200"
+        }
+      },
+      "name": "172.16.61.10-200",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.104.221"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "eth0"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.104.221-eth0"
+        }
+      },
+      "name": "172.16.104.221-eth0",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.104.221"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "eth0"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.10"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.61.11-200"
+        }
+      },
+      "name": "172.16.61.11-200",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.11"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.104.222"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "eth0"
+          }
+        }
+      ]
+    },
+    {
+      "link_id": {
+        "link_uuid": {
+          "uuid": "172.16.104.222-eth0"
+        }
+      },
+      "name": "172.16.104.222-eth0",
+      "attributes": {
+        "total_capacity_gbps": 10,
+        "used_capacity_gbps": 0
+      },
+      "link_endpoint_ids": [
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.104.222"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "eth0"
+          }
+        },
+        {
+          "device_id": {
+            "device_uuid": {
+              "uuid": "172.16.61.11"
+            }
+          },
+          "endpoint_uuid": {
+            "uuid": "200"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/src/tests/ofc25-camara-e2e-controller/data/slice/post_connection_group_to_network_slice1.json b/src/tests/ofc25-camara-e2e-controller/data/slice/post_connection_group_to_network_slice1.json
new file mode 100644
index 0000000000000000000000000000000000000000..d39a837bd8c3719463e8ecfd3fbfc2d25111afef
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/data/slice/post_connection_group_to_network_slice1.json
@@ -0,0 +1,62 @@
+{
+    "connection-group": [
+        {
+            "id": "line2",
+            "connectivity-type": "point-to-point",
+            "connectivity-construct": [
+                {
+                    "id": 1,
+                    "p2p-sender-sdp": "1",
+                    "p2p-receiver-sdp": "3",
+                    "service-slo-sle-policy": {
+                        "slo-policy": {
+                            "metric-bound": [
+                                {
+                                    "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                                    "metric-unit": "milliseconds",
+                                    "bound": "10"
+                                },
+                                {
+                                    "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                                    "metric-unit": "Mbps",
+                                    "bound": "5000"
+                                },
+                                {
+                                    "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                                    "metric-unit": "percentage",
+                                    "percentile-value": "0.001"
+                                }
+                            ]
+                        }
+                    }
+                },
+                {
+                    "id": 2,
+                    "p2p-sender-sdp": "3",
+                    "p2p-receiver-sdp": "1",
+                    "service-slo-sle-policy": {
+                        "slo-policy": {
+                            "metric-bound": [
+                                {
+                                    "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                                    "metric-unit": "milliseconds",
+                                    "bound": "20"
+                                },
+                                {
+                                    "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                                    "metric-unit": "Mbps",
+                                    "bound": "1000"
+                                },
+                                {
+                                    "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                                    "metric-unit": "percentage",
+                                    "percentile-value": "0.001"
+                                }
+                            ]
+                        }
+                    }
+                }
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/tests/ofc25-camara-e2e-controller/data/slice/post_connection_group_to_network_slice2.json b/src/tests/ofc25-camara-e2e-controller/data/slice/post_connection_group_to_network_slice2.json
new file mode 100644
index 0000000000000000000000000000000000000000..d39a837bd8c3719463e8ecfd3fbfc2d25111afef
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/data/slice/post_connection_group_to_network_slice2.json
@@ -0,0 +1,62 @@
+{
+    "connection-group": [
+        {
+            "id": "line2",
+            "connectivity-type": "point-to-point",
+            "connectivity-construct": [
+                {
+                    "id": 1,
+                    "p2p-sender-sdp": "1",
+                    "p2p-receiver-sdp": "3",
+                    "service-slo-sle-policy": {
+                        "slo-policy": {
+                            "metric-bound": [
+                                {
+                                    "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                                    "metric-unit": "milliseconds",
+                                    "bound": "10"
+                                },
+                                {
+                                    "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                                    "metric-unit": "Mbps",
+                                    "bound": "5000"
+                                },
+                                {
+                                    "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                                    "metric-unit": "percentage",
+                                    "percentile-value": "0.001"
+                                }
+                            ]
+                        }
+                    }
+                },
+                {
+                    "id": 2,
+                    "p2p-sender-sdp": "3",
+                    "p2p-receiver-sdp": "1",
+                    "service-slo-sle-policy": {
+                        "slo-policy": {
+                            "metric-bound": [
+                                {
+                                    "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                                    "metric-unit": "milliseconds",
+                                    "bound": "20"
+                                },
+                                {
+                                    "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                                    "metric-unit": "Mbps",
+                                    "bound": "1000"
+                                },
+                                {
+                                    "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                                    "metric-unit": "percentage",
+                                    "percentile-value": "0.001"
+                                }
+                            ]
+                        }
+                    }
+                }
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/tests/ofc25-camara-e2e-controller/data/slice/post_match_criteria_to_sdp1_in_slice1.json b/src/tests/ofc25-camara-e2e-controller/data/slice/post_match_criteria_to_sdp1_in_slice1.json
new file mode 100644
index 0000000000000000000000000000000000000000..16a36d45b86230b27eafa45a612b95c248a7b3ac
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/data/slice/post_match_criteria_to_sdp1_in_slice1.json
@@ -0,0 +1,40 @@
+{
+    "match-criterion": [
+        {
+            "index": 2,
+            "match-type": [
+                {
+                    "type": "ietf-network-slice-service:vlan",
+                    "value": [
+                        "101"
+                    ]
+                },
+                {
+                    "type": "ietf-network-slice-service:source-ip-prefix",
+                    "value": [
+                        "172.1.101.22/24"
+                    ]
+                },
+                {
+                    "type": "ietf-network-slice-service:source-tcp-port",
+                    "value": [
+                        "10200"
+                    ]
+                },
+                {
+                    "type": "ietf-network-slice-service:destination-ip-prefix",
+                    "value": [
+                        "172.16.104.222/24"
+                    ]
+                },
+                {
+                    "type": "ietf-network-slice-service:destination-tcp-port",
+                    "value": [
+                        "10500"
+                    ]
+                }
+            ],
+            "target-connection-group-id": "line2"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/tests/ofc25-camara-e2e-controller/data/slice/post_match_criteria_to_sdp1_in_slice2.json b/src/tests/ofc25-camara-e2e-controller/data/slice/post_match_criteria_to_sdp1_in_slice2.json
new file mode 100644
index 0000000000000000000000000000000000000000..8ceefdc2f2471af225143e5a1def2d7ba71e2ab1
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/data/slice/post_match_criteria_to_sdp1_in_slice2.json
@@ -0,0 +1,40 @@
+{
+    "match-criterion": [
+        {
+            "index": 2,
+            "match-type": [
+                {
+                    "type": "ietf-network-slice-service:vlan",
+                    "value": [
+                        "201"
+                    ]
+                },
+                {
+                    "type": "ietf-network-slice-service:source-ip-prefix",
+                    "value": [
+                        "172.1.201.22/24"
+                    ]
+                },
+                {
+                    "type": "ietf-network-slice-service:source-tcp-port",
+                    "value": [
+                        "10200"
+                    ]
+                },
+                {
+                    "type": "ietf-network-slice-service:destination-ip-prefix",
+                    "value": [
+                        "172.16.104.222/24"
+                    ]
+                },
+                {
+                    "type": "ietf-network-slice-service:destination-tcp-port",
+                    "value": [
+                        "10500"
+                    ]
+                }
+            ],
+            "target-connection-group-id": "line2"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/tests/ofc25-camara-e2e-controller/data/slice/post_network_slice1.json b/src/tests/ofc25-camara-e2e-controller/data/slice/post_network_slice1.json
new file mode 100644
index 0000000000000000000000000000000000000000..e6e0ee90a25ff12f73c8f8896f9c2c74ab6b4019
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/data/slice/post_network_slice1.json
@@ -0,0 +1,188 @@
+{
+    "slice-service": [
+        {
+            "id": "slice1",
+            "description": "network slice 1, connect to VM1",
+            "sdps": {
+                "sdp": [
+                    {
+                        "id": "1",
+                        "node-id": "172.16.204.220",
+                        "sdp-ip-address": [
+                            "172.16.204.220"
+                        ],
+                        "service-match-criteria": {
+                            "match-criterion": [
+                                {
+                                    "index": 1,
+                                    "match-type": [
+                                        {
+                                            "type": "ietf-network-slice-service:vlan",
+                                            "value": [
+                                                "101"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:destination-ip-prefix",
+                                            "value": [
+                                                "172.16.104.221/24"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:destination-tcp-port",
+                                            "value": [
+                                                "10500"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:source-ip-prefix",
+                                            "value": [
+                                                "172.1.101.22/24"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:source-tcp-port",
+                                            "value": [
+                                                "10200"
+                                            ]
+                                        }
+                                    ],
+                                    "target-connection-group-id": "line1"
+                                }
+                            ]
+                        },
+                        "attachment-circuits": {
+                            "attachment-circuit": [
+                                {
+                                    "id": "AC POP to VM1",
+                                    "description": "AC VM1 connected to POP",
+                                    "ac-node-id": "172.16.204.220",
+                                    "ac-tp-id": "200"
+                                }
+                            ]
+                        }
+                    },
+                    {
+                        "id": "2",
+                        "node-id": "172.16.61.10",
+                        "sdp-ip-address": [
+                            "172.16.61.10"
+                        ],
+                        "service-match-criteria": {
+                            "match-criterion": [
+                                {
+                                    "index": 1,
+                                    "match-type": [
+                                        {
+                                            "type": "ietf-network-slice-service:vlan",
+                                            "value": [
+                                                "21"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:source-ip-prefix",
+                                            "value": [
+                                                "172.16.104.221/24"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:source-tcp-port",
+                                            "value": [
+                                                "10500"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:destination-ip-prefix",
+                                            "value": [
+                                                "172.1.101.22/24"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:destination-tcp-port",
+                                            "value": [
+                                                "10200"
+                                            ]
+                                        }
+                                    ],
+                                    "target-connection-group-id": "line1"
+                                }
+                            ]
+                        },
+                        "attachment-circuits": {
+                            "attachment-circuit": [
+                                {
+                                    "id": "AC ONT",
+                                    "description": "AC connected to PC1",
+                                    "ac-node-id": "172.16.61.10",
+                                    "ac-tp-id": "200"
+                                }
+                            ]
+                        }
+                    }
+                ]
+            },
+            "connection-groups": {
+                "connection-group": [
+                    {
+                        "id": "line1",
+                        "connectivity-type": "point-to-point",
+                        "connectivity-construct": [
+                            {
+                                "id": 1,
+                                "p2p-sender-sdp": "1",
+                                "p2p-receiver-sdp": "2",
+                                "service-slo-sle-policy": {
+                                    "slo-policy": {
+                                        "metric-bound": [
+                                            {
+                                                "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                                                "metric-unit": "milliseconds",
+                                                "bound": "10"
+                                            },
+                                            {
+                                                "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                                                "metric-unit": "Mbps",
+                                                "bound": "5000"
+                                            },
+                                            {
+                                                "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                                                "metric-unit": "percentage",
+                                                "percentile-value": "0.001"
+                                            }
+                                        ]
+                                    }
+                                }
+                            },
+                            {
+                                "id": 2,
+                                "p2p-sender-sdp": "2",
+                                "p2p-receiver-sdp": "1",
+                                "service-slo-sle-policy": {
+                                    "slo-policy": {
+                                        "metric-bound": [
+                                            {
+                                                "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                                                "metric-unit": "milliseconds",
+                                                "bound": "20"
+                                            },
+                                            {
+                                                "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                                                "metric-unit": "Mbps",
+                                                "bound": "1000"
+                                            },
+                                            {
+                                                "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                                                "metric-unit": "percentage",
+                                                "percentile-value": "0.001"
+                                            }
+                                        ]
+                                    }
+                                }
+                            }
+                        ]
+                    }
+                ]
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/tests/ofc25-camara-e2e-controller/data/slice/post_network_slice2.json b/src/tests/ofc25-camara-e2e-controller/data/slice/post_network_slice2.json
new file mode 100644
index 0000000000000000000000000000000000000000..97e6ade27449be0a3816085aa31b707ffbb6f813
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/data/slice/post_network_slice2.json
@@ -0,0 +1,189 @@
+{
+    "slice-service": [
+        {
+            "id": "slice2",
+            "description": "network slice 2, connect to VM2",
+            "sdps": {
+                "sdp": [
+                    {
+                        "id": "1",
+                        "node-id": "172.16.204.220",
+                        "sdp-ip-address": [
+                            "172.16.204.220"
+                        ],
+                        "service-match-criteria": {
+                            "match-criterion": [
+                                {
+                                    "index": 1,
+                                    "match-type": [
+                                        {
+                                            "type": "ietf-network-slice-service:vlan",
+                                            "value": [
+                                                "201"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:destination-ip-prefix",
+                                            "value": [
+                                                "172.16.104.221/24"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:destination-tcp-port",
+                                            "value": [
+                                                "10500"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:source-ip-prefix",
+                                            "value": [
+                                                "172.1.201.22/24"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:source-tcp-port",
+                                            "value": [
+                                                "10200"
+                                            ]
+                                        }
+                                    ],
+                                    "target-connection-group-id": "line1"
+                                }
+                            ]
+                        },
+                        "attachment-circuits": {
+                            "attachment-circuit": [
+                                {
+                                    "id": "AC POP to VM2",
+                                    "description": "AC VM2 connected to POP",
+                                    "ac-node-id": "172.16.204.220",
+                                    "ac-tp-id": "201"
+                                }
+                            ]
+                        }
+                    },
+                    {
+                        "id": "2",
+                        "node-id": "172.16.61.10",
+                        "sdp-ip-address": [
+                            "172.16.61.10"
+                        ],
+                        "service-match-criteria": {
+                            "match-criterion": [
+                                {
+                                    "index": 1,
+                                    "match-type": [
+                                        {
+                                            "type": "ietf-network-slice-service:vlan",
+                                            "value": [
+                                                "31"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:source-ip-prefix",
+                                            "value": [
+                                                "172.16.104.221/24"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:source-tcp-port",
+                                            "value": [
+                                                "10500"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:destination-ip-prefix",
+                                            "value": [
+                                                "172.1.201.22/24"
+                                            ]
+                                        },
+                                        {
+                                            "type": "ietf-network-slice-service:destination-tcp-port",
+                                            "value": [
+                                                "10200"
+                                            ]
+                                        }
+                                    ],
+                                    "target-connection-group-id": "line1"
+                                }
+                            ]
+                        },
+                        "attachment-circuits": {
+                            "attachment-circuit": [
+                                {
+                                    "id": "AC ONT",
+                                    "description": "AC connected to PC",
+                                    "ac-node-id": "172.16.61.10",
+                                    "ac-tp-id": "200",
+                                    "ac-ipv4-address": "172.16.61.10"
+                                }
+                            ]
+                        }
+                    }
+                ]
+            },
+            "connection-groups": {
+                "connection-group": [
+                    {
+                        "id": "line1",
+                        "connectivity-type": "point-to-point",
+                        "connectivity-construct": [
+                            {
+                                "id": 1,
+                                "p2p-sender-sdp": "1",
+                                "p2p-receiver-sdp": "2",
+                                "service-slo-sle-policy": {
+                                    "slo-policy": {
+                                        "metric-bound": [
+                                            {
+                                                "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                                                "metric-unit": "milliseconds",
+                                                "bound": "10"
+                                            },
+                                            {
+                                                "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                                                "metric-unit": "Mbps",
+                                                "bound": "5000"
+                                            },
+                                            {
+                                                "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                                                "metric-unit": "percentage",
+                                                "percentile-value": "0.001"
+                                            }
+                                        ]
+                                    }
+                                }
+                            },
+                            {
+                                "id": 2,
+                                "p2p-sender-sdp": "2",
+                                "p2p-receiver-sdp": "1",
+                                "service-slo-sle-policy": {
+                                    "slo-policy": {
+                                        "metric-bound": [
+                                            {
+                                                "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                                                "metric-unit": "milliseconds",
+                                                "bound": "20"
+                                            },
+                                            {
+                                                "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                                                "metric-unit": "Mbps",
+                                                "bound": "1000"
+                                            },
+                                            {
+                                                "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                                                "metric-unit": "percentage",
+                                                "percentile-value": "0.001"
+                                            }
+                                        ]
+                                    }
+                                }
+                            }
+                        ]
+                    }
+                ]
+            }
+        }
+    ]
+}
diff --git a/src/tests/ofc25-camara-e2e-controller/data/slice/post_sdp_to_network_slice1.json b/src/tests/ofc25-camara-e2e-controller/data/slice/post_sdp_to_network_slice1.json
new file mode 100644
index 0000000000000000000000000000000000000000..bd3895fc4ae5a9a0b2059be3f6b31a05451abd22
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/data/slice/post_sdp_to_network_slice1.json
@@ -0,0 +1,61 @@
+{
+    "sdp": [
+        {
+            "id": "3",
+            "node-id": "172.16.61.11",
+            "sdp-ip-address": [
+                "172.16.61.11"
+            ],
+            "service-match-criteria": {
+                "match-criterion": [
+                    {
+                        "index": 1,
+                        "match-type": [
+                            {
+                                "type": "ietf-network-slice-service:vlan",
+                                "value": [
+                                    "21"
+                                ]
+                            },
+                            {
+                                "type": "ietf-network-slice-service:source-ip-prefix",
+                                "value": [
+                                    "172.16.104.222/24"
+                                ]
+                            },
+                            {
+                                "type": "ietf-network-slice-service:source-tcp-port",
+                                "value": [
+                                    "10500"
+                                ]
+                            },
+                            {
+                                "type": "ietf-network-slice-service:destination-ip-prefix",
+                                "value": [
+                                    "172.1.101.22/24"
+                                ]
+                            },
+                            {
+                                "type": "ietf-network-slice-service:destination-tcp-port",
+                                "value": [
+                                    "10200"
+                                ]
+                            }
+                        ],
+                        "target-connection-group-id": "line2"
+                    }
+                ]
+            },
+            "attachment-circuits": {
+                "attachment-circuit": [
+                    {
+                        "id": "AC ONT",
+                        "description": "AC connected to PC2",
+                        "ac-node-id": "172.16.61.11",
+                        "ac-tp-id": "200"
+                    }
+                ]
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/tests/ofc25-camara-e2e-controller/data/slice/post_sdp_to_network_slice2.json b/src/tests/ofc25-camara-e2e-controller/data/slice/post_sdp_to_network_slice2.json
new file mode 100644
index 0000000000000000000000000000000000000000..0b147125bd7eb3efc84c87bebab919639782f760
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/data/slice/post_sdp_to_network_slice2.json
@@ -0,0 +1,62 @@
+{
+    "sdp": [
+        {
+            "id": "3",
+            "node-id": "172.16.61.11",
+            "sdp-ip-address": [
+                "172.16.61.11"
+            ],
+            "service-match-criteria": {
+                "match-criterion": [
+                    {
+                        "index": 1,
+                        "match-type": [
+                            {
+                                "type": "ietf-network-slice-service:vlan",
+                                "value": [
+                                    "31"
+                                ]
+                            },
+                            {
+                                "type": "ietf-network-slice-service:source-ip-prefix",
+                                "value": [
+                                    "172.16.104.222/24"
+                                ]
+                            },
+                            {
+                                "type": "ietf-network-slice-service:source-tcp-port",
+                                "value": [
+                                    "10500"
+                                ]
+                            },
+                            {
+                                "type": "ietf-network-slice-service:destination-ip-prefix",
+                                "value": [
+                                    "172.1.201.22/24"
+                                ]
+                            },
+                            {
+                                "type": "ietf-network-slice-service:destination-tcp-port",
+                                "value": [
+                                    "10200"
+                                ]
+                            }
+                        ],
+                        "target-connection-group-id": "line2"
+                    }
+                ]
+            },
+            "attachment-circuits": {
+                "attachment-circuit": [
+                    {
+                        "id": "AC ONT",
+                        "description": "AC connected to PC2",
+                        "ac-node-id": "172.16.61.11",
+                        "ac-tp-id": "200",
+                        "ac-ipv4-address": "172.16.61.11"
+                    }
+                ]
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/tests/ofc25-camara-e2e-controller/data/target-full-ietf-slice.json b/src/tests/ofc25-camara-e2e-controller/data/target-full-ietf-slice.json
new file mode 100644
index 0000000000000000000000000000000000000000..c99876ad9e00e2f94ce44d17b2376f61282e60d7
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/data/target-full-ietf-slice.json
@@ -0,0 +1,678 @@
+{
+  "network-slice-services": {
+    "slice-service": [
+      {
+        "connection-groups": {
+          "connection-group": [
+            {
+              "connectivity-construct": [
+                {
+                  "id": 1,
+                  "p2p-receiver-sdp": "2",
+                  "p2p-sender-sdp": "1",
+                  "service-slo-sle-policy": {
+                    "slo-policy": {
+                      "metric-bound": [
+                        {
+                          "bound": "10",
+                          "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                          "metric-unit": "milliseconds"
+                        },
+                        {
+                          "bound": "5000",
+                          "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                          "metric-unit": "Mbps"
+                        },
+                        {
+                          "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                          "metric-unit": "percentage",
+                          "percentile-value": "0.001"
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "id": 2,
+                  "p2p-receiver-sdp": "1",
+                  "p2p-sender-sdp": "2",
+                  "service-slo-sle-policy": {
+                    "slo-policy": {
+                      "metric-bound": [
+                        {
+                          "bound": "20",
+                          "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                          "metric-unit": "milliseconds"
+                        },
+                        {
+                          "bound": "1000",
+                          "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                          "metric-unit": "Mbps"
+                        },
+                        {
+                          "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                          "metric-unit": "percentage",
+                          "percentile-value": "0.001"
+                        }
+                      ]
+                    }
+                  }
+                }
+              ],
+              "connectivity-type": "point-to-point",
+              "id": "line1"
+            },
+            {
+              "connectivity-construct": [
+                {
+                  "id": 1,
+                  "p2p-receiver-sdp": "3",
+                  "p2p-sender-sdp": "1",
+                  "service-slo-sle-policy": {
+                    "slo-policy": {
+                      "metric-bound": [
+                        {
+                          "bound": "10",
+                          "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                          "metric-unit": "milliseconds"
+                        },
+                        {
+                          "bound": "5000",
+                          "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                          "metric-unit": "Mbps"
+                        },
+                        {
+                          "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                          "metric-unit": "percentage",
+                          "percentile-value": "0.001"
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "id": 2,
+                  "p2p-receiver-sdp": "1",
+                  "p2p-sender-sdp": "3",
+                  "service-slo-sle-policy": {
+                    "slo-policy": {
+                      "metric-bound": [
+                        {
+                          "bound": "20",
+                          "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                          "metric-unit": "milliseconds"
+                        },
+                        {
+                          "bound": "1000",
+                          "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                          "metric-unit": "Mbps"
+                        },
+                        {
+                          "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                          "metric-unit": "percentage",
+                          "percentile-value": "0.001"
+                        }
+                      ]
+                    }
+                  }
+                }
+              ],
+              "connectivity-type": "point-to-point",
+              "id": "line2"
+            }
+          ]
+        },
+        "description": "network slice 2, connect to VM2",
+        "id": "slice2",
+        "sdps": {
+          "sdp": [
+            {
+              "attachment-circuits": {
+                "attachment-circuit": [
+                  {
+                    "ac-node-id": "172.16.204.220",
+                    "ac-tp-id": "201",
+                    "description": "AC VM2 connected to POP",
+                    "id": "AC POP to VM2"
+                  }
+                ]
+              },
+              "id": "1",
+              "node-id": "172.16.204.220",
+              "sdp-ip-address": [
+                "172.16.204.220"
+              ],
+              "service-match-criteria": {
+                "match-criterion": [
+                  {
+                    "index": 1,
+                    "match-type": [
+                      {
+                        "type": "ietf-network-slice-service:vlan",
+                        "value": [
+                          "201"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-ip-prefix",
+                        "value": [
+                          "172.16.104.221/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-tcp-port",
+                        "value": [
+                          "10500"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-ip-prefix",
+                        "value": [
+                          "172.1.201.22/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-tcp-port",
+                        "value": [
+                          "10200"
+                        ]
+                      }
+                    ],
+                    "target-connection-group-id": "line1"
+                  },
+                  {
+                    "index": 2,
+                    "match-type": [
+                      {
+                        "type": "ietf-network-slice-service:vlan",
+                        "value": [
+                          "201"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-ip-prefix",
+                        "value": [
+                          "172.1.201.22/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-tcp-port",
+                        "value": [
+                          "10200"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-ip-prefix",
+                        "value": [
+                          "172.16.104.222/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-tcp-port",
+                        "value": [
+                          "10500"
+                        ]
+                      }
+                    ],
+                    "target-connection-group-id": "line2"
+                  }
+                ]
+              }
+            },
+            {
+              "attachment-circuits": {
+                "attachment-circuit": [
+                  {
+                    "ac-ipv4-address": "172.16.61.10",
+                    "ac-node-id": "172.16.61.10",
+                    "ac-tp-id": "200",
+                    "description": "AC connected to PC",
+                    "id": "AC ONT"
+                  }
+                ]
+              },
+              "id": "2",
+              "node-id": "172.16.61.10",
+              "sdp-ip-address": [
+                "172.16.61.10"
+              ],
+              "service-match-criteria": {
+                "match-criterion": [
+                  {
+                    "index": 1,
+                    "match-type": [
+                      {
+                        "type": "ietf-network-slice-service:vlan",
+                        "value": [
+                          "31"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-ip-prefix",
+                        "value": [
+                          "172.16.104.221/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-tcp-port",
+                        "value": [
+                          "10500"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-ip-prefix",
+                        "value": [
+                          "172.1.201.22/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-tcp-port",
+                        "value": [
+                          "10200"
+                        ]
+                      }
+                    ],
+                    "target-connection-group-id": "line1"
+                  }
+                ]
+              }
+            },
+            {
+              "attachment-circuits": {
+                "attachment-circuit": [
+                  {
+                    "ac-ipv4-address": "172.16.61.11",
+                    "ac-node-id": "172.16.61.11",
+                    "ac-tp-id": "200",
+                    "description": "AC connected to PC2",
+                    "id": "AC ONT"
+                  }
+                ]
+              },
+              "id": "3",
+              "node-id": "172.16.61.11",
+              "sdp-ip-address": [
+                "172.16.61.11"
+              ],
+              "service-match-criteria": {
+                "match-criterion": [
+                  {
+                    "index": 1,
+                    "match-type": [
+                      {
+                        "type": "ietf-network-slice-service:vlan",
+                        "value": [
+                          "31"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-ip-prefix",
+                        "value": [
+                          "172.16.104.222/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-tcp-port",
+                        "value": [
+                          "10500"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-ip-prefix",
+                        "value": [
+                          "172.1.201.22/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-tcp-port",
+                        "value": [
+                          "10200"
+                        ]
+                      }
+                    ],
+                    "target-connection-group-id": "line2"
+                  }
+                ]
+              }
+            }
+          ]
+        }
+      },
+      {
+        "connection-groups": {
+          "connection-group": [
+            {
+              "connectivity-construct": [
+                {
+                  "id": 1,
+                  "p2p-receiver-sdp": "2",
+                  "p2p-sender-sdp": "1",
+                  "service-slo-sle-policy": {
+                    "slo-policy": {
+                      "metric-bound": [
+                        {
+                          "bound": "10",
+                          "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                          "metric-unit": "milliseconds"
+                        },
+                        {
+                          "bound": "5000",
+                          "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                          "metric-unit": "Mbps"
+                        },
+                        {
+                          "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                          "metric-unit": "percentage",
+                          "percentile-value": "0.001"
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "id": 2,
+                  "p2p-receiver-sdp": "1",
+                  "p2p-sender-sdp": "2",
+                  "service-slo-sle-policy": {
+                    "slo-policy": {
+                      "metric-bound": [
+                        {
+                          "bound": "20",
+                          "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                          "metric-unit": "milliseconds"
+                        },
+                        {
+                          "bound": "1000",
+                          "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                          "metric-unit": "Mbps"
+                        },
+                        {
+                          "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                          "metric-unit": "percentage",
+                          "percentile-value": "0.001"
+                        }
+                      ]
+                    }
+                  }
+                }
+              ],
+              "connectivity-type": "point-to-point",
+              "id": "line1"
+            },
+            {
+              "connectivity-construct": [
+                {
+                  "id": 1,
+                  "p2p-receiver-sdp": "3",
+                  "p2p-sender-sdp": "1",
+                  "service-slo-sle-policy": {
+                    "slo-policy": {
+                      "metric-bound": [
+                        {
+                          "bound": "10",
+                          "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                          "metric-unit": "milliseconds"
+                        },
+                        {
+                          "bound": "5000",
+                          "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                          "metric-unit": "Mbps"
+                        },
+                        {
+                          "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                          "metric-unit": "percentage",
+                          "percentile-value": "0.001"
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "id": 2,
+                  "p2p-receiver-sdp": "1",
+                  "p2p-sender-sdp": "3",
+                  "service-slo-sle-policy": {
+                    "slo-policy": {
+                      "metric-bound": [
+                        {
+                          "bound": "20",
+                          "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                          "metric-unit": "milliseconds"
+                        },
+                        {
+                          "bound": "1000",
+                          "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                          "metric-unit": "Mbps"
+                        },
+                        {
+                          "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                          "metric-unit": "percentage",
+                          "percentile-value": "0.001"
+                        }
+                      ]
+                    }
+                  }
+                }
+              ],
+              "connectivity-type": "point-to-point",
+              "id": "line2"
+            }
+          ]
+        },
+        "description": "network slice 1, connect to VM1",
+        "id": "slice1",
+        "sdps": {
+          "sdp": [
+            {
+              "attachment-circuits": {
+                "attachment-circuit": [
+                  {
+                    "ac-node-id": "172.16.204.220",
+                    "ac-tp-id": "200",
+                    "description": "AC VM1 connected to POP",
+                    "id": "AC POP to VM1"
+                  }
+                ]
+              },
+              "id": "1",
+              "node-id": "172.16.204.220",
+              "sdp-ip-address": [
+                "172.16.204.220"
+              ],
+              "service-match-criteria": {
+                "match-criterion": [
+                  {
+                    "index": 1,
+                    "match-type": [
+                      {
+                        "type": "ietf-network-slice-service:vlan",
+                        "value": [
+                          "101"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-ip-prefix",
+                        "value": [
+                          "172.16.104.221/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-tcp-port",
+                        "value": [
+                          "10500"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-ip-prefix",
+                        "value": [
+                          "172.1.101.22/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-tcp-port",
+                        "value": [
+                          "10200"
+                        ]
+                      }
+                    ],
+                    "target-connection-group-id": "line1"
+                  },
+                  {
+                    "index": 2,
+                    "match-type": [
+                      {
+                        "type": "ietf-network-slice-service:vlan",
+                        "value": [
+                          "101"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-ip-prefix",
+                        "value": [
+                          "172.1.101.22/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-tcp-port",
+                        "value": [
+                          "10200"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-ip-prefix",
+                        "value": [
+                          "172.16.104.222/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-tcp-port",
+                        "value": [
+                          "10500"
+                        ]
+                      }
+                    ],
+                    "target-connection-group-id": "line2"
+                  }
+                ]
+              }
+            },
+            {
+              "attachment-circuits": {
+                "attachment-circuit": [
+                  {
+                    "ac-node-id": "172.16.61.10",
+                    "ac-tp-id": "200",
+                    "description": "AC connected to PC1",
+                    "id": "AC ONT"
+                  }
+                ]
+              },
+              "id": "2",
+              "node-id": "172.16.61.10",
+              "sdp-ip-address": [
+                "172.16.61.10"
+              ],
+              "service-match-criteria": {
+                "match-criterion": [
+                  {
+                    "index": 1,
+                    "match-type": [
+                      {
+                        "type": "ietf-network-slice-service:vlan",
+                        "value": [
+                          "21"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-ip-prefix",
+                        "value": [
+                          "172.16.104.221/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-tcp-port",
+                        "value": [
+                          "10500"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-ip-prefix",
+                        "value": [
+                          "172.1.101.22/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-tcp-port",
+                        "value": [
+                          "10200"
+                        ]
+                      }
+                    ],
+                    "target-connection-group-id": "line1"
+                  }
+                ]
+              }
+            },
+            {
+              "attachment-circuits": {
+                "attachment-circuit": [
+                  {
+                    "ac-node-id": "172.16.61.11",
+                    "ac-tp-id": "200",
+                    "description": "AC connected to PC2",
+                    "id": "AC ONT"
+                  }
+                ]
+              },
+              "id": "3",
+              "node-id": "172.16.61.11",
+              "sdp-ip-address": [
+                "172.16.61.11"
+              ],
+              "service-match-criteria": {
+                "match-criterion": [
+                  {
+                    "index": 1,
+                    "match-type": [
+                      {
+                        "type": "ietf-network-slice-service:vlan",
+                        "value": [
+                          "21"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-ip-prefix",
+                        "value": [
+                          "172.16.104.222/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:source-tcp-port",
+                        "value": [
+                          "10500"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-ip-prefix",
+                        "value": [
+                          "172.1.101.22/24"
+                        ]
+                      },
+                      {
+                        "type": "ietf-network-slice-service:destination-tcp-port",
+                        "value": [
+                          "10200"
+                        ]
+                      }
+                    ],
+                    "target-connection-group-id": "line2"
+                  }
+                ]
+              }
+            }
+          ]
+        }
+      }
+    ]
+  }
+}
diff --git a/src/tests/ofc25-camara-e2e-controller/data/target-ietf-slice-posted-slices.json b/src/tests/ofc25-camara-e2e-controller/data/target-ietf-slice-posted-slices.json
new file mode 100644
index 0000000000000000000000000000000000000000..004d3cafff0decf4cbe550f555e99b2229702b07
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/data/target-ietf-slice-posted-slices.json
@@ -0,0 +1,382 @@
+[
+  {
+    "network-slice-services": {
+      "slice-service": [
+        {
+          "connection-groups": {
+            "connection-group": [
+              {
+                "connectivity-construct": [
+                  {
+                    "id": 1,
+                    "p2p-receiver-sdp": "2",
+                    "p2p-sender-sdp": "1",
+                    "service-slo-sle-policy": {
+                      "slo-policy": {
+                        "metric-bound": [
+                          {
+                            "bound": 10,
+                            "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                            "metric-unit": "milliseconds"
+                          },
+                          {
+                            "bound": 5000,
+                            "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                            "metric-unit": "Mbps"
+                          },
+                          {
+                            "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                            "metric-unit": "percentage",
+                            "percentile-value": 0.001
+                          }
+                        ]
+                      }
+                    }
+                  },
+                  {
+                    "id": 2,
+                    "p2p-receiver-sdp": "1",
+                    "p2p-sender-sdp": "2",
+                    "service-slo-sle-policy": {
+                      "slo-policy": {
+                        "metric-bound": [
+                          {
+                            "bound": 20,
+                            "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                            "metric-unit": "milliseconds"
+                          },
+                          {
+                            "bound": 1000,
+                            "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                            "metric-unit": "Mbps"
+                          },
+                          {
+                            "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                            "metric-unit": "percentage",
+                            "percentile-value": 0.001
+                          }
+                        ]
+                      }
+                    }
+                  }
+                ],
+                "connectivity-type": "point-to-point",
+                "id": "line1"
+              }
+            ]
+          },
+          "description": "dsc",
+          "id": "slice1",
+          "sdps": {
+            "sdp": [
+              {
+                "attachment-circuits": {
+                  "attachment-circuit": [
+                    {
+                      "ac-node-id": "172.16.185.32",
+                      "ac-tp-id": "200",
+                      "description": "dsc",
+                      "id": "0"
+                    }
+                  ]
+                },
+                "id": "1",
+                "node-id": "172.16.185.32",
+                "sdp-ip-address": [
+                  "172.16.185.32"
+                ],
+                "service-match-criteria": {
+                  "match-criterion": [
+                    {
+                      "index": 1,
+                      "match-type": [
+                        {
+                          "type": "ietf-network-slice-service:vlan",
+                          "value": [
+                            "101"
+                          ]
+                        },
+                        {
+                          "type": "ietf-network-slice-service:source-ip-prefix",
+                          "value": [
+                            "172.1.101.22/24"
+                          ]
+                        },
+                        {
+                          "type": "ietf-network-slice-service:source-tcp-port",
+                          "value": [
+                            "10200"
+                          ]
+                        },
+                        {
+                          "type": "ietf-network-slice-service:destination-ip-prefix",
+                          "value": [
+                            "172.16.104.221/24"
+                          ]
+                        },
+                        {
+                          "type": "ietf-network-slice-service:destination-tcp-port",
+                          "value": [
+                            "10500"
+                          ]
+                        }
+                      ],
+                      "target-connection-group-id": "line1"
+                    }
+                  ]
+                }
+              },
+              {
+                "attachment-circuits": {
+                  "attachment-circuit": [
+                    {
+                      "ac-node-id": "172.16.182.25",
+                      "ac-tp-id": "200",
+                      "description": "dsc",
+                      "id": "0"
+                    }
+                  ]
+                },
+                "id": "2",
+                "node-id": "172.16.182.25",
+                "sdp-ip-address": [
+                  "172.16.182.25"
+                ],
+                "service-match-criteria": {
+                  "match-criterion": [
+                    {
+                      "index": 1,
+                      "match-type": [
+                        {
+                          "type": "ietf-network-slice-service:vlan",
+                          "value": [
+                            "21"
+                          ]
+                        },
+                        {
+                          "type": "ietf-network-slice-service:source-ip-prefix",
+                          "value": [
+                            "172.16.104.221/24"
+                          ]
+                        },
+                        {
+                          "type": "ietf-network-slice-service:source-tcp-port",
+                          "value": [
+                            "10500"
+                          ]
+                        },
+                        {
+                          "type": "ietf-network-slice-service:destination-ip-prefix",
+                          "value": [
+                            "172.1.101.22/24"
+                          ]
+                        },
+                        {
+                          "type": "ietf-network-slice-service:destination-tcp-port",
+                          "value": [
+                            "10200"
+                          ]
+                        }
+                      ],
+                      "target-connection-group-id": "line1"
+                    }
+                  ]
+                }
+              }
+            ]
+          }
+        }
+      ]
+    }
+  },
+  {
+    "network-slice-services": {
+      "slice-service": [
+        {
+          "connection-groups": {
+            "connection-group": [
+              {
+                "connectivity-construct": [
+                  {
+                    "id": 1,
+                    "p2p-receiver-sdp": "2",
+                    "p2p-sender-sdp": "1",
+                    "service-slo-sle-policy": {
+                      "slo-policy": {
+                        "metric-bound": [
+                          {
+                            "bound": 10,
+                            "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                            "metric-unit": "milliseconds"
+                          },
+                          {
+                            "bound": 5000,
+                            "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                            "metric-unit": "Mbps"
+                          },
+                          {
+                            "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                            "metric-unit": "percentage",
+                            "percentile-value": 0.001
+                          }
+                        ]
+                      }
+                    }
+                  },
+                  {
+                    "id": 2,
+                    "p2p-receiver-sdp": "1",
+                    "p2p-sender-sdp": "2",
+                    "service-slo-sle-policy": {
+                      "slo-policy": {
+                        "metric-bound": [
+                          {
+                            "bound": 20,
+                            "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                            "metric-unit": "milliseconds"
+                          },
+                          {
+                            "bound": 1000,
+                            "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                            "metric-unit": "Mbps"
+                          },
+                          {
+                            "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                            "metric-unit": "percentage",
+                            "percentile-value": 0.001
+                          }
+                        ]
+                      }
+                    }
+                  }
+                ],
+                "connectivity-type": "point-to-point",
+                "id": "line1"
+              }
+            ]
+          },
+          "description": "dsc",
+          "id": "slice2",
+          "sdps": {
+            "sdp": [
+              {
+                "attachment-circuits": {
+                  "attachment-circuit": [
+                    {
+                      "ac-node-id": "172.16.185.32",
+                      "ac-tp-id": "200",
+                      "description": "dsc",
+                      "id": "0"
+                    }
+                  ]
+                },
+                "id": "1",
+                "node-id": "172.16.185.32",
+                "sdp-ip-address": [
+                  "172.16.185.32"
+                ],
+                "service-match-criteria": {
+                  "match-criterion": [
+                    {
+                      "index": 1,
+                      "match-type": [
+                        {
+                          "type": "ietf-network-slice-service:vlan",
+                          "value": [
+                            "201"
+                          ]
+                        },
+                        {
+                          "type": "ietf-network-slice-service:source-ip-prefix",
+                          "value": [
+                            "172.1.201.22/24"
+                          ]
+                        },
+                        {
+                          "type": "ietf-network-slice-service:source-tcp-port",
+                          "value": [
+                            "10200"
+                          ]
+                        },
+                        {
+                          "type": "ietf-network-slice-service:destination-ip-prefix",
+                          "value": [
+                            "172.16.104.221/24"
+                          ]
+                        },
+                        {
+                          "type": "ietf-network-slice-service:destination-tcp-port",
+                          "value": [
+                            "10500"
+                          ]
+                        }
+                      ],
+                      "target-connection-group-id": "line1"
+                    }
+                  ]
+                }
+              },
+              {
+                "attachment-circuits": {
+                  "attachment-circuit": [
+                    {
+                      "ac-node-id": "172.16.182.25",
+                      "ac-tp-id": "200",
+                      "description": "dsc",
+                      "id": "0"
+                    }
+                  ]
+                },
+                "id": "2",
+                "node-id": "172.16.182.25",
+                "sdp-ip-address": [
+                  "172.16.182.25"
+                ],
+                "service-match-criteria": {
+                  "match-criterion": [
+                    {
+                      "index": 1,
+                      "match-type": [
+                        {
+                          "type": "ietf-network-slice-service:vlan",
+                          "value": [
+                            "31"
+                          ]
+                        },
+                        {
+                          "type": "ietf-network-slice-service:source-ip-prefix",
+                          "value": [
+                            "172.16.104.221/24"
+                          ]
+                        },
+                        {
+                          "type": "ietf-network-slice-service:source-tcp-port",
+                          "value": [
+                            "10500"
+                          ]
+                        },
+                        {
+                          "type": "ietf-network-slice-service:destination-ip-prefix",
+                          "value": [
+                            "172.1.201.22/24"
+                          ]
+                        },
+                        {
+                          "type": "ietf-network-slice-service:destination-tcp-port",
+                          "value": [
+                            "10200"
+                          ]
+                        }
+                      ],
+                      "target-connection-group-id": "line1"
+                    }
+                  ]
+                }
+              }
+            ]
+          }
+        }
+      ]
+    }
+  }
+]
diff --git a/src/tests/ofc25-camara-e2e-controller/data/target-ietf-slice-put-connection-groups.json b/src/tests/ofc25-camara-e2e-controller/data/target-ietf-slice-put-connection-groups.json
new file mode 100644
index 0000000000000000000000000000000000000000..7526ebd8b92a2eab7f30d94a035ba63f0a503c2d
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/data/target-ietf-slice-put-connection-groups.json
@@ -0,0 +1,234 @@
+[
+  {
+    "connectivity-construct": [
+      {
+        "id": 1,
+        "p2p-receiver-sdp": "2",
+        "p2p-sender-sdp": "1",
+        "service-slo-sle-policy": {
+          "slo-policy": {
+            "metric-bound": [
+              {
+                "bound": 10,
+                "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                "metric-unit": "milliseconds"
+              },
+              {
+                "bound": 10000,
+                "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                "metric-unit": "Mbps"
+              },
+              {
+                "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                "metric-unit": "percentage",
+                "percentile-value": 0.001
+              }
+            ]
+          }
+        }
+      },
+      {
+        "id": 2,
+        "p2p-receiver-sdp": "1",
+        "p2p-sender-sdp": "2",
+        "service-slo-sle-policy": {
+          "slo-policy": {
+            "metric-bound": [
+              {
+                "bound": 20,
+                "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                "metric-unit": "milliseconds"
+              },
+              {
+                "bound": 2000,
+                "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                "metric-unit": "Mbps"
+              },
+              {
+                "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                "metric-unit": "percentage",
+                "percentile-value": 0.001
+              }
+            ]
+          }
+        }
+      }
+    ],
+    "connectivity-type": "point-to-point",
+    "id": "line1"
+  },
+  {
+    "connectivity-construct": [
+      {
+        "id": 1,
+        "p2p-receiver-sdp": "2",
+        "p2p-sender-sdp": "1",
+        "service-slo-sle-policy": {
+          "slo-policy": {
+            "metric-bound": [
+              {
+                "bound": 10,
+                "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                "metric-unit": "milliseconds"
+              },
+              {
+                "bound": 10000,
+                "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                "metric-unit": "Mbps"
+              },
+              {
+                "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                "metric-unit": "percentage",
+                "percentile-value": 0.001
+              }
+            ]
+          }
+        }
+      },
+      {
+        "id": 2,
+        "p2p-receiver-sdp": "1",
+        "p2p-sender-sdp": "2",
+        "service-slo-sle-policy": {
+          "slo-policy": {
+            "metric-bound": [
+              {
+                "bound": 20,
+                "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                "metric-unit": "milliseconds"
+              },
+              {
+                "bound": 2000,
+                "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                "metric-unit": "Mbps"
+              },
+              {
+                "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                "metric-unit": "percentage",
+                "percentile-value": 0.001
+              }
+            ]
+          }
+        }
+      }
+    ],
+    "connectivity-type": "point-to-point",
+    "id": "line1"
+  },
+  {
+    "connectivity-construct": [
+      {
+        "id": 1,
+        "p2p-receiver-sdp": "2",
+        "p2p-sender-sdp": "1",
+        "service-slo-sle-policy": {
+          "slo-policy": {
+            "metric-bound": [
+              {
+                "bound": 10,
+                "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                "metric-unit": "milliseconds"
+              },
+              {
+                "bound": 5000,
+                "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                "metric-unit": "Mbps"
+              },
+              {
+                "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                "metric-unit": "percentage",
+                "percentile-value": 0.001
+              }
+            ]
+          }
+        }
+      },
+      {
+        "id": 2,
+        "p2p-receiver-sdp": "1",
+        "p2p-sender-sdp": "2",
+        "service-slo-sle-policy": {
+          "slo-policy": {
+            "metric-bound": [
+              {
+                "bound": 20,
+                "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                "metric-unit": "milliseconds"
+              },
+              {
+                "bound": 1000,
+                "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                "metric-unit": "Mbps"
+              },
+              {
+                "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                "metric-unit": "percentage",
+                "percentile-value": 0.001
+              }
+            ]
+          }
+        }
+      }
+    ],
+    "connectivity-type": "point-to-point",
+    "id": "line1"
+  },
+  {
+    "connectivity-construct": [
+      {
+        "id": 1,
+        "p2p-receiver-sdp": "2",
+        "p2p-sender-sdp": "1",
+        "service-slo-sle-policy": {
+          "slo-policy": {
+            "metric-bound": [
+              {
+                "bound": 10,
+                "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                "metric-unit": "milliseconds"
+              },
+              {
+                "bound": 5000,
+                "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                "metric-unit": "Mbps"
+              },
+              {
+                "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                "metric-unit": "percentage",
+                "percentile-value": 0.001
+              }
+            ]
+          }
+        }
+      },
+      {
+        "id": 2,
+        "p2p-receiver-sdp": "1",
+        "p2p-sender-sdp": "2",
+        "service-slo-sle-policy": {
+          "slo-policy": {
+            "metric-bound": [
+              {
+                "bound": 20,
+                "metric-type": "ietf-network-slice-service:one-way-delay-maximum",
+                "metric-unit": "milliseconds"
+              },
+              {
+                "bound": 1000,
+                "metric-type": "ietf-network-slice-service:one-way-bandwidth",
+                "metric-unit": "Mbps"
+              },
+              {
+                "metric-type": "ietf-network-slice-service:two-way-packet-loss",
+                "metric-unit": "percentage",
+                "percentile-value": 0.001
+              }
+            ]
+          }
+        }
+      }
+    ],
+    "connectivity-type": "point-to-point",
+    "id": "line1"
+  }
+]
diff --git a/src/tests/ofc25-camara-e2e-controller/data/target-nce-app-flows.json b/src/tests/ofc25-camara-e2e-controller/data/target-nce-app-flows.json
new file mode 100644
index 0000000000000000000000000000000000000000..66f7ed2543f7f5472e50ccda9755dd965bc73452
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/data/target-nce-app-flows.json
@@ -0,0 +1,58 @@
+{
+  "App_Flow_2_1_slice1": {
+    "app-flow": [
+      {
+        "app-name": "App_Flow_2_1_slice1",
+        "duration": 9999,
+        "max-online-users": 1,
+        "name": "App_Flow_2_1_slice1",
+        "qos-profile": "AR_VR_Gaming",
+        "service-profile": "service_2_1_slice1",
+        "stas": "00:3D:E1:18:82:9E",
+        "user-id": "a8b5b840-1548-46c9-892e-5c18f9ec8d99"
+      }
+    ]
+  },
+  "App_Flow_3_1_slice1": {
+    "app-flow": [
+      {
+        "app-name": "App_Flow_3_1_slice1",
+        "duration": 9999,
+        "max-online-users": 1,
+        "name": "App_Flow_3_1_slice1",
+        "qos-profile": "AR_VR_Gaming",
+        "service-profile": "service_3_1_slice1",
+        "stas": "00:3D:E1:18:82:9E",
+        "user-id": "28a1c47b-0179-4ab8-85da-632e6f946491"
+      }
+    ]
+  },
+  "App_Flow_2_1_slice2": {
+    "app-flow": [
+      {
+        "app-name": "App_Flow_2_1_slice2",
+        "duration": 9999,
+        "max-online-users": 1,
+        "name": "App_Flow_2_1_slice2",
+        "qos-profile": "AR_VR_Gaming",
+        "service-profile": "service_2_1_slice2",
+        "stas": "00:3D:E1:18:82:9E",
+        "user-id": "9df7b98a-d5c0-43d4-bd0e-8d81ee4485f0"
+      }
+    ]
+  },
+  "App_Flow_3_1_slice2": {
+    "app-flow": [
+      {
+        "app-name": "App_Flow_3_1_slice2",
+        "duration": 9999,
+        "max-online-users": 1,
+        "name": "App_Flow_3_1_slice2",
+        "qos-profile": "AR_VR_Gaming",
+        "service-profile": "service_3_1_slice2",
+        "stas": "00:3D:E1:18:82:9E",
+        "user-id": "79b2becb-8500-42cc-b6be-c27c2ea60b22"
+      }
+    ]
+  }
+}
diff --git a/src/tests/ofc25-camara-e2e-controller/data/target-nce-apps.json b/src/tests/ofc25-camara-e2e-controller/data/target-nce-apps.json
new file mode 100644
index 0000000000000000000000000000000000000000..11a25897910cbbfd7fb666ddd86babc1972e7052
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/data/target-nce-apps.json
@@ -0,0 +1,82 @@
+{
+  "App_Flow_2_1_slice1": {
+    "application": [
+      {
+        "app-features": {
+          "app-feature": [
+            {
+              "dest-ip": "172.1.101.22",
+              "dest-port": "10200",
+              "id": "feature_2_1_slice1",
+              "protocol": "tcp",
+              "src-ip": "172.16.104.221",
+              "src-port": "10500"
+            }
+          ]
+        },
+        "app-id": "app_2_1_slice1",
+        "name": "App_Flow_2_1_slice1"
+      }
+    ]
+  },
+  "App_Flow_3_1_slice1": {
+    "application": [
+      {
+        "app-features": {
+          "app-feature": [
+            {
+              "dest-ip": "172.1.101.22",
+              "dest-port": "10200",
+              "id": "feature_3_1_slice1",
+              "protocol": "tcp",
+              "src-ip": "172.16.104.222",
+              "src-port": "10500"
+            }
+          ]
+        },
+        "app-id": "app_3_1_slice1",
+        "name": "App_Flow_3_1_slice1"
+      }
+    ]
+  },
+  "App_Flow_2_1_slice2": {
+    "application": [
+      {
+        "app-features": {
+          "app-feature": [
+            {
+              "dest-ip": "172.1.201.22",
+              "dest-port": "10200",
+              "id": "feature_2_1_slice2",
+              "protocol": "tcp",
+              "src-ip": "172.16.104.221",
+              "src-port": "10500"
+            }
+          ]
+        },
+        "app-id": "app_2_1_slice2",
+        "name": "App_Flow_2_1_slice2"
+      }
+    ]
+  },
+  "App_Flow_3_1_slice2": {
+    "application": [
+      {
+        "app-features": {
+          "app-feature": [
+            {
+              "dest-ip": "172.1.201.22",
+              "dest-port": "10200",
+              "id": "feature_3_1_slice2",
+              "protocol": "tcp",
+              "src-ip": "172.16.104.222",
+              "src-port": "10500"
+            }
+          ]
+        },
+        "app-id": "app_3_1_slice2",
+        "name": "App_Flow_3_1_slice2"
+      }
+    ]
+  }
+}
diff --git a/src/tests/ofc25-camara-e2e-controller/deploy_specs.sh b/src/tests/ofc25-camara-e2e-controller/deploy_specs.sh
new file mode 100755
index 0000000000000000000000000000000000000000..9ae83e7b126aa2913cd3c30887292b4626dd5855
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/deploy_specs.sh
@@ -0,0 +1,208 @@
+#!/bin/bash
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# ----- TeraFlowSDN ------------------------------------------------------------
+
+# Set the URL of the internal MicroK8s Docker registry where the images will be uploaded to.
+export TFS_REGISTRY_IMAGES="http://localhost:32000/tfs/"
+
+# Set the list of components, separated by spaces, you want to build images for, and deploy.
+#export TFS_COMPONENTS="context device pathcomp service slice nbi webui load_generator"
+export TFS_COMPONENTS="context device pathcomp service slice nbi"
+
+# Uncomment to activate Monitoring (old)
+#export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring"
+
+# Uncomment to activate Monitoring Framework (new)
+#export TFS_COMPONENTS="${TFS_COMPONENTS} kpi_manager kpi_value_writer kpi_value_api telemetry analytics automation"
+
+# Uncomment to activate QoS Profiles
+#export TFS_COMPONENTS="${TFS_COMPONENTS} qos_profile"
+
+# Uncomment to activate BGP-LS Speaker
+#export TFS_COMPONENTS="${TFS_COMPONENTS} bgpls_speaker"
+
+# Uncomment to activate Optical Controller
+#   To manage optical connections, "service" requires "opticalcontroller" to be deployed
+#   before "service", thus we "hack" the TFS_COMPONENTS environment variable prepending the
+#   "opticalcontroller" only if "service" is already in TFS_COMPONENTS, and re-export it.
+#if [[ "$TFS_COMPONENTS" == *"service"* ]]; then
+#    BEFORE="${TFS_COMPONENTS% service*}"
+#    AFTER="${TFS_COMPONENTS#* service}"
+#    export TFS_COMPONENTS="${BEFORE} opticalcontroller service ${AFTER}"
+#fi
+
+# Uncomment to activate ZTP
+#export TFS_COMPONENTS="${TFS_COMPONENTS} ztp"
+
+# Uncomment to activate Policy Manager
+#export TFS_COMPONENTS="${TFS_COMPONENTS} policy"
+
+# Uncomment to activate Optical CyberSecurity
+#export TFS_COMPONENTS="${TFS_COMPONENTS} dbscanserving opticalattackmitigator opticalattackdetector opticalattackmanager"
+
+# Uncomment to activate L3 CyberSecurity
+#export TFS_COMPONENTS="${TFS_COMPONENTS} l3_attackmitigator l3_centralizedattackdetector"
+
+# Uncomment to activate TE
+#export TFS_COMPONENTS="${TFS_COMPONENTS} te"
+
+# Uncomment to activate Forecaster
+#export TFS_COMPONENTS="${TFS_COMPONENTS} forecaster"
+
+# Uncomment to activate E2E Orchestrator
+#export TFS_COMPONENTS="${TFS_COMPONENTS} e2e_orchestrator"
+
+# Uncomment to activate DLT and Interdomain
+#export TFS_COMPONENTS="${TFS_COMPONENTS} interdomain dlt"
+#if [[ "$TFS_COMPONENTS" == *"dlt"* ]]; then
+#    export KEY_DIRECTORY_PATH="src/dlt/gateway/keys/priv_sk"
+#    export CERT_DIRECTORY_PATH="src/dlt/gateway/keys/cert.pem"
+#    export TLS_CERT_PATH="src/dlt/gateway/keys/ca.crt"
+#fi
+
+# Uncomment to activate QKD App
+#   To manage QKD Apps, "service" requires "qkd_app" to be deployed
+#   before "service", thus we "hack" the TFS_COMPONENTS environment variable prepending the
+#   "qkd_app" only if "service" is already in TFS_COMPONENTS, and re-export it.
+#if [[ "$TFS_COMPONENTS" == *"service"* ]]; then
+#    BEFORE="${TFS_COMPONENTS% service*}"
+#    AFTER="${TFS_COMPONENTS#* service}"
+#    export TFS_COMPONENTS="${BEFORE} qkd_app service ${AFTER}"
+#fi
+
+
+# Set the tag you want to use for your images.
+export TFS_IMAGE_TAG="dev"
+
+# Set the name of the Kubernetes namespace to deploy TFS to.
+export TFS_K8S_NAMESPACE="tfs"
+
+# Set additional manifest files to be applied after the deployment
+export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml"
+
+# Uncomment to monitor performance of components
+#export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/servicemonitors.yaml"
+
+# Uncomment when deploying Optical CyberSecurity
+#export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/cachingservice.yaml"
+
+# Set the new Grafana admin password
+export TFS_GRAFANA_PASSWORD="admin123+"
+
+# Disable skip-build flag to rebuild the Docker images.
+export TFS_SKIP_BUILD=""
+
+
+# ----- CockroachDB ------------------------------------------------------------
+
+# Set the namespace where CockroackDB will be deployed.
+export CRDB_NAMESPACE="crdb"
+
+# Set the external port CockroackDB Postgre SQL interface will be exposed to.
+export CRDB_EXT_PORT_SQL="26257"
+
+# Set the external port CockroackDB HTTP Mgmt GUI interface will be exposed to.
+export CRDB_EXT_PORT_HTTP="8081"
+
+# Set the database username to be used by Context.
+export CRDB_USERNAME="tfs"
+
+# Set the database user's password to be used by Context.
+export CRDB_PASSWORD="tfs123"
+
+# Set CockroachDB installation mode to 'single'. This option is convenient for development and testing.
+# See ./deploy/all.sh or ./deploy/crdb.sh for additional details
+export CRDB_DEPLOY_MODE="single"
+
+# Disable flag for dropping database, if it exists.
+export CRDB_DROP_DATABASE_IF_EXISTS="YES"
+
+# Disable flag for re-deploying CockroachDB from scratch.
+export CRDB_REDEPLOY=""
+
+
+# ----- NATS -------------------------------------------------------------------
+
+# Set the namespace where NATS will be deployed.
+export NATS_NAMESPACE="nats"
+
+# Set the external port NATS Client interface will be exposed to.
+export NATS_EXT_PORT_CLIENT="4222"
+
+# Set the external port NATS HTTP Mgmt GUI interface will be exposed to.
+export NATS_EXT_PORT_HTTP="8222"
+
+# Set NATS installation mode to 'single'. This option is convenient for development and testing.
+# See ./deploy/all.sh or ./deploy/nats.sh for additional details
+export NATS_DEPLOY_MODE="single"
+
+# Disable flag for re-deploying NATS from scratch.
+export NATS_REDEPLOY=""
+
+
+# ----- QuestDB ----------------------------------------------------------------
+
+# Set the namespace where QuestDB will be deployed.
+export QDB_NAMESPACE="qdb"
+
+# Set the external port QuestDB Postgre SQL interface will be exposed to.
+export QDB_EXT_PORT_SQL="8812"
+
+# Set the external port QuestDB Influx Line Protocol interface will be exposed to.
+export QDB_EXT_PORT_ILP="9009"
+
+# Set the external port QuestDB HTTP Mgmt GUI interface will be exposed to.
+export QDB_EXT_PORT_HTTP="9000"
+
+# Set the database username to be used for QuestDB.
+export QDB_USERNAME="admin"
+
+# Set the database user's password to be used for QuestDB.
+export QDB_PASSWORD="quest"
+
+# Set the table name to be used by Monitoring for KPIs.
+export QDB_TABLE_MONITORING_KPIS="tfs_monitoring_kpis"
+
+# Set the table name to be used by Slice for plotting groups.
+export QDB_TABLE_SLICE_GROUPS="tfs_slice_groups"
+
+# Disable flag for dropping tables if they exist.
+export QDB_DROP_TABLES_IF_EXIST="YES"
+
+# Disable flag for re-deploying QuestDB from scratch.
+export QDB_REDEPLOY=""
+
+
+# ----- K8s Observability ------------------------------------------------------
+
+# Set the external port Prometheus Mgmt HTTP GUI interface will be exposed to.
+export PROM_EXT_PORT_HTTP="9090"
+
+# Set the external port Grafana HTTP Dashboards will be exposed to.
+export GRAF_EXT_PORT_HTTP="3000"
+
+
+# ----- Apache Kafka -----------------------------------------------------------
+
+# Set the namespace where Apache Kafka will be deployed.
+export KFK_NAMESPACE="kafka"
+
+# Set the port Apache Kafka server will be exposed to.
+export KFK_SERVER_PORT="9092"
+
+# Set the flag to YES for redeploying of Apache Kafka
+export KFK_REDEPLOY=""
diff --git a/src/tests/ofc25-camara-e2e-controller/redeploy-tfs.sh b/src/tests/ofc25-camara-e2e-controller/redeploy-tfs.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d030596d707c5f49c14bc0f43a654bda3159b688
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/redeploy-tfs.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source ~/tfs-ctrl/src/tests/ofc25-camara-e2e-controller/deploy_specs.sh
+./deploy/all.sh
diff --git a/src/tests/ofc25-camara-e2e-controller/requirements.in b/src/tests/ofc25-camara-e2e-controller/requirements.in
new file mode 100644
index 0000000000000000000000000000000000000000..1bdaec9997da4b83fa89c1bf0d00d4c3a73558a4
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/requirements.in
@@ -0,0 +1,30 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+deepdiff==6.7.*
+requests==2.27.*
+
+coverage==6.3
+grpcio==1.47.*
+grpcio-health-checking==1.47.*
+grpcio-reflection==1.47.*
+grpcio-tools==1.47.*
+grpclib==0.4.4
+prettytable==3.5.0
+prometheus-client==0.13.0
+protobuf==3.20.*
+pytest==6.2.5
+pytest-benchmark==3.4.1
+python-dateutil==2.8.2
+pytest-depends==1.0.1
diff --git a/src/tests/ofc25-camara-e2e-controller/scripts/run-e2e-ietf-slice-operations.sh b/src/tests/ofc25-camara-e2e-controller/scripts/run-e2e-ietf-slice-operations.sh
new file mode 100755
index 0000000000000000000000000000000000000000..6c41a85db2d5363971531c814283edbf3ebc0d62
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/scripts/run-e2e-ietf-slice-operations.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source /var/teraflow/tfs_runtime_env_vars.sh
+export PYTHONPATH=/var/teraflow
+pytest --verbose --log-level=INFO \
+    --junitxml=/opt/results/report_e2e_ietf_slice_operations.xml \
+    /var/teraflow/tests/ofc25-camara-e2e-controller/tests/test_e2e_ietf_slice_operations.py
diff --git a/src/tests/ofc25-camara-e2e-controller/scripts/run-onboarding.sh b/src/tests/ofc25-camara-e2e-controller/scripts/run-onboarding.sh
new file mode 100755
index 0000000000000000000000000000000000000000..397d98d4b4db7952b2b879dcd1977c1a43cc30a2
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/scripts/run-onboarding.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source /var/teraflow/tfs_runtime_env_vars.sh
+export PYTHONPATH=/var/teraflow
+pytest --verbose --log-level=INFO \
+    --junitxml=/opt/results/report_onboarding.xml \
+    /var/teraflow/tests/ofc25-camara-e2e-controller/tests/test_onboarding.py
diff --git a/src/tests/ofc25-camara-e2e-controller/tests/Fixtures.py b/src/tests/ofc25-camara-e2e-controller/tests/Fixtures.py
new file mode 100644
index 0000000000000000000000000000000000000000..15978851faae668339fa4eed6db8ab7e1be2eb5e
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/tests/Fixtures.py
@@ -0,0 +1,43 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import pytest
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from monitoring.client.MonitoringClient import MonitoringClient
+from service.client.ServiceClient import ServiceClient
+
+@pytest.fixture(scope='session')
+def context_client():
+    _client = ContextClient()
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def device_client():
+    _client = DeviceClient()
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def monitoring_client():
+    _client = MonitoringClient()
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def service_client():
+    _client = ServiceClient()
+    yield _client
+    _client.close()
diff --git a/src/tests/ofc25-camara-e2e-controller/tests/Tools.py b/src/tests/ofc25-camara-e2e-controller/tests/Tools.py
new file mode 100644
index 0000000000000000000000000000000000000000..cd2add49edd23f4c169b5fdc3c5123b2b31daa8d
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/tests/Tools.py
@@ -0,0 +1,109 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import enum, logging, requests
+from typing import Any, Dict, List, Optional, Set, Union
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_host, get_service_port_http
+
+NBI_ADDRESS  = get_service_host(ServiceNameEnum.NBI)
+NBI_PORT     = get_service_port_http(ServiceNameEnum.NBI)
+NBI_USERNAME = 'admin'
+NBI_PASSWORD = 'admin'
+NBI_BASE_URL = ''
+
+class RestRequestMethod(enum.Enum):
+    GET    = 'get'
+    POST   = 'post'
+    PUT    = 'put'
+    PATCH  = 'patch'
+    DELETE = 'delete'
+
+EXPECTED_STATUS_CODES : Set[int] = {
+    requests.codes['OK'        ],
+    requests.codes['CREATED'   ],
+    requests.codes['ACCEPTED'  ],
+    requests.codes['NO_CONTENT'],
+}
+
+def do_rest_request(
+    method : RestRequestMethod, url : str, body : Optional[Any] = None, timeout : int = 10,
+    allow_redirects : bool = True, expected_status_codes : Set[int] = EXPECTED_STATUS_CODES,
+    logger : Optional[logging.Logger] = None
+) -> Optional[Union[Dict, List]]:
+    request_url = 'http://{:s}:{:s}@{:s}:{:d}{:s}{:s}'.format(
+        NBI_USERNAME, NBI_PASSWORD, NBI_ADDRESS, NBI_PORT, str(NBI_BASE_URL), url
+    )
+
+    if logger is not None:
+        msg = 'Request: {:s} {:s}'.format(str(method.value).upper(), str(request_url))
+        if body is not None: msg += ' body={:s}'.format(str(body))
+        logger.warning(msg)
+    reply = requests.request(method.value, request_url, headers={'Content-Type': 'application/json'}, timeout=timeout, json=body, allow_redirects=allow_redirects)
+    if logger is not None:
+        logger.warning('Reply: {:s}'.format(str(reply.text)))
+    assert reply.status_code in expected_status_codes, 'Reply failed with status code {:d}'.format(reply.status_code)
+
+    if reply.content and len(reply.content) > 0: return reply.json()
+    return None
+
+def do_rest_get_request(
+    url : str, body : Optional[Any] = None, timeout : int = 10,
+    allow_redirects : bool = True, expected_status_codes : Set[int] = EXPECTED_STATUS_CODES,
+    logger : Optional[logging.Logger] = None
+) -> Optional[Union[Dict, List]]:
+    return do_rest_request(
+        RestRequestMethod.GET, url, body=body, timeout=timeout, allow_redirects=allow_redirects,
+        expected_status_codes=expected_status_codes, logger=logger
+    )
+
+def do_rest_post_request(
+    url : str, body : Optional[Any] = None, timeout : int = 10,
+    allow_redirects : bool = True, expected_status_codes : Set[int] = EXPECTED_STATUS_CODES,
+    logger : Optional[logging.Logger] = None
+) -> Optional[Union[Dict, List]]:
+    return do_rest_request(
+        RestRequestMethod.POST, url, body=body, timeout=timeout, allow_redirects=allow_redirects,
+        expected_status_codes=expected_status_codes, logger=logger
+    )
+
+def do_rest_put_request(
+    url : str, body : Optional[Any] = None, timeout : int = 10,
+    allow_redirects : bool = True, expected_status_codes : Set[int] = EXPECTED_STATUS_CODES,
+    logger : Optional[logging.Logger] = None
+) -> Optional[Union[Dict, List]]:
+    return do_rest_request(
+        RestRequestMethod.PUT, url, body=body, timeout=timeout, allow_redirects=allow_redirects,
+        expected_status_codes=expected_status_codes, logger=logger
+    )
+
+def do_rest_patch_request(
+    url : str, body : Optional[Any] = None, timeout : int = 10,
+    allow_redirects : bool = True, expected_status_codes : Set[int] = EXPECTED_STATUS_CODES,
+    logger : Optional[logging.Logger] = None
+) -> Optional[Union[Dict, List]]:
+    return do_rest_request(
+        RestRequestMethod.PATCH, url, body=body, timeout=timeout, allow_redirects=allow_redirects,
+        expected_status_codes=expected_status_codes, logger=logger
+    )
+
+def do_rest_delete_request(
+    url : str, body : Optional[Any] = None, timeout : int = 10,
+    allow_redirects : bool = True, expected_status_codes : Set[int] = EXPECTED_STATUS_CODES,
+    logger : Optional[logging.Logger] = None
+) -> Optional[Union[Dict, List]]:
+    return do_rest_request(
+        RestRequestMethod.DELETE, url, body=body, timeout=timeout, allow_redirects=allow_redirects,
+        expected_status_codes=expected_status_codes, logger=logger
+    )
diff --git a/src/tests/ofc25-camara-e2e-controller/tests/__init__.py b/src/tests/ofc25-camara-e2e-controller/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ccc21c7db78aac26daa1f8c5ff8e1ffd3f35460
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/tests/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/tests/ofc25-camara-e2e-controller/tests/test_e2e_ietf_slice_operations.py b/src/tests/ofc25-camara-e2e-controller/tests/test_e2e_ietf_slice_operations.py
new file mode 100644
index 0000000000000000000000000000000000000000..cb991edbf1f3cc0768d006ef58725e621ac83de9
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/tests/test_e2e_ietf_slice_operations.py
@@ -0,0 +1,478 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json, logging, os
+import requests
+from deepdiff import DeepDiff
+
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+HEADERS = {"Content-Type": "application/json"}
+
+POST_NETWORK_SLICE1 = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "slice",
+    "post_network_slice1.json",
+)
+POST_NETWORK_SLICE2 = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "slice",
+    "post_network_slice2.json",
+)
+POST_CONNECTION_GROUP_TO_NETWORK_SLICE1 = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "slice",
+    "post_connection_group_to_network_slice1.json",
+)
+POST_CONNECTION_GROUP_TO_NETWORK_SLICE2 = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "slice",
+    "post_connection_group_to_network_slice2.json",
+)
+POST_MATCH_CRITERIA_TO_SDP1_IN_SLICE1 = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "slice",
+    "post_match_criteria_to_sdp1_in_slice1.json",
+)
+POST_MATCH_CRITERIA_TO_SDP1_IN_SLICE2 = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "slice",
+    "post_match_criteria_to_sdp1_in_slice2.json",
+)
+POST_SDP_TO_NETWORK_SLICE1 = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "slice",
+    "post_sdp_to_network_slice1.json",
+)
+POST_SDP_TO_NETWORK_SLICE2 = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "slice",
+    "post_sdp_to_network_slice2.json",
+)
+TARGET_NCE_APP_FLOWS = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "target-nce-app-flows.json",
+)
+TARGET_NCE_APPS = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "target-nce-apps.json",
+)
+TARGET_FULL_IETF_SLICE = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "slice",
+    "target-full-ietf-slice.json",
+)
+TARGET_FULL_IETF_SLICE = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "target-full-ietf-slice.json",
+)
+TARGET_IETF_SLICE_POSTED_SLICES = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "target-ietf-slice-posted-slices.json",
+)
+TARGET_IETF_SLICE_PUT_CONNECTION_GROUPS = os.path.join(
+    os.path.dirname(os.path.abspath(__file__)),
+    "..",
+    "data",
+    "target-ietf-slice-put-connection-groups.json",
+)
+
+NBI_ADDRESS = "localhost"
+NBI_PORT = "80"
+NBI_USERNAME = "admin"
+NBI_PASSWORD = "admin"
+
+NCE_ADDRESS = "localhost"
+NCE_PORT = 9090
+
+AGG_TFS_ADDRESS = "localhost"
+AGG_TFS_PORT = 9091
+
+BASE_IETF_SLICE_URL = f"http://{NBI_ADDRESS}:{NBI_PORT}/restconf/data/ietf-network-slice-service:network-slice-services"
+NCE_APP_DATA_URL = f"http://{NCE_ADDRESS}:{NCE_PORT}/restconf/v1/data/app-flows/apps"
+NCE_APP_FLOW_DATA_URL = f"http://{NCE_ADDRESS}:{NCE_PORT}/restconf/v1/data/app-flows"
+AGG_TFS_IETF_SLICE_URL = f"http://{AGG_TFS_ADDRESS}:{AGG_TFS_PORT}/restconf/data/ietf-network-slice-service:network-slice-services"
+
+
+# pylint: disable=redefined-outer-name, unused-argument
+def test_ietf_slice_creation_removal():
+    # Issue service creation request
+    with open(POST_NETWORK_SLICE1, "r", encoding="UTF-8") as f:
+        post_network_slice1 = json.load(f)
+    with open(POST_NETWORK_SLICE2, "r", encoding="UTF-8") as f:
+        post_network_slice2 = json.load(f)
+    with open(POST_CONNECTION_GROUP_TO_NETWORK_SLICE1, "r", encoding="UTF-8") as f:
+        post_connection_group_to_network_slice1 = json.load(f)
+    with open(POST_CONNECTION_GROUP_TO_NETWORK_SLICE2, "r", encoding="UTF-8") as f:
+        post_connection_group_to_network_slice2 = json.load(f)
+    with open(POST_MATCH_CRITERIA_TO_SDP1_IN_SLICE1, "r", encoding="UTF-8") as f:
+        post_match_criteria_to_sdp1_in_slice1 = json.load(f)
+    with open(POST_MATCH_CRITERIA_TO_SDP1_IN_SLICE2, "r", encoding="UTF-8") as f:
+        post_match_criteria_to_sdp1_in_slice2 = json.load(f)
+    with open(POST_SDP_TO_NETWORK_SLICE1, "r", encoding="UTF-8") as f:
+        post_sdp_to_network_slice1 = json.load(f)
+    with open(POST_SDP_TO_NETWORK_SLICE2, "r", encoding="UTF-8") as f:
+        post_sdp_to_network_slice2 = json.load(f)
+    with open(TARGET_NCE_APPS, "r", encoding="UTF-8") as f:
+        target_nce_apps = json.load(f)
+    with open(TARGET_NCE_APP_FLOWS, "r", encoding="UTF-8") as f:
+        target_nce_app_flows = json.load(f)
+    with open(TARGET_FULL_IETF_SLICE, "r", encoding="UTF-8") as f:
+        target_full_ietf_slice = json.load(f)
+    with open(TARGET_IETF_SLICE_POSTED_SLICES, "r", encoding="UTF-8") as f:
+        target_ietf_slice_posted_slices = json.load(f)
+    with open(TARGET_IETF_SLICE_PUT_CONNECTION_GROUPS, "r", encoding="UTF-8") as f:
+        target_ietf_slice_put_connection_groups = json.load(f)
+
+    # op 1
+    URL = BASE_IETF_SLICE_URL
+    requests.post(URL, headers=HEADERS, json=post_network_slice1)
+
+    URL = NCE_APP_DATA_URL
+    apps_response = requests.get(URL).json()
+    URL = NCE_APP_FLOW_DATA_URL
+    app_flows_response = requests.get(URL).json()
+    URL = AGG_TFS_IETF_SLICE_URL
+    ietf_slice_services = requests.get(URL).json()
+    URL = (
+        AGG_TFS_IETF_SLICE_URL
+        + "/slice-service=dummy/connection-groups/connection-group=dummy"
+    )
+    ietf_slice_connection_groups = requests.get(URL).json()
+
+    app_name = "App_Flow_2_1_slice1"
+    apps_diff = DeepDiff(apps_response[app_name], target_nce_apps[app_name])
+    app_flows_diff = DeepDiff(
+        app_flows_response[app_name],
+        target_nce_app_flows[app_name],
+        exclude_regex_paths=r"root\['app-flow'\]\[\d+\]\['user-id'\]",
+    )
+    assert not apps_diff
+    assert not app_flows_diff
+    assert len(apps_response) == 1 and len(app_flows_response) == 1
+
+    assert len(ietf_slice_connection_groups) == 0
+    assert len(ietf_slice_services) == 1
+    slice_diff = DeepDiff(
+        ietf_slice_services["slice1"], target_ietf_slice_posted_slices[0]
+    )
+    assert not slice_diff
+
+    # op 2
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice1/sdps"
+    requests.post(URL, headers=HEADERS, json=post_sdp_to_network_slice1)
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice1/connection-groups"
+    requests.post(URL, headers=HEADERS, json=post_connection_group_to_network_slice1)
+    URL = (
+        BASE_IETF_SLICE_URL + "/slice-service=slice1/sdps/sdp=1/service-match-criteria"
+    )
+    requests.post(URL, headers=HEADERS, json=post_match_criteria_to_sdp1_in_slice1)
+
+    URL = NCE_APP_DATA_URL
+    apps_response = requests.get(URL).json()
+    URL = NCE_APP_FLOW_DATA_URL
+    app_flows_response = requests.get(URL).json()
+    URL = AGG_TFS_IETF_SLICE_URL
+    ietf_slice_services = requests.get(URL).json()
+    URL = (
+        AGG_TFS_IETF_SLICE_URL
+        + "/slice-service=dummy/connection-groups/connection-group=dummy"
+    )
+    ietf_slice_connection_groups = requests.get(URL).json()
+
+    app_name = "App_Flow_3_1_slice1"
+    apps_diff = DeepDiff(apps_response[app_name], target_nce_apps[app_name])
+    app_flows_diff = DeepDiff(
+        app_flows_response[app_name],
+        target_nce_app_flows[app_name],
+        exclude_regex_paths=r"root\['app-flow'\]\[\d+\]\['user-id'\]",
+    )
+    assert not apps_diff
+    assert not app_flows_diff
+    assert len(apps_response) == 2 and len(app_flows_response) == 2
+
+    assert len(ietf_slice_connection_groups) == 1
+    assert len(ietf_slice_services) == 1
+    connection_group_diff = DeepDiff(
+        ietf_slice_connection_groups[0], target_ietf_slice_put_connection_groups[0]
+    )
+    assert not connection_group_diff
+
+    # op 3
+    URL = BASE_IETF_SLICE_URL
+    requests.post(URL, headers=HEADERS, json=post_network_slice2)
+
+    URL = NCE_APP_DATA_URL
+    apps_response = requests.get(URL).json()
+    URL = NCE_APP_FLOW_DATA_URL
+    app_flows_response = requests.get(URL).json()
+    URL = AGG_TFS_IETF_SLICE_URL
+    ietf_slice_services = requests.get(URL).json()
+    URL = (
+        AGG_TFS_IETF_SLICE_URL
+        + "/slice-service=dummy/connection-groups/connection-group=dummy"
+    )
+    ietf_slice_connection_groups = requests.get(URL).json()
+
+    app_name = "App_Flow_2_1_slice2"
+    apps_diff = DeepDiff(apps_response[app_name], target_nce_apps[app_name])
+    app_flows_diff = DeepDiff(
+        app_flows_response[app_name],
+        target_nce_app_flows[app_name],
+        exclude_regex_paths=r"root\['app-flow'\]\[\d+\]\['user-id'\]",
+    )
+    assert not apps_diff
+    assert not app_flows_diff
+    assert len(apps_response) == 3 and len(app_flows_response) == 3
+
+    assert len(ietf_slice_connection_groups) == 1
+    assert len(ietf_slice_services) == 2
+    slice_diff = DeepDiff(
+        ietf_slice_services["slice2"], target_ietf_slice_posted_slices[1]
+    )
+    assert not slice_diff
+
+    # op 4
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice2/sdps"
+    requests.post(URL, headers=HEADERS, json=post_sdp_to_network_slice2)
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice2/connection-groups"
+    requests.post(URL, headers=HEADERS, json=post_connection_group_to_network_slice2)
+    URL = (
+        BASE_IETF_SLICE_URL + "/slice-service=slice2/sdps/sdp=1/service-match-criteria"
+    )
+    requests.post(URL, headers=HEADERS, json=post_match_criteria_to_sdp1_in_slice2)
+
+    URL = NCE_APP_DATA_URL
+    apps_response = requests.get(URL).json()
+    URL = NCE_APP_FLOW_DATA_URL
+    app_flows_response = requests.get(URL).json()
+    URL = AGG_TFS_IETF_SLICE_URL
+    ietf_slice_services = requests.get(URL).json()
+    URL = (
+        AGG_TFS_IETF_SLICE_URL
+        + "/slice-service=dummy/connection-groups/connection-group=dummy"
+    )
+    ietf_slice_connection_groups = requests.get(URL).json()
+
+    app_name = "App_Flow_3_1_slice2"
+    apps_diff = DeepDiff(apps_response[app_name], target_nce_apps[app_name])
+    app_flows_diff = DeepDiff(
+        app_flows_response[app_name],
+        target_nce_app_flows[app_name],
+        exclude_regex_paths=r"root\['app-flow'\]\[\d+\]\['user-id'\]",
+    )
+    assert not apps_diff
+    assert not app_flows_diff
+    assert len(apps_response) == 4 and len(app_flows_response) == 4
+
+    assert len(ietf_slice_connection_groups) == 2
+    assert len(ietf_slice_services) == 2
+    connection_group_diff = DeepDiff(
+        ietf_slice_connection_groups[1], target_ietf_slice_put_connection_groups[1]
+    )
+    assert not connection_group_diff
+
+    # op 5
+    ietf_slices_full_retrieved = requests.get(BASE_IETF_SLICE_URL).json()
+    ietf_slice_data = DeepDiff(ietf_slices_full_retrieved, target_full_ietf_slice)
+    assert not ietf_slice_data
+
+    # op 6
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice1/sdps/sdp=2"
+    requests.delete(URL)
+    URL = (
+        BASE_IETF_SLICE_URL
+        + "/slice-service=slice1/sdps/sdp=1/service-match-criteria/match-criterion=1"
+    )
+    requests.delete(URL)
+    URL = (
+        BASE_IETF_SLICE_URL
+        + "/slice-service=slice1/connection-groups/connection-group=line1"
+    )
+    requests.delete(URL)
+
+    URL = NCE_APP_DATA_URL
+    apps_response = requests.get(URL).json()
+    URL = NCE_APP_FLOW_DATA_URL
+    app_flows_response = requests.get(URL).json()
+    URL = AGG_TFS_IETF_SLICE_URL
+    ietf_slice_services = requests.get(URL).json()
+    URL = (
+        AGG_TFS_IETF_SLICE_URL
+        + "/slice-service=dummy/connection-groups/connection-group=dummy"
+    )
+    ietf_slice_connection_groups = requests.get(URL).json()
+
+    app_name = "App_Flow_2_1_slice1"
+    assert app_name not in apps_response
+    assert app_name not in app_flows_response
+    assert len(apps_response) == 3 and len(app_flows_response) == 3
+
+    assert len(ietf_slice_connection_groups) == 3
+    assert len(ietf_slice_services) == 2
+    connection_group_diff = DeepDiff(
+        ietf_slice_connection_groups[2], target_ietf_slice_put_connection_groups[2]
+    )
+    assert not connection_group_diff
+
+    # op 7
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice1/sdps/sdp=3"
+    requests.delete(URL)
+    URL = (
+        BASE_IETF_SLICE_URL
+        + "/slice-service=slice1/sdps/sdp=1/service-match-criteria/match-criterion=2"
+    )
+    requests.delete(URL)
+    URL = (
+        BASE_IETF_SLICE_URL
+        + "/slice-service=slice1/connection-groups/connection-group=line2"
+    )
+    requests.delete(URL)
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice1/sdps/sdp=1"
+
+    URL = NCE_APP_DATA_URL
+    apps_response = requests.get(URL).json()
+    URL = NCE_APP_FLOW_DATA_URL
+    app_flows_response = requests.get(URL).json()
+    URL = AGG_TFS_IETF_SLICE_URL
+    ietf_slice_services = requests.get(URL).json()
+    URL = (
+        AGG_TFS_IETF_SLICE_URL
+        + "/slice-service=dummy/connection-groups/connection-group=dummy"
+    )
+    ietf_slice_connection_groups = requests.get(URL).json()
+
+    requests.delete(URL)
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice1"
+    requests.delete(URL)
+
+    app_name = "App_Flow_3_1_slice1"
+    assert app_name not in apps_response
+    assert app_name not in app_flows_response
+    assert len(apps_response) == 2 and len(app_flows_response) == 2
+
+    assert len(ietf_slice_connection_groups) == 3
+    assert len(ietf_slice_services) == 1
+    assert "slice1" not in ietf_slice_services
+
+    # op 8
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice2/sdps/sdp=2"
+    requests.delete(URL)
+    URL = (
+        BASE_IETF_SLICE_URL
+        + "/slice-service=slice2/sdps/sdp=1/service-match-criteria/match-criterion=1"
+    )
+    requests.delete(URL)
+    URL = (
+        BASE_IETF_SLICE_URL
+        + "/slice-service=slice2/connection-groups/connection-group=line1"
+    )
+    requests.delete(URL)
+
+    URL = NCE_APP_DATA_URL
+    apps_response = requests.get(URL).json()
+    URL = NCE_APP_FLOW_DATA_URL
+    app_flows_response = requests.get(URL).json()
+    URL = AGG_TFS_IETF_SLICE_URL
+    ietf_slice_services = requests.get(URL).json()
+    URL = (
+        AGG_TFS_IETF_SLICE_URL
+        + "/slice-service=dummy/connection-groups/connection-group=dummy"
+    )
+    ietf_slice_connection_groups = requests.get(URL).json()
+
+    app_name = "App_Flow_2_1_slice2"
+    assert app_name not in apps_response
+    assert app_name not in app_flows_response
+    assert len(apps_response) == 1 and len(app_flows_response) == 1
+
+    assert len(ietf_slice_connection_groups) == 4
+    assert len(ietf_slice_services) == 1
+    connection_group_diff = DeepDiff(
+        ietf_slice_connection_groups[3], target_ietf_slice_put_connection_groups[3]
+    )
+    assert not connection_group_diff
+
+    # op 9
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice2/sdps/sdp=3"
+    requests.delete(URL)
+    URL = (
+        BASE_IETF_SLICE_URL
+        + "/slice-service=slice2/sdps/sdp=1/service-match-criteria/match-criterion=2"
+    )
+    requests.delete(URL)
+    URL = (
+        BASE_IETF_SLICE_URL
+        + "/slice-service=slice2/connection-groups/connection-group=line2"
+    )
+    requests.delete(URL)
+
+    URL = NCE_APP_DATA_URL
+    apps_response = requests.get(URL).json()
+    URL = NCE_APP_FLOW_DATA_URL
+    app_flows_response = requests.get(URL).json()
+    URL = AGG_TFS_IETF_SLICE_URL
+    ietf_slice_services = requests.get(URL).json()
+    URL = (
+        AGG_TFS_IETF_SLICE_URL
+        + "/slice-service=dummy/connection-groups/connection-group=dummy"
+    )
+    ietf_slice_connection_groups = requests.get(URL).json()
+
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice2/sdps/sdp=1"
+    requests.delete(URL)
+    URL = BASE_IETF_SLICE_URL + "/slice-service=slice2"
+    requests.delete(URL)
+
+    app_name = "App_Flow_3_1_slice2"
+    assert app_name not in apps_response
+    assert app_name not in app_flows_response
+    assert len(apps_response) == 0 and len(app_flows_response) == 0
+
+    assert len(ietf_slice_connection_groups) == 4
+    assert len(ietf_slice_services) == 0
+
+    # op 10
+    ietf_slices_full_retrieved = requests.get(BASE_IETF_SLICE_URL).json()
+    empty_ietf_slices = {"network-slice-services": {"slice-service": []}}
+    ietf_slice_data = DeepDiff(ietf_slices_full_retrieved, empty_ietf_slices)
+    assert not ietf_slice_data
diff --git a/src/tests/ofc25-camara-e2e-controller/tests/test_onboarding.py b/src/tests/ofc25-camara-e2e-controller/tests/test_onboarding.py
new file mode 100644
index 0000000000000000000000000000000000000000..05e031da7b3ab88a8ee3f3c80fdddb92d9f26913
--- /dev/null
+++ b/src/tests/ofc25-camara-e2e-controller/tests/test_onboarding.py
@@ -0,0 +1,67 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging, os, time
+from common.Constants import DEFAULT_CONTEXT_NAME
+from common.proto.context_pb2 import ContextId, DeviceOperationalStatusEnum, Empty
+from common.tools.descriptor.Loader import DescriptorLoader, check_descriptor_load_results, validate_empty_scenario
+from common.tools.object_factory.Context import json_context_id
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from .Fixtures import context_client, device_client # pylint: disable=unused-import
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+DESCRIPTOR_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'data', 'camara-e2e-topology.json')
+ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME))
+
+def test_scenario_onboarding(
+    context_client : ContextClient, # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,   # pylint: disable=redefined-outer-name
+) -> None:
+    validate_empty_scenario(context_client)
+
+    descriptor_loader = DescriptorLoader(
+        descriptors_file=DESCRIPTOR_FILE, context_client=context_client, device_client=device_client)
+    results = descriptor_loader.process()
+    check_descriptor_load_results(results, descriptor_loader)
+    # descriptor_loader.validate()
+
+    # Verify the scenario has no services/slices
+    response = context_client.GetContext(ADMIN_CONTEXT_ID)
+    assert len(response.service_ids) == 0
+    assert len(response.slice_ids) == 0
+
+def test_scenario_devices_enabled(
+    context_client : ContextClient,         # pylint: disable=redefined-outer-name
+) -> None:
+    """
+    This test validates that the devices are enabled.
+    """
+    DEVICE_OP_STATUS_ENABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
+
+    num_devices = -1
+    num_devices_enabled, num_retry = 0, 0
+    while (num_devices != num_devices_enabled) and (num_retry < 10):
+        time.sleep(1.0)
+        response = context_client.ListDevices(Empty())
+        num_devices = len(response.devices)
+        num_devices_enabled = 0
+        for device in response.devices:
+            if device.device_operational_status != DEVICE_OP_STATUS_ENABLED: continue
+            num_devices_enabled += 1
+        LOGGER.info('Num Devices enabled: {:d}/{:d}'.format(num_devices_enabled, num_devices))
+        num_retry += 1
+    assert num_devices_enabled == num_devices
diff --git a/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/Dockerfile b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..b2ac55af45ba673cd7c119f19a5245d065d02ea3
--- /dev/null
+++ b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/Dockerfile
@@ -0,0 +1,37 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+FROM python:3.9-slim
+
+# Set Python to show logs as they occur
+ENV PYTHONUNBUFFERED=0
+
+# Get generic Python packages
+RUN python3 -m pip install --upgrade pip
+RUN python3 -m pip install --upgrade setuptools wheel
+RUN python3 -m pip install --upgrade pip-tools
+
+# Create component sub-folders, and copy content
+RUN mkdir -p /var/teraflow/mock_ietf_l3vpn_sdn_ctrl
+WORKDIR /var/teraflow/mock_ietf_l3vpn_sdn_ctrl
+COPY . .
+
+# Get specific Python packages
+RUN pip-compile --quiet --output-file=requirements.txt requirements.in
+RUN python3 -m pip install -r requirements.txt
+
+RUN python3 -m pip list
+
+# Start the service
+ENTRYPOINT ["python", "MockIetfL3VPNSdnCtrl.py"]
diff --git a/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/L3VPNServices.py b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/L3VPNServices.py
new file mode 100644
index 0000000000000000000000000000000000000000..1e4d7c6195a3dd0b0cb6c124f788c2efa5fe7927
--- /dev/null
+++ b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/L3VPNServices.py
@@ -0,0 +1,44 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# REST-API resource implementing minimal support for "IETF YANG Data Model for Transport Network Client Signals".
+# Ref: https://www.ietf.org/archive/id/draft-ietf-ccamp-client-signal-yang-10.html
+
+from flask import jsonify, make_response, request
+from flask_restful import Resource
+
+VPN_SERVICES = {}
+
+
+class L3VPNServices(Resource):
+    def get(self):
+        return make_response(jsonify(VPN_SERVICES), 200)
+
+    def post(self):
+        json_request = request.get_json()
+        name = json_request["ietf-l3vpn-svc:l3vpn-svc"]["vpn-services"]["vpn-service"][0]["vpn-id"]
+        VPN_SERVICES[name] = json_request
+        return make_response(jsonify({}), 201)
+
+
+class L3VPNService(Resource):
+    def put(self, vpn_id: str):
+        json_request = request.get_json()
+        VPN_SERVICES[vpn_id] = json_request
+        return make_response(jsonify({}), 200)
+
+    def delete(self, vpn_id: str):
+        slice = VPN_SERVICES.pop(vpn_id, None)
+        data, status = ({}, 404) if slice is None else (slice, 204)
+        return make_response(jsonify(data), status)
diff --git a/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/MockIetfL3VPNSdnCtrl.py b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/MockIetfL3VPNSdnCtrl.py
new file mode 100644
index 0000000000000000000000000000000000000000..49685aa19902c619cdc0259b5cb0573dbf77bd63
--- /dev/null
+++ b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/MockIetfL3VPNSdnCtrl.py
@@ -0,0 +1,77 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Mock IETF ACTN SDN controller
+# -----------------------------
+# REST server implementing minimal support for:
+# - IETF YANG Data Model for Transport Network Client Signals
+#       Ref: https://www.ietf.org/archive/id/draft-ietf-ccamp-client-signal-yang-10.html
+# - IETF YANG Data Model for Traffic Engineering Tunnels, Label Switched Paths and Interfaces
+#       Ref: https://www.ietf.org/archive/id/draft-ietf-teas-yang-te-34.html
+
+
+import functools, logging, sys, time
+from flask import Flask, request
+from flask_restful import Api
+
+from L3VPNServices import L3VPNService, L3VPNServices
+
+BIND_ADDRESS = "0.0.0.0"
+BIND_PORT = 8443
+BASE_URL = "/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services"
+STR_ENDPOINT = "http://{:s}:{:s}{:s}".format(
+    str(BIND_ADDRESS), str(BIND_PORT), str(BASE_URL)
+)
+LOG_LEVEL = logging.DEBUG
+
+logging.basicConfig(
+    level=LOG_LEVEL, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s"
+)
+LOGGER = logging.getLogger(__name__)
+
+logging.getLogger("werkzeug").setLevel(logging.WARNING)
+
+
+def log_request(logger: logging.Logger, response):
+    timestamp = time.strftime("[%Y-%b-%d %H:%M]")
+    logger.info(
+        "%s %s %s %s %s",
+        timestamp,
+        request.remote_addr,
+        request.method,
+        request.full_path,
+        response.status,
+    )
+    return response
+
+
+def main():
+    LOGGER.info("Starting...")
+
+    app = Flask(__name__)
+    app.after_request(functools.partial(log_request, LOGGER))
+
+    api = Api(app, prefix=BASE_URL)
+    api.add_resource(L3VPNServices, "")
+    api.add_resource(L3VPNService, "/vpn-service=<string:vpn_id>")
+
+    LOGGER.info("Listening on {:s}...".format(str(STR_ENDPOINT)))
+    app.run(debug=True, host=BIND_ADDRESS, port=BIND_PORT)
+
+    LOGGER.info("Bye")
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/README.md b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..ed9d744f7641e20ddd39b51f837ea68e47fe64c0
--- /dev/null
+++ b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/README.md
@@ -0,0 +1,31 @@
+# Mock IETF L3VPN SDN Controller
+
+This REST server implements very basic support for the following YANG data models:
+- YANG Data Model for L3VPN Service Delivery
+  - Ref: https://datatracker.ietf.org/doc/html/rfc8049
+
+The aim of this server is to enable testing ietf netowrk slice service handler, ietf l3vpn service handler, and ietf l3vpn driver
+
+
+## 1. Install requirements for the Mock IETF Network Slice SDN controller
+__NOTE__: if you run the Mock IETF L3VPN SDN controller from the PyEnv used for developing on the TeraFlowSDN
+framework and you followed the official steps in
+[Development Guide > Configure Environment > Python](https://labs.etsi.org/rep/tfs/controller/-/wikis/2.-Development-Guide/2.1.-Configure-Environment/2.1.1.-Python),
+all the requirements are already in place. Install them only if you execute it in a separate/standalone environment.
+
+Install the required dependencies as follows:
+```bash
+pip install -r src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/requirements.in
+```
+
+Run the Mock IETF L3VPN SDN Controller as follows:
+```bash
+python src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/MockIetfL3VPNSdnCtrl.py
+```
+
+
+## 2. Run the Mock IETF L3VPN SDN controller
+Run the Mock IETF L3VPN SDN Controller as follows:
+```bash
+python src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/MockIetfL3VPNSdnCtrl.py
+```
diff --git a/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/__init__.py b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ccc21c7db78aac26daa1f8c5ff8e1ffd3f35460
--- /dev/null
+++ b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/build.sh b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/build.sh
new file mode 100755
index 0000000000000000000000000000000000000000..e5f12798556b0c9c044d86c0f175aeec9d0cff23
--- /dev/null
+++ b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/build.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Make folder containing the script the root folder for its execution
+cd $(dirname $0)
+
+docker build -t mock-ietf-l3vpn-sdn-ctrl:test -f Dockerfile .
+docker tag mock-ietf-l3vpn-sdn-ctrl:test localhost:32000/tfs/mock-ietf-l3vpn-sdn-ctrl:test
+docker push localhost:32000/tfs/mock-ietf-l3vpn-sdn-ctrl:test
diff --git a/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/deploy.sh b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/deploy.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1c6e68deb33de588cffab91fda550aafe222ce37
--- /dev/null
+++ b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/deploy.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+kubectl delete namespace mocks
+kubectl --namespace mocks apply -f mock-ietf-l3vpn-sdn-ctrl.yaml
diff --git a/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/mock-ietf-network-slice-sdn-ctrl.yaml b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/mock-ietf-network-slice-sdn-ctrl.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ace79810f0cbfbd6605ef049c71c6c75cf5c0317
--- /dev/null
+++ b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/mock-ietf-network-slice-sdn-ctrl.yaml
@@ -0,0 +1,64 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+kind: Namespace
+apiVersion: v1
+metadata:
+  name: mocks
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: mock-ietf-l3vpn-sdn-ctrl
+spec:
+  selector:
+    matchLabels:
+      app: mock-ietf-l3vpn-sdn-ctrl
+  replicas: 1
+  template:
+    metadata:
+      annotations:
+        config.linkerd.io/skip-inbound-ports: "8443"
+      labels:
+        app: mock-ietf-l3vpn-sdn-ctrl
+    spec:
+      terminationGracePeriodSeconds: 5
+      containers:
+      - name: server
+        image: localhost:32000/tfs/mock-ietf-l3vpn-sdn-ctrl:test
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 8443
+        resources:
+          requests:
+            cpu: 250m
+            memory: 512Mi
+          limits:
+            cpu: 700m
+            memory: 1024Mi
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: mock-ietf-l3vpn-sdn-ctrl
+  labels:
+    app: mock-ietf-l3vpn-sdn-ctrl
+spec:
+  type: ClusterIP
+  selector:
+    app: mock-ietf-l3vpn-sdn-ctrl
+  ports:
+  - name: http
+    port: 8443
+    targetPort: 8443
diff --git a/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/requirements.in b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/requirements.in
new file mode 100644
index 0000000000000000000000000000000000000000..dbb8e95d65cfd0f1ee60d9bb4f840393ac893725
--- /dev/null
+++ b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/requirements.in
@@ -0,0 +1,22 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cryptography==39.0.1
+pyopenssl==23.0.0
+Flask==2.1.3
+Flask-HTTPAuth==4.5.0
+Flask-RESTful==0.3.9
+jsonschema==4.4.0
+requests==2.27.1
+werkzeug==2.3.7
diff --git a/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/run.sh b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..3c0ddc2b06f8f3af6ed3645a65fcea31888c82de
--- /dev/null
+++ b/src/tests/tools/mock_ietf_l3vpn_sdn_ctrl/run.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Make folder containing the script the root folder for its execution
+cd $(dirname $0)
+
+python MockIetfL3VPNSdnCtrl.py
diff --git a/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/Dockerfile b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..a624152de7d9188067a5828b4a8958b8d3418694
--- /dev/null
+++ b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/Dockerfile
@@ -0,0 +1,37 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+FROM python:3.9-slim
+
+# Set Python to show logs as they occur
+ENV PYTHONUNBUFFERED=0
+
+# Get generic Python packages
+RUN python3 -m pip install --upgrade pip
+RUN python3 -m pip install --upgrade setuptools wheel
+RUN python3 -m pip install --upgrade pip-tools
+
+# Create component sub-folders, and copy content
+RUN mkdir -p /var/teraflow/mock_ietf_network_slice_sdn_ctrl
+WORKDIR /var/teraflow/mock_ietf_network_slice_sdn_ctrl
+COPY . .
+
+# Get specific Python packages
+RUN pip-compile --quiet --output-file=requirements.txt requirements.in
+RUN python3 -m pip install -r requirements.txt
+
+RUN python3 -m pip list
+
+# Start the service
+ENTRYPOINT ["python", "MockIetfNetworkSliceSdnCtrl.py"]
diff --git a/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/MockIetfNetworkSliceSdnCtrl.py b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/MockIetfNetworkSliceSdnCtrl.py
new file mode 100644
index 0000000000000000000000000000000000000000..8d13f1bafcd98c28f20033ab8859bc6cc4b207dd
--- /dev/null
+++ b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/MockIetfNetworkSliceSdnCtrl.py
@@ -0,0 +1,81 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Mock IETF ACTN SDN controller
+# -----------------------------
+# REST server implementing minimal support for:
+# - IETF YANG Data Model for Transport Network Client Signals
+#       Ref: https://www.ietf.org/archive/id/draft-ietf-ccamp-client-signal-yang-10.html
+# - IETF YANG Data Model for Traffic Engineering Tunnels, Label Switched Paths and Interfaces
+#       Ref: https://www.ietf.org/archive/id/draft-ietf-teas-yang-te-34.html
+
+
+import functools, logging, sys, time
+from flask import Flask, request
+from flask_restful import Api
+from ResourceNetworkSlices import NetworkSliceService, NetworkSliceServices
+from ResourceConnectionGroups import ConnectionGroup
+
+BIND_ADDRESS = "0.0.0.0"
+BIND_PORT = 8443
+BASE_URL = "/restconf/data/ietf-network-slice-service:network-slice-services"
+STR_ENDPOINT = "http://{:s}:{:s}{:s}".format(
+    str(BIND_ADDRESS), str(BIND_PORT), str(BASE_URL)
+)
+LOG_LEVEL = logging.DEBUG
+
+logging.basicConfig(
+    level=LOG_LEVEL, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s"
+)
+LOGGER = logging.getLogger(__name__)
+
+logging.getLogger("werkzeug").setLevel(logging.WARNING)
+
+
+def log_request(logger: logging.Logger, response):
+    timestamp = time.strftime("[%Y-%b-%d %H:%M]")
+    logger.info(
+        "%s %s %s %s %s",
+        timestamp,
+        request.remote_addr,
+        request.method,
+        request.full_path,
+        response.status,
+    )
+    return response
+
+
+def main():
+    LOGGER.info("Starting...")
+
+    app = Flask(__name__)
+    app.after_request(functools.partial(log_request, LOGGER))
+
+    api = Api(app, prefix=BASE_URL)
+    api.add_resource(NetworkSliceServices, "")
+    api.add_resource(NetworkSliceService, "/slice-service=<string:slice_id>")
+    api.add_resource(
+        ConnectionGroup,
+        "/slice-service=<string:slice_id>/connection-groups/connection-group=<string:connection_group_id>",
+    )
+
+    LOGGER.info("Listening on {:s}...".format(str(STR_ENDPOINT)))
+    app.run(debug=True, host=BIND_ADDRESS, port=BIND_PORT)
+
+    LOGGER.info("Bye")
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/README.md b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..493fe37362dbbb8e8dbdf1a9621cb81a15c64691
--- /dev/null
+++ b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/README.md
@@ -0,0 +1,31 @@
+# Mock IETF Network Slice SDN Controller
+
+This REST server implements very basic support for the following YANG data models:
+- IETF YANG Data Model for Transport Network Client Signals (draft-ietf-ccamp-client-signal-yang-10)
+  - Ref: https://datatracker.ietf.org/doc/draft-ietf-teas-ietf-network-slice-nbi-yang/
+
+The aim of this server is to enable testing ietf netowrk slice service driver and ietf slice service service handler
+
+
+## 1. Install requirements for the Mock IETF Network Slice SDN controller
+__NOTE__: if you run the Mock IETF Network Slice SDN controller from the PyEnv used for developing on the TeraFlowSDN
+framework and you followed the official steps in
+[Development Guide > Configure Environment > Python](https://labs.etsi.org/rep/tfs/controller/-/wikis/2.-Development-Guide/2.1.-Configure-Environment/2.1.1.-Python),
+all the requirements are already in place. Install them only if you execute it in a separate/standalone environment.
+
+Install the required dependencies as follows:
+```bash
+pip install -r src/tests/tools/mock_ietf_network_slice_sdn_ctrl/requirements.in
+```
+
+Run the Mock IETF Network Slice SDN Controller as follows:
+```bash
+python src/tests/tools/mock_ietf_network_slice_sdn_ctrl/MockIetfNetworkSliceSdnCtrl.py
+```
+
+
+## 2. Run the Mock IETF Network Slice SDN controller
+Run the Mock IETF Network Slice SDN Controller as follows:
+```bash
+python src/tests/tools/mock_ietf_network_slice_sdn_ctrl/MockIetfNetworkSliceSdnCtrl.py
+```
diff --git a/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/ResourceConnectionGroups.py b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/ResourceConnectionGroups.py
new file mode 100644
index 0000000000000000000000000000000000000000..19c84e181a97354940fd3dca8f3d6396c0a50068
--- /dev/null
+++ b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/ResourceConnectionGroups.py
@@ -0,0 +1,31 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# REST-API resource implementing minimal support for "IETF YANG Data Model for Transport Network Client Signals".
+# Ref: https://www.ietf.org/archive/id/draft-ietf-ccamp-client-signal-yang-10.html
+
+from flask import jsonify, make_response, request
+from flask_restful import Resource
+
+CONNECTION_GROUPS = []
+
+
+class ConnectionGroup(Resource):
+    def get(self, slice_id: str, connection_group_id: str):
+        return make_response(jsonify(CONNECTION_GROUPS), 200)
+
+    def put(self, slice_id: str, connection_group_id: str):
+        json_request = request.get_json()
+        CONNECTION_GROUPS.append(json_request)
+        return make_response(jsonify({}), 200)
diff --git a/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/ResourceNetworkSlices.py b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/ResourceNetworkSlices.py
new file mode 100644
index 0000000000000000000000000000000000000000..80840f8da13e00af689c7b84e9577e952d9e2adf
--- /dev/null
+++ b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/ResourceNetworkSlices.py
@@ -0,0 +1,39 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# REST-API resource implementing minimal support for "IETF YANG Data Model for Transport Network Client Signals".
+# Ref: https://www.ietf.org/archive/id/draft-ietf-ccamp-client-signal-yang-10.html
+
+from flask import jsonify, make_response, request
+from flask_restful import Resource
+
+NETWORK_SLICES = {}
+
+
+class NetworkSliceServices(Resource):
+    def get(self):
+        return make_response(jsonify(NETWORK_SLICES), 200)
+
+    def post(self):
+        json_request = request.get_json()
+        name = json_request["network-slice-services"]["slice-service"][0]["id"]
+        NETWORK_SLICES[name] = json_request
+        return make_response(jsonify({}), 201)
+
+
+class NetworkSliceService(Resource):
+    def delete(self, slice_id: str):
+        slice = NETWORK_SLICES.pop(slice_id, None)
+        data, status = ({}, 404) if slice is None else (slice, 204)
+        return make_response(jsonify(data), status)
diff --git a/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/__init__.py b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ccc21c7db78aac26daa1f8c5ff8e1ffd3f35460
--- /dev/null
+++ b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/build.sh b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/build.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8e4dda34d7c83ef76c9944bcf52475de05d5238d
--- /dev/null
+++ b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/build.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Make folder containing the script the root folder for its execution
+cd $(dirname $0)
+
+docker build -t mock-ietf-network-slice-sdn-ctrl:test -f Dockerfile .
+docker tag mock-ietf-network-slice-sdn-ctrl:test localhost:32000/tfs/mock-ietf-network-slice-sdn-ctrl:test
+docker push localhost:32000/tfs/mock-ietf-network-slice-sdn-ctrl:test
diff --git a/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/deploy.sh b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/deploy.sh
new file mode 100755
index 0000000000000000000000000000000000000000..6db45be588e4d538e04ecb8922b3350432439a70
--- /dev/null
+++ b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/deploy.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+kubectl delete namespace mocks
+kubectl --namespace mocks apply -f mock-ietf-network-slice-sdn-ctrl.yaml
diff --git a/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/mock-ietf-network-slice-sdn-ctrl.yaml b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/mock-ietf-network-slice-sdn-ctrl.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..cd5734a5f3087dc36d9a103a75e90f3eb902865d
--- /dev/null
+++ b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/mock-ietf-network-slice-sdn-ctrl.yaml
@@ -0,0 +1,64 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+kind: Namespace
+apiVersion: v1
+metadata:
+  name: mocks
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: mock-ietf-network-slice-sdn-ctrl
+spec:
+  selector:
+    matchLabels:
+      app: mock-ietf-network-slice-sdn-ctrl
+  replicas: 1
+  template:
+    metadata:
+      annotations:
+        config.linkerd.io/skip-inbound-ports: "8443"
+      labels:
+        app: mock-ietf-network-slice-sdn-ctrl
+    spec:
+      terminationGracePeriodSeconds: 5
+      containers:
+      - name: server
+        image: localhost:32000/tfs/mock-ietf-network-slice-sdn-ctrl:test
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 8443
+        resources:
+          requests:
+            cpu: 250m
+            memory: 512Mi
+          limits:
+            cpu: 700m
+            memory: 1024Mi
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: mock-ietf-network-slice-sdn-ctrl
+  labels:
+    app: mock-ietf-network-slice-sdn-ctrl
+spec:
+  type: ClusterIP
+  selector:
+    app: mock-ietf-network-slice-sdn-ctrl
+  ports:
+  - name: http
+    port: 8443
+    targetPort: 8443
diff --git a/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/requirements.in b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/requirements.in
new file mode 100644
index 0000000000000000000000000000000000000000..dbb8e95d65cfd0f1ee60d9bb4f840393ac893725
--- /dev/null
+++ b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/requirements.in
@@ -0,0 +1,22 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cryptography==39.0.1
+pyopenssl==23.0.0
+Flask==2.1.3
+Flask-HTTPAuth==4.5.0
+Flask-RESTful==0.3.9
+jsonschema==4.4.0
+requests==2.27.1
+werkzeug==2.3.7
diff --git a/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/run.sh b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f52b6061b3d89b75504f2b80d77696573a09814d
--- /dev/null
+++ b/src/tests/tools/mock_ietf_network_slice_sdn_ctrl/run.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Make folder containing the script the root folder for its execution
+cd $(dirname $0)
+
+python MockIetfNetworkSliceSdnCtrl.py
diff --git a/src/tests/tools/mock_nce_ctrl/Dockerfile b/src/tests/tools/mock_nce_ctrl/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..ae9dde4eb469a951c1ccf3f78a79a9ab2d07c122
--- /dev/null
+++ b/src/tests/tools/mock_nce_ctrl/Dockerfile
@@ -0,0 +1,37 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+FROM python:3.9-slim
+
+# Set Python to show logs as they occur
+ENV PYTHONUNBUFFERED=0
+
+# Get generic Python packages
+RUN python3 -m pip install --upgrade pip
+RUN python3 -m pip install --upgrade setuptools wheel
+RUN python3 -m pip install --upgrade pip-tools
+
+# Create component sub-folders, and copy content
+RUN mkdir -p /var/teraflow/mock_nce_ctrl
+WORKDIR /var/teraflow/mock_nce_ctrl
+COPY . .
+
+# Get specific Python packages
+RUN pip-compile --quiet --output-file=requirements.txt requirements.in
+RUN python3 -m pip install -r requirements.txt
+
+RUN python3 -m pip list
+
+# Start the service
+ENTRYPOINT ["python", "MockNCECtrl.py"]
diff --git a/src/tests/tools/mock_nce_ctrl/MockNCECtrl.py b/src/tests/tools/mock_nce_ctrl/MockNCECtrl.py
new file mode 100644
index 0000000000000000000000000000000000000000..e58a4dc445e74e6186267e7b43b2872b05cb114e
--- /dev/null
+++ b/src/tests/tools/mock_nce_ctrl/MockNCECtrl.py
@@ -0,0 +1,79 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Mock IETF ACTN SDN controller
+# -----------------------------
+# REST server implementing minimal support for:
+# - IETF YANG Data Model for Transport Network Client Signals
+#       Ref: https://www.ietf.org/archive/id/draft-ietf-ccamp-client-signal-yang-10.html
+# - IETF YANG Data Model for Traffic Engineering Tunnels, Label Switched Paths and Interfaces
+#       Ref: https://www.ietf.org/archive/id/draft-ietf-teas-yang-te-34.html
+
+
+import functools, logging, sys, time
+from flask import Flask, jsonify, make_response, request
+from flask_restful import Api, Resource
+from ResourceApps import Apps, App
+from ResourceAppFlows import AppFlows, AppFlow
+
+BIND_ADDRESS = "0.0.0.0"
+BIND_PORT = 8443
+BASE_URL = "/restconf/v1/data/app-flows"
+STR_ENDPOINT = "http://{:s}:{:s}{:s}".format(
+    str(BIND_ADDRESS), str(BIND_PORT), str(BASE_URL)
+)
+LOG_LEVEL = logging.DEBUG
+
+logging.basicConfig(
+    level=LOG_LEVEL, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s"
+)
+LOGGER = logging.getLogger(__name__)
+
+logging.getLogger("werkzeug").setLevel(logging.WARNING)
+
+
+def log_request(logger: logging.Logger, response):
+    timestamp = time.strftime("[%Y-%b-%d %H:%M]")
+    logger.info(
+        "%s %s %s %s %s",
+        timestamp,
+        request.remote_addr,
+        request.method,
+        request.full_path,
+        response.status,
+    )
+    return response
+
+
+def main():
+    LOGGER.info("Starting...")
+
+    app = Flask(__name__)
+    app.after_request(functools.partial(log_request, LOGGER))
+
+    api = Api(app, prefix=BASE_URL)
+    api.add_resource(Apps, "/apps")
+    api.add_resource(App, "/apps/application=<string:app_name>")
+    api.add_resource(AppFlows, "")
+    api.add_resource(AppFlow, "/app-flow=<string:app_name>")
+
+    LOGGER.info("Listening on {:s}...".format(str(STR_ENDPOINT)))
+    app.run(debug=True, host=BIND_ADDRESS, port=BIND_PORT)
+
+    LOGGER.info("Bye")
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/src/tests/tools/mock_nce_ctrl/README.md b/src/tests/tools/mock_nce_ctrl/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..407f26425bd70b22e1426cc13dede15993925258
--- /dev/null
+++ b/src/tests/tools/mock_nce_ctrl/README.md
@@ -0,0 +1,29 @@
+# Mock NCE Controller
+
+This REST server implements very basic support for the NCE access controller.
+
+The aim of this server is to enable testing IETF Network Slice NBI, NCE driver and NCE service handler.
+
+
+## 1. Install requirements for the Mock NCE controller
+__NOTE__: if you run the Mock NCE controller from the PyEnv used for developing on the TeraFlowSDN
+framework and you followed the official steps in
+[Development Guide > Configure Environment > Python](https://labs.etsi.org/rep/tfs/controller/-/wikis/2.-Development-Guide/2.1.-Configure-Environment/2.1.1.-Python),
+all the requirements are already in place. Install them only if you execute it in a separate/standalone environment.
+
+Install the required dependencies as follows:
+```bash
+pip install -r src/tests/tools/mock_nce_ctrl/requirements.in
+```
+
+Run the Mock NCE Controller as follows:
+```bash
+python src/tests/tools/mock_nce_ctrl/MockNCECtrl.py
+```
+
+
+## 2. Run the Mock NCE controller
+Run the Mock NCE Controller as follows:
+```bash
+python src/tests/tools/mock_nce_ctrl/MockNCECtrl.py
+```
diff --git a/src/tests/tools/mock_nce_ctrl/ResourceAppFlows.py b/src/tests/tools/mock_nce_ctrl/ResourceAppFlows.py
new file mode 100644
index 0000000000000000000000000000000000000000..9f7a8df41497293af912bcf4f77aa27eabdbf095
--- /dev/null
+++ b/src/tests/tools/mock_nce_ctrl/ResourceAppFlows.py
@@ -0,0 +1,39 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# REST-API resource implementing minimal support for "IETF YANG Data Model for Transport Network Client Signals".
+# Ref: https://www.ietf.org/archive/id/draft-ietf-ccamp-client-signal-yang-10.html
+
+from flask import jsonify, make_response, request
+from flask_restful import Resource
+
+APP_FLOWS = {}
+
+
+class AppFlows(Resource):
+    def get(self):
+        return make_response(jsonify(APP_FLOWS), 200)
+
+    def post(self):
+        json_request = request.get_json()
+        name = json_request["app-flow"][0]["app-name"]
+        APP_FLOWS[name] = json_request
+        return make_response(jsonify({}), 201)
+
+
+class AppFlow(Resource):
+    def delete(self, app_name: str):
+        app_flow = APP_FLOWS.pop(app_name, None)
+        data, status = ({}, 404) if app_flow is None else (app_flow, 204)
+        return make_response(jsonify(data), status)
diff --git a/src/tests/tools/mock_nce_ctrl/ResourceApps.py b/src/tests/tools/mock_nce_ctrl/ResourceApps.py
new file mode 100644
index 0000000000000000000000000000000000000000..163d08fc2fed7fd3c21806418de06bf7ef08741a
--- /dev/null
+++ b/src/tests/tools/mock_nce_ctrl/ResourceApps.py
@@ -0,0 +1,39 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# REST-API resource implementing minimal support for "IETF YANG Data Model for Transport Network Client Signals".
+# Ref: https://www.ietf.org/archive/id/draft-ietf-ccamp-client-signal-yang-10.html
+
+from flask import jsonify, make_response, request
+from flask_restful import Resource
+
+APPS = {}
+
+
+class Apps(Resource):
+    def get(self):
+        return make_response(jsonify(APPS), 200)
+
+    def post(self):
+        json_request = request.get_json()
+        name = json_request["application"][0]["name"]
+        APPS[name] = json_request
+        return make_response(jsonify({}), 201)
+
+
+class App(Resource):
+    def delete(self, app_name: str):
+        app_flow = APPS.pop(app_name, None)
+        data, status = ({}, 404) if app_flow is None else (app_flow, 204)
+        return make_response(jsonify(data), status)
diff --git a/src/tests/tools/mock_nce_ctrl/__init__.py b/src/tests/tools/mock_nce_ctrl/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ccc21c7db78aac26daa1f8c5ff8e1ffd3f35460
--- /dev/null
+++ b/src/tests/tools/mock_nce_ctrl/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/tests/tools/mock_nce_ctrl/build.sh b/src/tests/tools/mock_nce_ctrl/build.sh
new file mode 100755
index 0000000000000000000000000000000000000000..766d2c1dc5d3a890c5a74d88c22055792b089de4
--- /dev/null
+++ b/src/tests/tools/mock_nce_ctrl/build.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Make folder containing the script the root folder for its execution
+cd $(dirname $0)
+
+docker build -t mock-nce-ctrl:test -f Dockerfile .
+docker tag mock-nce-ctrl:test localhost:32000/tfs/mock-nce-ctrl:test
+docker push localhost:32000/tfs/mock-nce-ctrl:test
diff --git a/src/tests/tools/mock_nce_ctrl/deploy.sh b/src/tests/tools/mock_nce_ctrl/deploy.sh
new file mode 100755
index 0000000000000000000000000000000000000000..0e5faf26d435ee928f550106e36f85e65109ac66
--- /dev/null
+++ b/src/tests/tools/mock_nce_ctrl/deploy.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+kubectl delete namespace mocks
+kubectl --namespace mocks apply -f mock-nce-ctrl.yaml
diff --git a/src/tests/tools/mock_nce_ctrl/mock-nce-ctrl.yaml b/src/tests/tools/mock_nce_ctrl/mock-nce-ctrl.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4a1512f238970afb0867a3cb79824df4ac60d5c9
--- /dev/null
+++ b/src/tests/tools/mock_nce_ctrl/mock-nce-ctrl.yaml
@@ -0,0 +1,64 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+kind: Namespace
+apiVersion: v1
+metadata:
+  name: mocks
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: mock-nce-ctrl
+spec:
+  selector:
+    matchLabels:
+      app: mock-nce-ctrl
+  replicas: 1
+  template:
+    metadata:
+      annotations:
+        config.linkerd.io/skip-inbound-ports: "8443"
+      labels:
+        app: mock-nce-ctrl
+    spec:
+      terminationGracePeriodSeconds: 5
+      containers:
+      - name: server
+        image: localhost:32000/tfs/mock-nce-ctrl:test
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 8443
+        resources:
+          requests:
+            cpu: 250m
+            memory: 512Mi
+          limits:
+            cpu: 700m
+            memory: 1024Mi
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: mock-nce-ctrl
+  labels:
+    app: mock-nce-ctrl
+spec:
+  type: ClusterIP
+  selector:
+    app: mock-nce-ctrl
+  ports:
+  - name: https
+    port: 8443
+    targetPort: 8443
diff --git a/src/tests/tools/mock_nce_ctrl/requirements.in b/src/tests/tools/mock_nce_ctrl/requirements.in
new file mode 100644
index 0000000000000000000000000000000000000000..dbb8e95d65cfd0f1ee60d9bb4f840393ac893725
--- /dev/null
+++ b/src/tests/tools/mock_nce_ctrl/requirements.in
@@ -0,0 +1,22 @@
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cryptography==39.0.1
+pyopenssl==23.0.0
+Flask==2.1.3
+Flask-HTTPAuth==4.5.0
+Flask-RESTful==0.3.9
+jsonschema==4.4.0
+requests==2.27.1
+werkzeug==2.3.7
diff --git a/src/tests/tools/mock_nce_ctrl/run.sh b/src/tests/tools/mock_nce_ctrl/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..6aa1149a4a9571bc1e52ab66ca0a36391edc6f54
--- /dev/null
+++ b/src/tests/tools/mock_nce_ctrl/run.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Make folder containing the script the root folder for its execution
+cd $(dirname $0)
+
+python MockNCECtrl.py
diff --git a/src/webui/service/slice/routes.py b/src/webui/service/slice/routes.py
index 922f8af96dc916f0ca5658e120cdf3dfa4ec9b21..f56c50f46d8c9df083a943a91704e7d16352e5a2 100644
--- a/src/webui/service/slice/routes.py
+++ b/src/webui/service/slice/routes.py
@@ -12,12 +12,16 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import json
+from typing import Dict, Optional, Tuple
 import grpc
 from flask import current_app, redirect, render_template, Blueprint, flash, session, url_for
-from common.proto.context_pb2 import IsolationLevelEnum, Slice, SliceId, SliceStatusEnum
+from common.method_wrappers.ServiceExceptions import InvalidArgumentsException
+from common.proto.context_pb2 import IsolationLevelEnum, Slice, SliceId, SliceStatusEnum, EndPointId, SliceConfig, ConfigRule
 from common.tools.context_queries.Context import get_context
 from common.tools.context_queries.EndPoint import get_endpoint_names
-from common.tools.context_queries.Slice import get_slice_by_uuid
+from common.tools.context_queries.Slice import get_slice_by_uuid, get_uuid_from_string
+from common.Constants import DEFAULT_CONTEXT_NAME
 from context.client.ContextClient import ContextClient
 from slice.client.SliceClient import SliceClient
 
@@ -26,6 +30,94 @@ slice = Blueprint('slice', __name__, url_prefix='/slice')
 context_client = ContextClient()
 slice_client = SliceClient()
 
+
+RUNNING_RESOURCE_KEY = "running_ietf_slice"
+CANDIDATE_RESOURCE_KEY = "candidate_ietf_slice"
+
+
+class ConfigRuleNotFoundError(Exception):
+    ...
+
+def get_custom_config_rule(
+    slice_config: SliceConfig, resource_key: str
+) -> Optional[ConfigRule]:
+    """
+    Retrieve the custom config rule with the given resource_key from a ServiceConfig.
+    """
+    for cr in slice_config.config_rules:
+        if (
+            cr.WhichOneof("config_rule") == "custom"
+            and cr.custom.resource_key == resource_key
+        ):
+            return cr
+    return None
+
+
+def get_ietf_data_from_config(slice_request: Slice, resource_key: str) -> Dict:
+    """
+    Retrieve the IETF data (as a Python dict) from a slice's config rule for the specified resource_key.
+    Raises an exception if not found.
+    """
+    config_rule = get_custom_config_rule(slice_request.slice_config, resource_key)
+    if not config_rule:
+        raise ConfigRuleNotFoundError(f"IETF data not found for resource_key: {resource_key}")
+    return json.loads(config_rule.custom.resource_value)
+
+
+def endpoint_get_uuid(
+    endpoint_id : EndPointId, endpoint_name : str = '', allow_random : bool = False
+) -> Tuple[str, str, str]:
+    device_uuid = endpoint_id.device_id.device_uuid.uuid
+    topology_uuid = endpoint_id.topology_id.topology_uuid.uuid
+    raw_endpoint_uuid = endpoint_id.endpoint_uuid.uuid
+
+    if len(raw_endpoint_uuid) > 0:
+        prefix_for_name = '{:s}/{:s}'.format(topology_uuid, device_uuid)
+        return topology_uuid, device_uuid, get_uuid_from_string(raw_endpoint_uuid, prefix_for_name=prefix_for_name)
+    if len(endpoint_name) > 0:
+        prefix_for_name = '{:s}/{:s}'.format(topology_uuid, device_uuid)
+        return topology_uuid, device_uuid, get_uuid_from_string(endpoint_name, prefix_for_name=prefix_for_name)
+
+    raise InvalidArgumentsException([
+        ('endpoint_id.endpoint_uuid.uuid', raw_endpoint_uuid),
+        ('name', endpoint_name),
+    ], extra_details=['At least one is required to produce a EndPoint UUID'])
+
+def get_slice_endpoints(slice_obj: Slice) -> list[EndPointId]:
+    '''
+    Get the list of endpoint ids for a slice.
+    If the slice has a `running_ietf_slice` config rule, return the list of endpoint ids from the config rule,
+    otherwise return the slice's list of endpoint ids.
+    '''
+    try:
+        first_slice_endpoint_id = slice_obj.slice_endpoint_ids[0]
+        topology_uuid = first_slice_endpoint_id.topology_id.topology_uuid.uuid
+        context_uuid = slice_obj.slice_id.context_id.context_uuid.uuid
+        running_ietf_data = get_ietf_data_from_config(slice_obj, RUNNING_RESOURCE_KEY)
+        slice_service = running_ietf_data["network-slice-services"]["slice-service"][0]
+        slice_sdps = slice_service["sdps"]["sdp"]
+        list_endpoint_ids = []
+        for sdp in slice_sdps:
+            endpoint = EndPointId()
+            endpoint.topology_id.context_id.context_uuid.uuid = context_uuid
+            endpoint.topology_id.topology_uuid.uuid = topology_uuid
+            device_uuid = get_uuid_from_string(sdp["node-id"])
+            endpoint.device_id.device_uuid.uuid = device_uuid
+            attachment_circuits = sdp["attachment-circuits"]["attachment-circuit"]
+            endpoint_name = attachment_circuits[0]["ac-tp-id"]
+            endpoint.endpoint_uuid.uuid = endpoint_name
+            _, _, endpoint_uuid = endpoint_get_uuid(endpoint)
+            endpoint.endpoint_uuid.uuid = endpoint_uuid
+            list_endpoint_ids.append(endpoint)
+        del slice_obj.slice_endpoint_ids[:]
+        slice_obj.slice_endpoint_ids.extend(list_endpoint_ids)
+
+    except ConfigRuleNotFoundError:
+        # The slice does not have `running_ietf_slice` config rule, return slice's list of endpoint ids
+        list_endpoint_ids = slice_obj.slice_endpoint_ids
+
+    return list_endpoint_ids
+
 @slice.get('/')
 def home():
     if 'context_uuid' not in session or 'topology_uuid' not in session:
@@ -50,7 +142,8 @@ def home():
         else:
             endpoint_ids = list()
             for slice_ in slices:
-                endpoint_ids.extend(slice_.slice_endpoint_ids)
+                slice_endpoint_ids = get_slice_endpoints(slice_)
+                endpoint_ids.extend(slice_endpoint_ids)
             device_names, endpoints_data = get_endpoint_names(context_client, endpoint_ids)
 
     context_client.close()
@@ -81,7 +174,8 @@ def detail(slice_uuid: str):
             flash('Context({:s})/Slice({:s}) not found'.format(str(context_uuid), str(slice_uuid)), 'danger')
             slice_obj = Slice()
         else:
-            device_names, endpoints_data = get_endpoint_names(context_client, slice_obj.slice_endpoint_ids)
+            slice_endpoint_ids = get_slice_endpoints(slice_obj)
+            device_names, endpoints_data = get_endpoint_names(context_client, slice_endpoint_ids)
 
         context_client.close()
 
@@ -111,5 +205,5 @@ def delete(slice_uuid: str):
         flash('Slice "{:s}" deleted successfully!'.format(slice_uuid), 'success')
     except Exception as e:
         flash('Problem deleting slice "{:s}": {:s}'.format(slice_uuid, str(e.details())), 'danger')
-        current_app.logger.exception(e) 
+        current_app.logger.exception(e)
     return redirect(url_for('slice.home'))
diff --git a/src/webui/service/static/topology_icons/ietf-slice.png b/src/webui/service/static/topology_icons/ietf-slice.png
new file mode 100644
index 0000000000000000000000000000000000000000..ed2232e8223a39eb0d829e0e50975a697b0660fc
Binary files /dev/null and b/src/webui/service/static/topology_icons/ietf-slice.png differ
diff --git a/src/webui/service/static/topology_icons/nce.png b/src/webui/service/static/topology_icons/nce.png
new file mode 100644
index 0000000000000000000000000000000000000000..0c9af8f37fbb7249fbe570a920e0bcd281582655
Binary files /dev/null and b/src/webui/service/static/topology_icons/nce.png differ