diff --git a/src/context/service/database/models/enums/DeviceDriver.py b/src/context/service/database/models/enums/DeviceDriver.py
index fe0d83fb1886a42526b1c71304b7e3ecc2b0b7d7..8db363ce2b3e5d7dc431429188f8af931e76163f 100644
--- a/src/context/service/database/models/enums/DeviceDriver.py
+++ b/src/context/service/database/models/enums/DeviceDriver.py
@@ -38,6 +38,7 @@ class ORM_DeviceDriverEnum(enum.Enum):
     IETF_SLICE            = DeviceDriverEnum.DEVICEDRIVER_IETF_SLICE
     OC                    = DeviceDriverEnum.DEVICEDRIVER_OC
     QKD                   = DeviceDriverEnum.DEVICEDRIVER_QKD
+    IETF_L3VPN            = DeviceDriverEnum.DEVICEDRIVER_IETF_L3VPN
 
 grpc_to_enum__device_driver = functools.partial(
     grpc_to_enum, DeviceDriverEnum, ORM_DeviceDriverEnum)
diff --git a/src/device/service/drivers/__init__.py b/src/device/service/drivers/__init__.py
index bfadaafdd7961cc6ce09ee8491503b15e42a7ab8..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, [
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..f635f1a75aba78fb3d54b9fb46275e6f2f2e2c29
--- /dev/null
+++ b/src/device/service/drivers/ietf_l3vpn/TfsApiClient.py
@@ -0,0 +1,172 @@
+# 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)
+        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)
+        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..eeb0d87f1600979ebc30fd7400f23e3595afb7a4
--- /dev/null
+++ b/src/device/service/drivers/ietf_l3vpn/Tools.py
@@ -0,0 +1,414 @@
+# 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 create_l3vpn_datamodel(service_uuid, resource_value: dict) -> dict:
+    src_device_uuid: str = resource_value["src_device_name"]
+    src_endpoint_uuid: str = resource_value["src_endpoint_name"]
+    src_site_location: str = resource_value["src_site_location"]
+    src_ipv4_lan_prefixes: list[LANPrefixesDict] = resource_value.get(
+        "src_ipv4_lan_prefixes"
+    )
+    src_site_id: str = resource_value.get("src_site_id", f"site_{src_site_location}")
+    src_management_type: str = resource_value.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 = resource_value["src_ce_address"]
+    src_pe_address: str = resource_value["src_pe_address"]
+    src_ce_pe_network_prefix: int = resource_value["src_ce_pe_network_prefix"]
+    src_mtu: int = resource_value["src_mtu"]
+    src_input_bw: int = resource_value.get("src_input_bw", 1000000000)
+    src_output_bw: int = resource_value.get("src_input_bw", 1000000000)
+    src_qos_profile_id = "qos-realtime"
+    src_qos_profile_direction = "ietf-l3vpn-svc:both"
+    src_qos_profile_latency: int = resource_value.get("src_qos_profile_latency", 10)
+    src_qos_profile_bw_guarantee: int = resource_value.get(
+        "src_qos_profile_bw_guarantee", 100
+    )
+
+    dst_device_uuid = resource_value["dst_device_name"]
+    dst_endpoint_uuid = resource_value["dst_endpoint_name"]
+    dst_site_location: str = resource_value["dst_site_location"]
+    dst_ipv4_lan_prefixes: list[LANPrefixesDict] = resource_value[
+        "dst_ipv4_lan_prefixes"
+    ]
+    dst_site_id: str = resource_value.get("dst_site_id", f"site_{dst_site_location}")
+    dst_management_type: str = resource_value.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 = resource_value["dst_ce_address"]
+    dst_pe_address: str = resource_value["dst_pe_address"]
+    dst_ce_pe_network_prefix: int = resource_value["dst_ce_pe_network_prefix"]
+    dst_mtu: int = resource_value["dst_mtu"]
+    dst_input_bw: int = resource_value.get("dst_input_bw", 1000000000)
+    dst_output_bw: int = resource_value.get("dst_output_bw", 1000000000)
+    dst_qos_profile_id = "qos-realtime"
+    dst_qos_profile_direction = "ietf-l3vpn-svc:both"
+    dst_qos_profile_latency: int = resource_value.get("dst_qos_profile_latency", 10)
+    dst_qos_profile_bw_guarantee: int = resource_value.get(
+        "dst_qos_profile_bw_guarantee", 100
+    )
+
+    # Create source site information
+    src_management = {"type": src_management_type}
+    src_locations = {"location": [{"location-id": src_site_location}]}
+    src_devices = {
+        "device": [{"device-id": src_device_uuid, "location": src_site_location}]
+    }
+    src_site_lan_prefixes = [
+        {"lan": lp["lan"], "lan-tag": lp["lan_tag"], "next-hop": src_pe_address}
+        for lp in src_ipv4_lan_prefixes
+    ]
+    src_site_routing_protocols = {
+        "routing-protocol": [
+            {
+                "type": "ietf-l3vpn-svc:static",
+                "static": {
+                    "cascaded-lan-prefixes": {
+                        "ipv4-lan-prefixes": src_site_lan_prefixes
+                    }
+                },
+            }
+        ]
+    }
+    src_site_network_accesses = {
+        "site-network-access": [
+            {
+                "site-network-access-id": src_endpoint_uuid,
+                "site-network-access-type": SITE_NETWORK_ACCESS_TYPE,
+                "device-reference": src_device_uuid,
+                "vpn-attachment": {"vpn-id": service_uuid, "site-role": src_role},
+                "ip-connection": {
+                    "ipv4": {
+                        "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                        "addresses": {
+                            "provider-address": src_pe_address,
+                            "customer-address": src_ce_address,
+                            "prefix-length": src_ce_pe_network_prefix,
+                        },
+                    }
+                },
+                "service": {
+                    "svc-mtu": src_mtu,
+                    "svc-input-bandwidth": src_input_bw,
+                    "svc-output-bandwidth": src_output_bw,
+                    "qos": {
+                        "qos-profile": {
+                            "classes": {
+                                "class": [
+                                    {
+                                        "class-id": src_qos_profile_id,
+                                        "direction": src_qos_profile_direction,
+                                        "latency": {
+                                            "latency-boundary": src_qos_profile_latency
+                                        },
+                                        "bandwidth": {
+                                            "guaranteed-bw-percent": src_qos_profile_bw_guarantee
+                                        },
+                                    }
+                                ]
+                            }
+                        }
+                    },
+                },
+            }
+        ]
+    }
+
+    # Create destination site information
+    dst_management = {"type": src_management_type}
+    dst_locations = {"location": [{"location-id": dst_site_location}]}
+    dst_devices = {
+        "device": [{"device-id": dst_device_uuid, "location": dst_site_location}]
+    }
+    dst_site_lan_prefixes = [
+        {"lan": lp["lan"], "lan-tag": lp["lan_tag"], "next-hop": dst_pe_address}
+        for lp in dst_ipv4_lan_prefixes
+    ]
+    dst_site_routing_protocols = {
+        "routing-protocol": [
+            {
+                "type": "ietf-l3vpn-svc:static",
+                "static": {
+                    "cascaded-lan-prefixes": {
+                        "ipv4-lan-prefixes": dst_site_lan_prefixes
+                    }
+                },
+            }
+        ]
+    }
+    dst_site_network_accesses = {
+        "site-network-access": [
+            {
+                "site-network-access-id": dst_endpoint_uuid,
+                "site-network-access-type": SITE_NETWORK_ACCESS_TYPE,
+                "device-reference": dst_device_uuid,
+                "vpn-attachment": {"vpn-id": service_uuid, "site-role": dst_role},
+                "ip-connection": {
+                    "ipv4": {
+                        "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                        "addresses": {
+                            "provider-address": dst_pe_address,
+                            "customer-address": dst_ce_address,
+                            "prefix-length": dst_ce_pe_network_prefix,
+                        },
+                    }
+                },
+                "service": {
+                    "svc-mtu": dst_mtu,
+                    "svc-input-bandwidth": dst_input_bw,
+                    "svc-output-bandwidth": dst_output_bw,
+                    "qos": {
+                        "qos-profile": {
+                            "classes": {
+                                "class": [
+                                    {
+                                        "class-id": dst_qos_profile_id,
+                                        "direction": dst_qos_profile_direction,
+                                        "latency": {
+                                            "latency-boundary": dst_qos_profile_latency
+                                        },
+                                        "bandwidth": {
+                                            "guaranteed-bw-percent": dst_qos_profile_bw_guarantee
+                                        },
+                                    }
+                                ]
+                            }
+                        }
+                    },
+                },
+            }
+        ]
+    }
+
+    sites = {
+        "site": [
+            {
+                "site-id": src_site_id,
+                "management": src_management,
+                "locations": src_locations,
+                "devices": src_devices,
+                "routing-protocols": src_site_routing_protocols,
+                "site-network-accesses": src_site_network_accesses,
+            },
+            {
+                "site-id": dst_site_id,
+                "management": dst_management,
+                "locations": dst_locations,
+                "devices": dst_devices,
+                "routing-protocols": dst_site_routing_protocols,
+                "site-network-accesses": dst_site_network_accesses,
+            },
+        ]
+    }
+
+    l3_vpn_data_model = {
+        "ietf-l3vpn-svc:l3vpn-svc": {
+            "vpn-services": {"vpn-service": [{"vpn-id": service_uuid}]},
+            "sites": sites,
+        }
+    }
+
+    return l3_vpn_data_model
+
+
+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..25d8f9319d5cc14b14f843c7d06a75cc59212560
--- /dev/null
+++ b/src/device/service/drivers/ietf_l3vpn/driver.py
@@ -0,0 +1,292 @@
+# 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,
+    create_l3vpn_datamodel,
+    service_exists,
+)
+
+LOGGER = logging.getLogger(__name__)
+
+
+ALL_RESOURCE_KEYS = [
+    RESOURCE_ENDPOINTS,
+    RESOURCE_SERVICES,
+]
+
+RE_GET_ENDPOINT_FROM_INTERFACE = re.compile(r"^\/interface\[([^\]]+)\].*")
+
+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:
+                LOGGER.info("resource = {:s}".format(str(resource)))
+                resource_key, resource_value = resource
+                try:
+                    resource_value = json.loads(resource_value)
+
+                    service_uuid = resource_value["uuid"]
+
+                    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
+
+                    l3vpn_datamodel = create_l3vpn_datamodel(
+                        service_uuid, resource_value
+                    )
+                    self.tac.create_connectivity_service(l3vpn_datamodel)
+                    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:
+                    resource_value = json.loads(resource_value)
+                    service_uuid = resource_value["uuid"]
+
+                    if service_exists(self.__tfs_nbi_root, self.__auth, service_uuid):
+                        self.tac.delete_connectivity_service(service_uuid)
+                    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/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/rest_server/nbi_plugins/ietf_l3vpn/Handlers.py b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/Handlers.py
index 0e8b8013ef5cba1305cdd040ea68efc653eefa5e..b76bf0cec3a99907a182fbde4777939dfa3d4a67 100644
--- a/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/Handlers.py
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/Handlers.py
@@ -15,7 +15,7 @@
 import logging, netaddr
 from typing import Dict, List, Optional, Tuple
 from common.Constants import DEFAULT_CONTEXT_NAME
-from common.proto.context_pb2 import Service, ServiceStatusEnum, ServiceTypeEnum
+from common.proto.context_pb2 import Service, ServiceStatusEnum, ServiceTypeEnum, Empty
 from common.tools.context_queries.Service import get_service_by_uuid
 from common.tools.grpc.ConfigRules import update_config_rule_custom
 from common.tools.grpc.Constraints import (
@@ -97,8 +97,11 @@ def update_service_endpoint(
     endpoint_settings_key = ENDPOINT_SETTINGS_KEY.format(device_uuid, endpoint_uuid)
     field_updates = {}
     if vlan_tag              is not None: field_updates['vlan_tag'        ] = (vlan_tag,              True)
-    if ipv4_address          is not None: field_updates['ip_address'      ] = (ipv4_address,          True)
-    if neighbor_ipv4_address is not None: field_updates['neighbor_address'] = (neighbor_ipv4_address, True)
+    # if ipv4_address          is not None: field_updates['ip_address'      ] = (ipv4_address,          True)
+    # if neighbor_ipv4_address is not None: field_updates['neighbor_address'] = (neighbor_ipv4_address, True)
+    #! neighbor_ipv4_address and ipv4_address' field swapped to manage the PE. Fix it later
+    if ipv4_address          is not None: field_updates['ip_address'      ] = (neighbor_ipv4_address,          True)
+    if neighbor_ipv4_address is not None: field_updates['neighbor_address'] = (ipv4_address, True)
     if ipv4_prefix_length    is not None: field_updates['prefix_length'   ] = (ipv4_prefix_length,    True)
     update_config_rule_custom(config_rules, endpoint_settings_key, field_updates)
 
@@ -113,6 +116,8 @@ def update_service_endpoint(
 def process_site_network_access(
     site_id : str, network_access : Dict, site_static_routing : Dict[Tuple[str, str], str], errors : List[Dict]
 ) -> None:
+    # client = ContextClient()
+    # devices = client.ListDevices(Empty()).devices
     endpoint_uuid = network_access['site-network-access-id']
 
     if network_access['site-network-access-type'] != 'ietf-l3vpn-svc:multipoint':
@@ -120,6 +125,12 @@ def process_site_network_access(
         raise NotImplementedError(MSG.format(str(network_access['site-network-access-type'])))
 
     device_uuid  = network_access['device-reference']
+
+    # location = network_access['location-reference']
+    # for device in devices:
+    #     for cr in device.device_config.config_rules:
+    #         if cr.WhichOneof('config_rule') != 'custom':
+    #             continue
     service_uuid = network_access['vpn-attachment']['vpn-id']
     
     access_role : str = network_access['vpn-attachment']['site-role']
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/tests/data/agg-net-descriptor.json b/src/nbi/tests/data/agg-net-descriptor.json
new file mode 100644
index 0000000000000000000000000000000000000000..bde4db62844084c0674312a60d7c1cbf8357de52
--- /dev/null
+++ b/src/nbi/tests/data/agg-net-descriptor.json
@@ -0,0 +1,628 @@
+{
+    "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.10.10.10"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "80"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": {
+                                "endpoints": [],
+                                "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": [
+                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",
+                                        "ce-ip": "128.32.33.2",
+                                        "address_ip": "128.32.33.254",
+                                        "address_prefix": "24",
+                                        "site_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": "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": [
+                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",
+            "controller_id": {
+                "device_uuid": {
+                    "uuid": "ip-net-controller"
+                }
+            },
+            "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",
+            "controller_id": {
+                "device_uuid": {
+                    "uuid": "ip-net-controller"
+                }
+            },
+            "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",
+                                        "ce-ip": "172.10.33.2",
+                                        "address_ip": "172.10.33.254",
+                                        "address_prefix": "24",
+                                        "site_location": "cloud",
+                                        "mtu": "1500",
+                                        "ipv4_lan_prefixes": [
+                                            {
+                                                "lan": "172.1.101.0/24",
+                                                "lan_tag": "101"
+                                            }
+                                        ]
+                                    },
+                                    {
+                                        "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/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/service/service/service_handler_api/FilterFields.py b/src/service/service/service_handler_api/FilterFields.py
index 585bad6b04ceb182587532d517459d508af416d9..e47fd635f0c02667a052ebb9cff0569496c5fbec 100644
--- a/src/service/service/service_handler_api/FilterFields.py
+++ b/src/service/service/service_handler_api/FilterFields.py
@@ -47,6 +47,7 @@ DEVICE_DRIVER_VALUES = {
     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 3d1ae9041443977985a13ca272bbe7a1b1cc0769..85545d238f2b93bd77b1beb1fce2d46b01b06800 100644
--- a/src/service/service/service_handlers/__init__.py
+++ b/src/service/service/service_handlers/__init__.py
@@ -16,6 +16,7 @@ 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
@@ -68,6 +69,12 @@ 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,
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..4b4e9add563de81c6228b74a9494cb86326c9276
--- /dev/null
+++ b/src/service/service/service_handlers/l3nm_ietfl3vpn/L3NM_IETFL3VPN_ServiceHandler.py
@@ -0,0 +1,415 @@
+# 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
+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.ConfigRule import json_config_rule_delete
+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
+
+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_ip: str
+    dst_ip: str
+    src_port: str
+    dst_port: str
+    vlan: str
+
+
+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
+
+
+def get_running_candidate_ietf_slice_data_diff(service_config: ServiceConfig) -> dict:
+    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
+    )
+    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
+    )
+    return DeepDiff(
+        running_resource_value_dict,
+        candidate_resource_value_dict,
+    )
+
+
+def extract_match_criterion_ipv4_info(
+    match_criterion: dict,
+) -> Ipv4Info:
+    for type_value in match_criterion["match-type"]:
+        if type_value["type"] == "ietf-network-slice-service:source-ip-prefix":
+            src_ip = type_value["value"][0].split("/")[0]
+        elif type_value["type"] == "ietf-network-slice-service:destination-ip-prefix":
+            dst_ip = type_value["value"][0].split("/")[0]
+        elif type_value["type"] == "ietf-network-slice-service:source-tcp-port":
+            src_port = type_value["value"][0]
+        elif type_value["type"] == "ietf-network-slice-service:destination-tcp-port":
+            dst_port = type_value["value"][0]
+        elif type_value["type"] == "ietf-network-slice-service:vlan":
+            vlan = type_value["value"][0]
+        return Ipv4Info(
+            src_ip=src_ip,
+            dst_ip=dst_ip,
+            src_port=src_port,
+            dst_port=dst_port,
+            vlan=vlan,
+        )
+
+
+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]:
+        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:
+                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")
+        for ep in endpoints[::-1]:
+            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:
+                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,
+        )
+
+    @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_uuid = self.__service.service_id.service_uuid.uuid
+        service_config = self.__service.service_config
+        try:
+            (
+                src_device_uuid,
+                src_endpoint_uuid,
+                dst_device_uuid,
+                dst_endpoint_uuid,
+                controller,
+            ) = self.__find_IP_transport_edge_endpoints(endpoints)
+            service_uuid = self.__service.service_id.service_uuid.uuid
+            service_config = self.__service.service_config
+            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)
+            src_device_name = src_device_obj.name
+            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)
+            dst_device_name = dst_device_obj.name
+            for cr in src_device_obj.device_config.config_rules:
+                if (
+                    cr.WhichOneof("config_rule") == "custom"
+                    and cr.custom.resource_key
+                    == f"/endpoints/endpoint[{src_endpoint_obj.name}]"
+                ):
+                    src_endpoint_settings = json.loads(cr.custom.resource_value)
+                    break
+            else:
+                raise Exception("Endpoint settings not found")
+            for cr in dst_device_obj.device_config.config_rules:
+                if (
+                    cr.WhichOneof("config_rule") == "custom"
+                    and cr.custom.resource_key
+                    == f"/endpoints/endpoint[{dst_endpoint_obj.name}]"
+                ):
+                    dst_endpoint_settings = json.loads(cr.custom.resource_value)
+                    break
+            else:
+                raise Exception("Endpoint settings not found")
+            ietf_slice_running_cr = get_custom_config_rule(
+                service_config, RUNNING_RESOURCE_KEY
+            )
+            ietf_slice_candidate_cr = get_custom_config_rule(
+                service_config, CANDIDATE_RESOURCE_KEY
+            )
+            if (
+                ietf_slice_running_cr and ietf_slice_candidate_cr
+            ):  # The request comes from the IETF Slice NBI
+                running_resource_value_dict = json.loads(
+                    ietf_slice_running_cr.custom.resource_value
+                )
+                candidate_resource_value_dict = json.loads(
+                    ietf_slice_candidate_cr.custom.resource_value
+                )
+                running_candidate_diff = get_running_candidate_ietf_slice_data_diff(
+                    service_config
+                )
+                slice_services = candidate_resource_value_dict[
+                    "network-slice-services"
+                ]["slice-service"]
+                slice_service = slice_services[0]
+                sdps = slice_service["sdps"]["sdp"]
+                connection_groups = slice_service["connection-groups"][
+                    "connection-group"
+                ]
+                connection_group = connection_groups[0]
+                connecitivity_constructs = connection_group["connectivity-construct"]
+                connecitivity_construct = connecitivity_constructs[0]
+                src_sdp_idx = connecitivity_construct["p2p-sender-sdp"]
+                dst_sdp_idx = connecitivity_construct["p2p-receiver-sdp"]
+                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
+                )
+                src_ipv4_lan_prefixes = [
+                    LANPrefixesDict(
+                        lan=src_match_criterion_ipv4_info["dst_ip"],
+                        lan_tag=src_match_criterion_ipv4_info["vlan"],
+                    )
+                ]
+                dst_ipv4_lan_prefixes = [
+                    LANPrefixesDict(
+                        lan=dst_match_criterion_ipv4_info["dst_ip"],
+                        lan_tag=dst_match_criterion_ipv4_info["vlan"],
+                    )
+                ]
+                src_ce_address = src_endpoint_settings["address_ip"]
+                src_pe_address = src_ce_address
+                src_ce_address_prefix = src_endpoint_settings["address_prefix"]
+                dst_ce_address = dst_endpoint_settings["address_ip"]
+                dst_pe_address = dst_ce_address
+                dst_ce_address_prefix = dst_endpoint_settings["address_prefix"]
+            resource_value_dict = {
+                "uuid": service_uuid,
+                "src_device_name": src_device_name,
+                "src_endpoint_name": src_endpoint_obj.name,
+                "src_site_location": src_endpoint_settings["site_location"],
+                "src_ipv4_lan_prefixes": src_ipv4_lan_prefixes,
+                "src_ce_address": src_ce_address,
+                "src_pe_address": src_pe_address,
+                "src_ce_pe_network_prefix": src_ce_address_prefix,
+                "src_mtu": MTU,
+                "dst_device_name": dst_device_name,
+                "dst_endpoint_name": dst_endpoint_obj.name,
+                "dst_site_location": dst_endpoint_settings["site_location"],
+                "dst_ipv4_lan_prefixes": dst_ipv4_lan_prefixes,
+                "dst_ce_address": dst_ce_address,
+                "dst_pe_address": dst_pe_address,
+                "dst_ce_pe_network_prefix": dst_ce_address_prefix,
+                "dst_mtu": MTU,
+            }
+            json_config_rules = setup_config_rules(service_uuid, 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
+            LOGGER.exception(
+                "Unable to SetEndpoint for Service({:s})".format(str(service_uuid))
+            )
+            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_uuid = self.__service.service_id.service_uuid.uuid
+
+        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_rule = json_config_rule_delete(
+                "/services/service[{:s}]".format(service_uuid), {"uuid": service_uuid}
+            )
+            del controller.device_config.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
+            LOGGER.exception(
+                "Unable to DeleteEndpoint for Service({:s})".format(str(service_uuid))
+            )
+            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..3ee6f7071f145e06c3aeaefc09a43ccd88e619e3
--- /dev/null
+++ b/src/service/service/service_handlers/l3nm_ietfl3vpn/__init__.py
@@ -0,0 +1,14 @@
+# 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.
+