From 210ed9344c3f36ea667182a531488edfe62d00dc Mon Sep 17 00:00:00 2001
From: "Georgios P. Katsikas" <gkatsikas@ubitech.eu>
Date: Wed, 19 Mar 2025 19:34:34 +0000
Subject: [PATCH 01/14] fix: basic P4 refactoring

---
 proto/context.proto                           |  24 +-
 src/common/type_checkers/Checkers.py          |  79 +++++
 .../service/database/models/enums/LinkType.py |  13 +-
 .../database/models/enums/ServiceType.py      |   3 +
 src/device/service/drivers/p4/p4_common.py    |  84 +----
 src/device/service/drivers/p4/p4_driver.py    |  32 +-
 src/device/tests/test_internal_p4.py          |  28 +-
 .../service_handler_api/FilterFields.py       |   3 +
 .../service/service_handlers/__init__.py      |   6 +-
 .../{p4 => p4_l1}/__init__.py                 |   0
 .../p4_l1_service_handler.py}                 |  48 +--
 ...ert-acl.json => sbi-rules-insert-acl.json} |   0
 ...t-b1.json => sbi-rules-insert-int-b1.json} |   0
 ...t-b2.json => sbi-rules-insert-int-b2.json} |   0
 ...t-b3.json => sbi-rules-insert-int-b3.json} |   0
 ...son => sbi-rules-insert-routing-corp.json} |   0
 ...son => sbi-rules-insert-routing-edge.json} |   0
 ...ules-remove.json => sbi-rules-remove.json} |   0
 .../descriptors/topology.json                 | 310 ++++--------------
 ....sh => run_test_02_sbi_rules_provision.sh} |   2 +-
 ...h => run_test_03_sbi_rules_deprovision.sh} |   2 +-
 ...t_04_cleanup.sh => run_test_06_cleanup.sh} |   0
 src/tests/p4-int-routing-acl/test_common.py   |  27 +-
 .../test_functional_cleanup.py                |   1 -
 ... test_functional_sbi_rules_deprovision.py} |   0
 ...=> test_functional_sbi_rules_provision.py} |   0
 .../static/topology_icons/p4-switch.png       | Bin 6288 -> 244738 bytes
 27 files changed, 261 insertions(+), 401 deletions(-)
 rename src/service/service/service_handlers/{p4 => p4_l1}/__init__.py (100%)
 rename src/service/service/service_handlers/{p4/p4_service_handler.py => p4_l1/p4_l1_service_handler.py} (95%)
 rename src/tests/p4-int-routing-acl/descriptors/{rules-insert-acl.json => sbi-rules-insert-acl.json} (100%)
 rename src/tests/p4-int-routing-acl/descriptors/{rules-insert-int-b1.json => sbi-rules-insert-int-b1.json} (100%)
 rename src/tests/p4-int-routing-acl/descriptors/{rules-insert-int-b2.json => sbi-rules-insert-int-b2.json} (100%)
 rename src/tests/p4-int-routing-acl/descriptors/{rules-insert-int-b3.json => sbi-rules-insert-int-b3.json} (100%)
 rename src/tests/p4-int-routing-acl/descriptors/{rules-insert-routing-corp.json => sbi-rules-insert-routing-corp.json} (100%)
 rename src/tests/p4-int-routing-acl/descriptors/{rules-insert-routing-edge.json => sbi-rules-insert-routing-edge.json} (100%)
 rename src/tests/p4-int-routing-acl/descriptors/{rules-remove.json => sbi-rules-remove.json} (100%)
 rename src/tests/p4-int-routing-acl/{run_test_02_rules_provision.sh => run_test_02_sbi_rules_provision.sh} (95%)
 rename src/tests/p4-int-routing-acl/{run_test_03_rules_deprovision.sh => run_test_03_sbi_rules_deprovision.sh} (95%)
 rename src/tests/p4-int-routing-acl/{run_test_04_cleanup.sh => run_test_06_cleanup.sh} (100%)
 rename src/tests/p4-int-routing-acl/{test_functional_rules_deprovision.py => test_functional_sbi_rules_deprovision.py} (100%)
 rename src/tests/p4-int-routing-acl/{test_functional_rules_provision.py => test_functional_sbi_rules_provision.py} (100%)

diff --git a/proto/context.proto b/proto/context.proto
index fb0111e14..0f2c8011f 100644
--- a/proto/context.proto
+++ b/proto/context.proto
@@ -199,13 +199,13 @@ message Device {
   DeviceId controller_id = 9; // Identifier of node controlling the actual device
 }
 
-message Component {                         //Defined previously to this section - Tested OK
-  Uuid component_uuid   = 1;
-  string name           = 2;
-  string type           = 3;
+message Component {                         // Defined previously in this section
+  Uuid component_uuid = 1;
+  string name         = 2;
+  string type         = 3;
   
   map<string, string> attributes = 4; // dict[attr.name => json.dumps(attr.value)]
-  string parent         = 5;
+  string parent       = 5;
 }
 
 message DeviceConfig {
@@ -271,6 +271,7 @@ enum LinkTypeEnum {
   LINKTYPE_FIBER   = 2;
   LINKTYPE_RADIO   = 3;
   LINKTYPE_VIRTUAL = 4;
+  LINKTYPE_MANAGEMENT = 5;
 }
 
 message LinkAttributes {
@@ -320,11 +321,14 @@ enum ServiceTypeEnum {
   SERVICETYPE_UNKNOWN = 0;
   SERVICETYPE_L3NM = 1;
   SERVICETYPE_L2NM = 2;
-  SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3;
-  SERVICETYPE_TE = 4;
-  SERVICETYPE_E2E = 5;
-  SERVICETYPE_OPTICAL_CONNECTIVITY = 6;
-  SERVICETYPE_QKD = 7;
+  SERVICETYPE_L1NM = 3;
+  SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 4;
+  SERVICETYPE_TE = 5;
+  SERVICETYPE_E2E = 6;
+  SERVICETYPE_OPTICAL_CONNECTIVITY = 7;
+  SERVICETYPE_QKD = 8;
+  SERVICETYPE_INT = 9;
+  SERVICETYPE_ACL = 10;
 }
 
 enum ServiceStatusEnum {
diff --git a/src/common/type_checkers/Checkers.py b/src/common/type_checkers/Checkers.py
index e1bbe3f06..694f14102 100644
--- a/src/common/type_checkers/Checkers.py
+++ b/src/common/type_checkers/Checkers.py
@@ -13,6 +13,8 @@
 # limitations under the License.
 
 import re
+import ipaddress
+from ctypes import c_uint16, sizeof
 from typing import Any, Container, Dict, List, Optional, Pattern, Set, Sized, Tuple, Union
 
 def chk_none(name : str, value : Any, reason=None) -> Any:
@@ -107,3 +109,80 @@ def chk_options(name : str, value : Any, options : Container) -> Any:
         msg = '{}({}) is not one of options({}).'
         raise ValueError(msg.format(str(name), str(value), str(options)))
     return value
+
+# MAC address checker
+mac_pattern = re.compile(r"^([\da-fA-F]{2}:){5}([\da-fA-F]{2})$")
+
+def chk_address_mac(mac_addr : str):
+    """
+    Check whether input string is a valid MAC address or not.
+
+    :param mac_addr: string-based MAC address
+    :return: boolean status
+    """
+    return mac_pattern.match(mac_addr) is not None
+
+# IPv4/IPv6 address checkers
+IPV4_LOCALHOST = "localhost"
+
+def chk_address_ipv4(ip_addr : str):
+    """
+    Check whether input string is a valid IPv4 address or not.
+
+    :param ip_addr: string-based IPv4 address
+    :return: boolean status
+    """
+    if ip_addr == IPV4_LOCALHOST:
+        return True
+    try:
+        addr = ipaddress.ip_address(ip_addr)
+        return isinstance(addr, ipaddress.IPv4Address)
+    except ValueError:
+        return False
+
+def chk_address_ipv6(ip_addr : str):
+    """
+    Check whether input string is a valid IPv6 address or not.
+
+    :param ip_addr: string-based IPv6 address
+    :return: boolean status
+    """
+    try:
+        addr = ipaddress.ip_address(ip_addr)
+        return isinstance(addr, ipaddress.IPv6Address)
+    except ValueError:
+        return False
+
+
+# VLAN ID checker
+VLAN_ID_MIN = 1
+VLAN_ID_MAX = 4094
+
+def chk_vlan_id(vlan_id : int):
+    return VLAN_ID_MIN <= vlan_id <= VLAN_ID_MAX
+
+
+# Transport port checker
+
+def limits(c_int_type):
+    """
+    Discover limits of numerical type.
+
+    :param c_int_type: numerical type
+    :return: tuple of numerical type's limits
+    """
+    signed = c_int_type(-1).value < c_int_type(0).value
+    bit_size = sizeof(c_int_type) * 8
+    signed_limit = 2 ** (bit_size - 1)
+    return (-signed_limit, signed_limit - 1) \
+        if signed else (0, 2 * signed_limit - 1)
+
+def chk_transport_port(trans_port : int):
+    """
+    Check whether input is a valid transport port number or not.
+
+    :param trans_port: transport port number
+    :return: boolean status
+    """
+    lim = limits(c_uint16)
+    return lim[0] <= trans_port <= lim[1]
diff --git a/src/context/service/database/models/enums/LinkType.py b/src/context/service/database/models/enums/LinkType.py
index 68624af84..97eacdd8b 100644
--- a/src/context/service/database/models/enums/LinkType.py
+++ b/src/context/service/database/models/enums/LinkType.py
@@ -18,15 +18,16 @@ from ._GrpcToEnum import grpc_to_enum
 
 # IMPORTANT: Entries of enum class ORM_LinkTypeEnum should be named as in
 #            the proto files removing the prefixes. For example, proto item
-#            LinkTypeEnum.DEVICEDRIVER_COPPER should be included as COPPER.
+#            LinkTypeEnum.COPPER should be included as COPPER.
 #            If item name does not match, automatic mapping of proto enums
 #            to database enums will fail.
 class ORM_LinkTypeEnum(enum.Enum):
-    UNKNOWN = LinkTypeEnum.LINKTYPE_UNKNOWN
-    COPPER  = LinkTypeEnum.LINKTYPE_COPPER
-    FIBER   = LinkTypeEnum.LINKTYPE_FIBER
-    RADIO   = LinkTypeEnum.LINKTYPE_RADIO
-    VIRTUAL = LinkTypeEnum.LINKTYPE_VIRTUAL
+    UNKNOWN    = LinkTypeEnum.LINKTYPE_UNKNOWN
+    COPPER     = LinkTypeEnum.LINKTYPE_COPPER
+    FIBER      = LinkTypeEnum.LINKTYPE_FIBER
+    RADIO      = LinkTypeEnum.LINKTYPE_RADIO
+    VIRTUAL    = LinkTypeEnum.LINKTYPE_VIRTUAL
+    MANAGEMENT = LinkTypeEnum.LINKTYPE_MANAGEMENT
 
 grpc_to_enum__link_type_enum = functools.partial(
     grpc_to_enum, LinkTypeEnum, ORM_LinkTypeEnum
diff --git a/src/context/service/database/models/enums/ServiceType.py b/src/context/service/database/models/enums/ServiceType.py
index 45f849a26..899c71acf 100644
--- a/src/context/service/database/models/enums/ServiceType.py
+++ b/src/context/service/database/models/enums/ServiceType.py
@@ -25,11 +25,14 @@ class ORM_ServiceTypeEnum(enum.Enum):
     UNKNOWN                   = ServiceTypeEnum.SERVICETYPE_UNKNOWN
     L3NM                      = ServiceTypeEnum.SERVICETYPE_L3NM
     L2NM                      = ServiceTypeEnum.SERVICETYPE_L2NM
+    L1NM                      = ServiceTypeEnum.SERVICETYPE_L1NM
     TAPI_CONNECTIVITY_SERVICE = ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE
     TE                        = ServiceTypeEnum.SERVICETYPE_TE
     E2E                       = ServiceTypeEnum.SERVICETYPE_E2E
     OPTICAL_CONNECTIVITY      = ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY
     QKD                       = ServiceTypeEnum.SERVICETYPE_QKD
+    INT                       = ServiceTypeEnum.SERVICETYPE_INT
+    ACL                       = ServiceTypeEnum.SERVICETYPE_ACL
 
 grpc_to_enum__service_type = functools.partial(
     grpc_to_enum, ServiceTypeEnum, ORM_ServiceTypeEnum)
diff --git a/src/device/service/drivers/p4/p4_common.py b/src/device/service/drivers/p4/p4_common.py
index b55296a65..b4c0d8832 100644
--- a/src/device/service/drivers/p4/p4_common.py
+++ b/src/device/service/drivers/p4/p4_common.py
@@ -23,16 +23,15 @@ as well as static variables used by various P4 driver components.
 """
 
 import logging
+import ipaddress
+import macaddress
 import math
-import re
 import socket
-import ipaddress
 from typing import Any, Dict, List, Optional, Tuple
-from ctypes import c_uint16, sizeof
-import macaddress
 
 from common.type_checkers.Checkers import \
-    chk_attribute, chk_string, chk_type, chk_issubclass
+    chk_attribute, chk_string, chk_type, chk_issubclass,\
+    chk_address_mac, chk_address_ipv4, chk_address_ipv6
 try:
     from .p4_exception import UserBadValueError
 except ImportError:
@@ -60,17 +59,6 @@ LOGGER = logging.getLogger(__name__)
 
 
 # MAC address encoding/decoding
-mac_pattern = re.compile(r"^([\da-fA-F]{2}:){5}([\da-fA-F]{2})$")
-
-
-def matches_mac(mac_addr_string):
-    """
-    Check whether input string is a valid MAC address or not.
-
-    :param mac_addr_string: string-based MAC address
-    :return: boolean status
-    """
-    return mac_pattern.match(mac_addr_string) is not None
 
 
 def encode_mac(mac_addr_string):
@@ -94,23 +82,6 @@ def decode_mac(encoded_mac_addr):
 
 
 # IP address encoding/decoding
-IPV4_LOCALHOST = "localhost"
-
-
-def matches_ipv4(ip_addr_string):
-    """
-    Check whether input string is a valid IPv4 address or not.
-
-    :param ip_addr_string: string-based IPv4 address
-    :return: boolean status
-    """
-    if ip_addr_string == IPV4_LOCALHOST:
-        return True
-    try:
-        addr = ipaddress.ip_address(ip_addr_string)
-        return isinstance(addr, ipaddress.IPv4Address)
-    except ValueError:
-        return False
 
 
 def encode_ipv4(ip_addr_string):
@@ -133,20 +104,6 @@ def decode_ipv4(encoded_ip_addr):
     return socket.inet_ntoa(encoded_ip_addr)
 
 
-def matches_ipv6(ip_addr_string):
-    """
-    Check whether input string is a valid IPv6 address or not.
-
-    :param ip_addr_string: string-based IPv6 address
-    :return: boolean status
-    """
-    try:
-        addr = ipaddress.ip_address(ip_addr_string)
-        return isinstance(addr, ipaddress.IPv6Address)
-    except ValueError:
-        return False
-
-
 def encode_ipv6(ip_addr_string):
     """
     Convert string-based IPv6 address into bytes.
@@ -170,31 +127,6 @@ def decode_ipv6(encoded_ip_addr):
 # Numerical encoding/decoding
 
 
-def limits(c_int_type):
-    """
-    Discover limits of numerical type.
-
-    :param c_int_type: numerical type
-    :return: tuple of numerical type's limits
-    """
-    signed = c_int_type(-1).value < c_int_type(0).value
-    bit_size = sizeof(c_int_type) * 8
-    signed_limit = 2 ** (bit_size - 1)
-    return (-signed_limit, signed_limit - 1) \
-        if signed else (0, 2 * signed_limit - 1)
-
-
-def valid_port(port):
-    """
-    Check whether input is a valid port number or not.
-
-    :param port: port number
-    :return: boolean status
-    """
-    lim = limits(c_uint16)
-    return lim[0] <= port <= lim[1]
-
-
 def bitwidth_to_bytes(bitwidth):
     """
     Convert number of bits to number of bytes.
@@ -245,11 +177,11 @@ def encode(variable, bitwidth):
     if isinstance(variable, int):
         encoded_bytes = encode_num(variable, bitwidth)
     elif isinstance(variable, str):
-        if matches_mac(variable):
+        if chk_address_mac(variable):
             encoded_bytes = encode_mac(variable)
-        elif matches_ipv4(variable):
+        elif chk_address_ipv4(variable):
             encoded_bytes = encode_ipv4(variable)
-        elif matches_ipv6(variable):
+        elif chk_address_ipv6(variable):
             encoded_bytes = encode_ipv6(variable)
         else:
             try:
@@ -471,7 +403,7 @@ def parse_integer_list_from_json(resource, resource_list, resource_item):
     return integers_list
 
 def process_optional_string_field(
-    #TODO: Consider adding this in common methdos as it is taken by the Emulated driver
+    #TODO: Consider adding this in common methods as it is taken by the Emulated driver
     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)
diff --git a/src/device/service/drivers/p4/p4_driver.py b/src/device/service/drivers/p4/p4_driver.py
index c89a42bad..0b109529d 100644
--- a/src/device/service/drivers/p4/p4_driver.py
+++ b/src/device/service/drivers/p4/p4_driver.py
@@ -22,10 +22,10 @@ import logging
 import threading
 from typing import Any, Iterator, List, Optional, Tuple, Union
 from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method
-from common.type_checkers.Checkers import chk_type, chk_length, chk_string
+from common.type_checkers.Checkers import chk_type, chk_length, chk_string, \
+    chk_address_ipv4, chk_address_ipv6, chk_transport_port
 from device.service.driver_api._Driver import RESOURCE_ENDPOINTS, RESOURCE_RULES
-from .p4_common import matches_ipv4, matches_ipv6, valid_port,\
-    compose_resource_endpoints, parse_resource_string_from_json,\
+from .p4_common import compose_resource_endpoints,\
     P4_ATTR_DEV_ID, P4_ATTR_DEV_NAME, P4_ATTR_DEV_ENDPOINTS,\
     P4_ATTR_DEV_VENDOR, P4_ATTR_DEV_HW_VER, P4_ATTR_DEV_SW_VER,\
     P4_ATTR_DEV_P4BIN, P4_ATTR_DEV_P4INFO, P4_ATTR_DEV_TIMEOUT,\
@@ -336,9 +336,9 @@ class P4Driver(_Driver):
         :return: void or exception in case of validation error
         """
         # Device endpoint information
-        assert matches_ipv4(self.__address) or (matches_ipv6(self.__address)),\
+        assert chk_address_ipv4(self.__address) or (chk_address_ipv6(self.__address)),\
             f"{self.__address} not a valid IPv4 or IPv6 address"
-        assert valid_port(self.__port), \
+        assert chk_transport_port(self.__port), \
             f"{self.__port} not a valid transport port"
         self.__grpc_endpoint = f"{self.__address}:{self.__port}"
 
@@ -395,18 +395,24 @@ class P4Driver(_Driver):
         # Path to P4 binary file
         if P4_ATTR_DEV_P4BIN in self.__settings:
             self.__p4bin_path = self.__settings.get(P4_ATTR_DEV_P4BIN)
-            assert os.path.exists(self.__p4bin_path),\
-                "Invalid path to p4bin file: {}".format(self.__p4bin_path)
-            assert P4_ATTR_DEV_P4INFO in self.__settings,\
-                "p4info and p4bin settings must be provided together"
+            if not os.path.exists(self.__p4bin_path):
+                LOGGER.warning(
+                    "Invalid path to p4bin file: {}".format(self.__p4bin_path))
+                self.__p4bin_path = ""
+            else:
+                assert P4_ATTR_DEV_P4INFO in self.__settings,\
+                    "p4info and p4bin settings must be provided together"
 
         # Path to P4 info file
         if P4_ATTR_DEV_P4INFO in self.__settings:
             self.__p4info_path = self.__settings.get(P4_ATTR_DEV_P4INFO)
-            assert os.path.exists(self.__p4info_path),\
-                "Invalid path to p4info file: {}".format(self.__p4info_path)
-            assert P4_ATTR_DEV_P4BIN in self.__settings,\
-                "p4info and p4bin settings must be provided together"
+            if not os.path.exists(self.__p4info_path):
+                LOGGER.warning(
+                    "Invalid path to p4info file: {}".format(self.__p4info_path))
+                self.__p4info_path = ""
+            else:
+                assert P4_ATTR_DEV_P4BIN in self.__settings,\
+                    "p4info and p4bin settings must be provided together"
 
         if (not self.__p4bin_path) or (not self.__p4info_path):
             LOGGER.warning(
diff --git a/src/device/tests/test_internal_p4.py b/src/device/tests/test_internal_p4.py
index af99bb86b..48501bfd8 100644
--- a/src/device/tests/test_internal_p4.py
+++ b/src/device/tests/test_internal_p4.py
@@ -17,11 +17,13 @@ Internal P4 driver tests.
 """
 
 import pytest
+from common.type_checkers.Checkers import chk_address_mac, \
+    chk_address_ipv4, chk_address_ipv6
 from device.service.drivers.p4.p4_driver import P4Driver
 from device.service.drivers.p4.p4_common import (
-    matches_mac, encode_mac, decode_mac, encode,
-    matches_ipv4, encode_ipv4, decode_ipv4,
-    matches_ipv6, encode_ipv6, decode_ipv6,
+    encode_mac, decode_mac, encode,
+    encode_ipv4, decode_ipv4,
+    encode_ipv6, decode_ipv6,
     encode_num, decode_num
 )
 from .device_p4 import(
@@ -172,10 +174,10 @@ def test_p4_common_mac():
     :return: void
     """
     wrong_mac = "aa:bb:cc:dd:ee"
-    assert not matches_mac(wrong_mac)
+    assert not chk_address_mac(wrong_mac)
 
     mac = "aa:bb:cc:dd:ee:fe"
-    assert matches_mac(mac)
+    assert chk_address_mac(mac)
     enc_mac = encode_mac(mac)
     assert enc_mac == b'\xaa\xbb\xcc\xdd\xee\xfe',\
         "String-based MAC address to bytes failed"
@@ -193,13 +195,13 @@ def test_p4_common_ipv4():
 
     :return: void
     """
-    assert not matches_ipv4("10.0.0.1.5")
-    assert not matches_ipv4("256.0.0.1")
-    assert not matches_ipv4("256.0.1")
-    assert not matches_ipv4("10001")
+    assert not chk_address_ipv4("10.0.0.1.5")
+    assert not chk_address_ipv4("256.0.0.1")
+    assert not chk_address_ipv4("256.0.1")
+    assert not chk_address_ipv4("10001")
 
     ipv4 = "10.0.0.1"
-    assert matches_ipv4(ipv4)
+    assert chk_address_ipv4(ipv4)
     enc_ipv4 = encode_ipv4(ipv4)
     assert enc_ipv4 == b'\x0a\x00\x00\x01',\
         "String-based IPv4 address to bytes failed"
@@ -214,11 +216,11 @@ def test_p4_common_ipv6():
 
     :return: void
     """
-    assert not matches_ipv6('10.0.0.1')
-    assert matches_ipv6('2001:0000:85a3::8a2e:370:1111')
+    assert not chk_address_ipv6('10.0.0.1')
+    assert chk_address_ipv6('2001:0000:85a3::8a2e:370:1111')
 
     ipv6 = "1:2:3:4:5:6:7:8"
-    assert matches_ipv6(ipv6)
+    assert chk_address_ipv6(ipv6)
     enc_ipv6 = encode_ipv6(ipv6)
     assert enc_ipv6 == \
            b'\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08',\
diff --git a/src/service/service/service_handler_api/FilterFields.py b/src/service/service/service_handler_api/FilterFields.py
index 34f5ce59a..170f34a61 100644
--- a/src/service/service/service_handler_api/FilterFields.py
+++ b/src/service/service/service_handler_api/FilterFields.py
@@ -23,11 +23,14 @@ SERVICE_TYPE_VALUES = {
     ServiceTypeEnum.SERVICETYPE_UNKNOWN,
     ServiceTypeEnum.SERVICETYPE_L3NM,
     ServiceTypeEnum.SERVICETYPE_L2NM,
+    ServiceTypeEnum.SERVICETYPE_L1NM,
     ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
     ServiceTypeEnum.SERVICETYPE_TE,
     ServiceTypeEnum.SERVICETYPE_E2E,
     ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY,
     ServiceTypeEnum.SERVICETYPE_QKD,
+    ServiceTypeEnum.SERVICETYPE_INT,
+    ServiceTypeEnum.SERVICETYPE_ACL,
 }
 
 DEVICE_DRIVER_VALUES = {
diff --git a/src/service/service/service_handlers/__init__.py b/src/service/service/service_handlers/__init__.py
index f63866d9d..933725aa5 100644
--- a/src/service/service/service_handlers/__init__.py
+++ b/src/service/service/service_handlers/__init__.py
@@ -25,7 +25,7 @@ from .l3nm_ietf_actn.L3NMIetfActnServiceHandler import L3NMIetfActnServiceHandle
 from .l3nm_nce.L3NMNCEServiceHandler import L3NMNCEServiceHandler
 from .l3slice_ietfslice.L3SliceIETFSliceServiceHandler import L3NMSliceIETFSliceServiceHandler
 from .microwave.MicrowaveServiceHandler import MicrowaveServiceHandler
-from .p4.p4_service_handler import P4ServiceHandler
+from .p4_l1.p4_l1_service_handler import P4L1ServiceHandler
 from .tapi_tapi.TapiServiceHandler import TapiServiceHandler
 from .tapi_xr.TapiXrServiceHandler import TapiXrServiceHandler
 from .optical_tfs.OpticalTfsServiceHandler import OpticalTfsServiceHandler
@@ -105,9 +105,9 @@ SERVICE_HANDLERS = [
             FilterFieldEnum.DEVICE_DRIVER : [DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY, DeviceDriverEnum.DEVICEDRIVER_ONF_TR_532],
         }
     ]),
-    (P4ServiceHandler, [
+    (P4L1ServiceHandler, [
         {
-            FilterFieldEnum.SERVICE_TYPE: ServiceTypeEnum.SERVICETYPE_L2NM,
+            FilterFieldEnum.SERVICE_TYPE: ServiceTypeEnum.SERVICETYPE_L1NM,
             FilterFieldEnum.DEVICE_DRIVER: DeviceDriverEnum.DEVICEDRIVER_P4,
         }
     ]),
diff --git a/src/service/service/service_handlers/p4/__init__.py b/src/service/service/service_handlers/p4_l1/__init__.py
similarity index 100%
rename from src/service/service/service_handlers/p4/__init__.py
rename to src/service/service/service_handlers/p4_l1/__init__.py
diff --git a/src/service/service/service_handlers/p4/p4_service_handler.py b/src/service/service/service_handlers/p4_l1/p4_l1_service_handler.py
similarity index 95%
rename from src/service/service/service_handlers/p4/p4_service_handler.py
rename to src/service/service/service_handlers/p4_l1/p4_l1_service_handler.py
index 49bedbb22..b1ff9c600 100644
--- a/src/service/service/service_handlers/p4/p4_service_handler.py
+++ b/src/service/service/service_handlers/p4_l1/p4_l1_service_handler.py
@@ -13,7 +13,8 @@
 # limitations under the License.
 
 """
-P4 service handler for the TeraFlowSDN controller.
+P4 service handler for L1 connectivity services
+(in-port to out-port or input endpoint to output endpoint).
 """
 
 import logging
@@ -28,7 +29,7 @@ from service.service.task_scheduler.TaskExecutor import TaskExecutor
 
 LOGGER = logging.getLogger(__name__)
 
-METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'p4'})
+METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'p4_l1'})
 
 def create_rule_set(endpoint_a, endpoint_b):
     return json_config_rule_set(
@@ -79,14 +80,13 @@ def find_names(uuid_a, uuid_b, device_endpoints):
             endpoint_a = endpoint.name
         elif endpoint.endpoint_id.endpoint_uuid.uuid == uuid_b:
             endpoint_b = endpoint.name
-            
+
     return (endpoint_a, endpoint_b)
 
-class P4ServiceHandler(_ServiceHandler):
-    def __init__(self,
-                 service: Service,
-                 task_executor : TaskExecutor,
-                 **settings) -> None:
+class P4L1ServiceHandler(_ServiceHandler):
+    def __init__(   # pylint: disable=super-init-not-called
+        self, service : Service, task_executor : TaskExecutor, **settings
+    ) -> None:
         """ Initialize Driver.
             Parameters:
                 service
@@ -106,7 +106,7 @@ class P4ServiceHandler(_ServiceHandler):
         self, endpoints : List[Tuple[str, str, Optional[str]]],
         connection_uuid : Optional[str] = None
     ) -> List[Union[bool, Exception]]:
-        """ Create/Update service endpoints form a list.
+        """ Create/Update service endpoints from a list.
             Parameters:
                 endpoints: List[Tuple[str, str, Optional[str]]]
                     List of tuples, each containing a device_uuid,
@@ -126,21 +126,21 @@ class P4ServiceHandler(_ServiceHandler):
         if len(endpoints) == 0: return []
 
         service_uuid = self.__service.service_id.service_uuid.uuid
+        LOGGER.info("SetEndpoint - Service {}".format(service_uuid))
 
         history = {}
-        
         results = []
         index = {}
         i = 0
-        for endpoint in endpoints:        
+        for endpoint in endpoints:
             device_uuid, endpoint_uuid = endpoint[0:2] # ignore topology_uuid by now
-            if device_uuid in history:       
+            if device_uuid in history:
                 try:
                     matched_endpoint_uuid = history.pop(device_uuid)
                     device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
 
                     del device.device_config.config_rules[:]
-                    
+
                     # Find names from uuids
                     (endpoint_a, endpoint_b) = find_names(matched_endpoint_uuid, endpoint_uuid, device.device_endpoints)
                     if endpoint_a is None:
@@ -151,14 +151,14 @@ class P4ServiceHandler(_ServiceHandler):
                         raise Exception('Unable to find name of endpoint({:s})'.format(str(endpoint_uuid)))
 
                     # One way
-                    rule = create_rule_set(endpoint_a, endpoint_b) 
+                    rule = create_rule_set(endpoint_a, endpoint_b)
                     device.device_config.config_rules.append(ConfigRule(**rule))
                     # The other way
-                    rule = create_rule_set(endpoint_b, endpoint_a) 
+                    rule = create_rule_set(endpoint_b, endpoint_a)
                     device.device_config.config_rules.append(ConfigRule(**rule))
 
                     self.__task_executor.configure_device(device)
-            
+
                     results.append(True)
                     results[index[device_uuid]] = True
                 except Exception as e:
@@ -177,7 +177,7 @@ class P4ServiceHandler(_ServiceHandler):
         self, endpoints : List[Tuple[str, str, Optional[str]]],
         connection_uuid : Optional[str] = None
     ) -> List[Union[bool, Exception]]:
-        """ Delete service endpoints form a list.
+        """ Delete service endpoints from a list.
             Parameters:
                 endpoints: List[Tuple[str, str, Optional[str]]]
                     List of tuples, each containing a device_uuid,
@@ -197,15 +197,15 @@ class P4ServiceHandler(_ServiceHandler):
         if len(endpoints) == 0: return []
 
         service_uuid = self.__service.service_id.service_uuid.uuid
+        LOGGER.info("DeleteEndpoint - Service {}".format(service_uuid))
 
         history = {}
-        
         results = []
         index = {}
         i = 0
-        for endpoint in endpoints:        
+        for endpoint in endpoints:
             device_uuid, endpoint_uuid = endpoint[0:2] # ignore topology_uuid by now
-            if device_uuid in history:       
+            if device_uuid in history:
                 try:
                     matched_endpoint_uuid = history.pop(device_uuid)
                     device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
@@ -222,14 +222,14 @@ class P4ServiceHandler(_ServiceHandler):
                         raise Exception('Unable to find name of endpoint({:s})'.format(str(endpoint_uuid)))
 
                     # One way
-                    rule = create_rule_del(endpoint_a, endpoint_b) 
+                    rule = create_rule_del(endpoint_a, endpoint_b)
                     device.device_config.config_rules.append(ConfigRule(**rule))
                     # The other way
-                    rule = create_rule_del(endpoint_b, endpoint_a) 
+                    rule = create_rule_del(endpoint_b, endpoint_a)
                     device.device_config.config_rules.append(ConfigRule(**rule))
 
                     self.__task_executor.configure_device(device)
-            
+
                     results.append(True)
                     results[index[device_uuid]] = True
                 except Exception as e:
@@ -338,4 +338,4 @@ class P4ServiceHandler(_ServiceHandler):
 
         msg = '[SetConfig] Method not implemented. Resources({:s}) are being ignored.'
         LOGGER.warning(msg.format(str(resources)))
-        return [True for _ in range(len(resources))]
\ No newline at end of file
+        return [True for _ in range(len(resources))]
diff --git a/src/tests/p4-int-routing-acl/descriptors/rules-insert-acl.json b/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-acl.json
similarity index 100%
rename from src/tests/p4-int-routing-acl/descriptors/rules-insert-acl.json
rename to src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-acl.json
diff --git a/src/tests/p4-int-routing-acl/descriptors/rules-insert-int-b1.json b/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b1.json
similarity index 100%
rename from src/tests/p4-int-routing-acl/descriptors/rules-insert-int-b1.json
rename to src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b1.json
diff --git a/src/tests/p4-int-routing-acl/descriptors/rules-insert-int-b2.json b/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b2.json
similarity index 100%
rename from src/tests/p4-int-routing-acl/descriptors/rules-insert-int-b2.json
rename to src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b2.json
diff --git a/src/tests/p4-int-routing-acl/descriptors/rules-insert-int-b3.json b/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b3.json
similarity index 100%
rename from src/tests/p4-int-routing-acl/descriptors/rules-insert-int-b3.json
rename to src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b3.json
diff --git a/src/tests/p4-int-routing-acl/descriptors/rules-insert-routing-corp.json b/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-routing-corp.json
similarity index 100%
rename from src/tests/p4-int-routing-acl/descriptors/rules-insert-routing-corp.json
rename to src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-routing-corp.json
diff --git a/src/tests/p4-int-routing-acl/descriptors/rules-insert-routing-edge.json b/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-routing-edge.json
similarity index 100%
rename from src/tests/p4-int-routing-acl/descriptors/rules-insert-routing-edge.json
rename to src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-routing-edge.json
diff --git a/src/tests/p4-int-routing-acl/descriptors/rules-remove.json b/src/tests/p4-int-routing-acl/descriptors/sbi-rules-remove.json
similarity index 100%
rename from src/tests/p4-int-routing-acl/descriptors/rules-remove.json
rename to src/tests/p4-int-routing-acl/descriptors/sbi-rules-remove.json
diff --git a/src/tests/p4-int-routing-acl/descriptors/topology.json b/src/tests/p4-int-routing-acl/descriptors/topology.json
index 3b1f6e410..30e1f5e9a 100644
--- a/src/tests/p4-int-routing-acl/descriptors/topology.json
+++ b/src/tests/p4-int-routing-acl/descriptors/topology.json
@@ -1,287 +1,113 @@
 {
     "contexts": [
-        {
-            "context_id": {
-                "context_uuid": {
-                    "uuid": "admin"
-                }
-            }
-        }
+        {"context_id": {"context_uuid": {"uuid": "admin"}}}
     ],
     "topologies": [
-        {
-            "topology_id": {
-                "context_id": {
-                    "context_uuid": {
-                        "uuid": "admin"
-                    }
-                },
-                "topology_uuid": {
-                    "uuid": "admin"
-                }
-            }
+        {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
         }
     ],
     "devices": [
         {
-            "device_id": {
-                "device_uuid": {
-                    "uuid": "edge-net"
-                }
-            },
+            "device_id": {"device_uuid": {"uuid": "tfs-sdn-controller"}},
+            "name": "tfs-sdn-controller",
+            "device_type": "teraflowsdn",
+            "device_drivers": ["DEVICEDRIVER_IETF_L3VPN"],
+            "device_operational_status": "DEVICEOPERATIONALSTATUS_UNDEFINED",
+            "device_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.10.10.41"}},
+                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8002"}},
+                {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
+                    "endpoints": [{"uuid": "mgmt", "name": "mgmt", "type": "mgmt-int"}],
+                    "scheme": "http", "username": "admin", "password": "admin", "import_topology": "topology"
+                }}}
+            ]}
+        },
+        {
+            "device_id": {"device_uuid": {"uuid": "edge-net"}},
             "device_type": "network",
-            "device_drivers": [
-                "DEVICEDRIVER_UNDEFINED"
-            ],
+            "device_drivers": ["DEVICEDRIVER_UNDEFINED"],
             "device_config": {
                 "config_rules": [
-                    {
-                        "action": "CONFIGACTION_SET",
-                        "custom": {
-                            "resource_key": "_connect/address",
-                            "resource_value": "127.0.0.1"
-                        }
-                    },
-                    {
-                        "action": "CONFIGACTION_SET",
-                        "custom": {
-                            "resource_key": "_connect/port",
-                            "resource_value": "0"
-                        }
-                    },
-                    {
-                        "action": "CONFIGACTION_SET",
-                        "custom": {
-                            "resource_key": "_connect/settings",
-                            "resource_value": {
-                                "endpoints": [
-                                    {
-                                        "uuid": "eth1",
-                                        "type": "copper"
-                                    }
-                                ]
-                            }
-                        }
-                    }
+                    {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}},
+                    {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/port", "resource_value": "0"}},
+                    {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/settings", "resource_value": {
+                        "endpoints": [{"uuid": "eth1", "name": "eth1", "type": "copper"}]
+                    }}}
                 ]
             }
         },
         {
-            "device_id": {
-                "device_uuid": {
-                    "uuid": "corporate-net"
-                }
-            },
+            "device_id": {"device_uuid": {"uuid": "corporate-net"}},
             "device_type": "network",
-            "device_drivers": [
-                "DEVICEDRIVER_UNDEFINED"
-            ],
+            "device_drivers": ["DEVICEDRIVER_UNDEFINED"],
             "device_config": {
                 "config_rules": [
-                    {
-                        "action": "CONFIGACTION_SET",
-                        "custom": {
-                            "resource_key": "_connect/address",
-                            "resource_value": "127.0.0.1"
-                        }
-                    },
-                    {
-                        "action": "CONFIGACTION_SET",
-                        "custom": {
-                            "resource_key": "_connect/port",
-                            "resource_value": "0"
-                        }
-                    },
-                    {
-                        "action": "CONFIGACTION_SET",
-                        "custom": {
-                            "resource_key": "_connect/settings",
-                            "resource_value": {
-                                "endpoints": [
-                                    {
-                                        "uuid": "eth1",
-                                        "type": "copper"
-                                    }
-                                ]
-                            }
-                        }
-                    }
+                    {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}},
+                    {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/port", "resource_value": "0"}},
+                    {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/settings", "resource_value": {
+                        "endpoints": [{"uuid": "eth1", "name": "eth1", "type": "copper"}]
+                    }}}
                 ]
             }
         },
         {
-            "device_id": {
-                "device_uuid": {
-                    "uuid": "p4-sw1"
-                }
-            },
+            "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
             "device_type": "p4-switch",
-            "device_drivers": [
-                "DEVICEDRIVER_P4"
-            ],
+            "device_drivers": ["DEVICEDRIVER_P4"],
             "device_operational_status": "DEVICEOPERATIONALSTATUS_DISABLED",
             "name": "p4-sw1",
             "device_config": {
                 "config_rules": [
-                    {
-                        "action": "CONFIGACTION_SET",
-                        "custom": {
-                            "resource_key": "_connect/address",
-                            "resource_value": "10.10.10.120"
-                        }
-                    },
-                    {
-                        "action": "CONFIGACTION_SET",
-                        "custom": {
-                            "resource_key": "_connect/port",
-                            "resource_value": "50001"
-                        }
-                    },
-                    {
-                        "action": "CONFIGACTION_SET",
-                        "custom": {
-                            "resource_key": "_connect/settings",
-                            "resource_value": {
-                                "id": 1,
-                                "name": "p4-sw1",
-                                "vendor": "Open Networking Foundation",
-                                "hw_ver": "BMv2 simple_switch",
-                                "sw_ver": "Stratum",
-                                "p4bin": "/root/p4/bmv2.json",
-                                "p4info": "/root/p4/p4info.txt",
-                                "timeout": 60,
-                                "endpoints": [
-                                    {
-                                        "uuid": "1",
-                                        "type": "port"
-                                    },
-                                    {
-                                        "uuid": "2",
-                                        "type": "port"
-                                    }
-                                ]
-                            }
-                        }
-                    }
+                    {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/address", "resource_value": "10.10.10.120"}},
+                    {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/port", "resource_value": "50001"}},
+                    {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/settings", "resource_value": {
+                        "id": 1,
+                        "name": "p4-sw1",
+                        "vendor": "Open Networking Foundation",
+                        "hw_ver": "BMv2 simple_switch",
+                        "sw_ver": "Stratum",
+                        "timeout": 60,
+                        "p4bin": "/root/p4/bmv2.json",
+                        "p4info": "/root/p4/p4info.txt",
+                        "endpoints": [
+                            {"uuid": "1", "name": "1", "type": "port-dataplane"},
+                            {"uuid": "2", "name": "2", "type": "port-dataplane"},
+                            {"uuid": "3", "name": "3", "type": "port-int"}
+                        ]
+                    }}}
                 ]
             }
         }
     ],
     "links": [
         {
-            "link_id": {
-                "link_uuid": {
-                    "uuid": "p4-sw1/1==edge-net/eth1"
-                }
-            },
-            "link_endpoint_ids": [
-                {
-                    "device_id": {
-                        "device_uuid": {
-                            "uuid": "p4-sw1"
-                        }
-                    },
-                    "endpoint_uuid": {
-                        "uuid": "1"
-                    }
-                },
-                {
-                    "device_id": {
-                        "device_uuid": {
-                            "uuid": "edge-net"
-                        }
-                    },
-                    "endpoint_uuid": {
-                        "uuid": "eth1"
-                    }
-                }
+            "link_id": {"link_uuid": {"uuid": "p4-sw1/1==edge-net/eth1"}}, "link_type": "LINKTYPE_VIRTUAL", "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "p4-sw1"}},   "endpoint_uuid": {"uuid": "1"}},
+                {"device_id": {"device_uuid": {"uuid": "edge-net"}}, "endpoint_uuid": {"uuid": "eth1"}}
+            ]
+        },
+        {
+            "link_id": {"link_uuid": {"uuid": "edge-net/eth1==p4-sw1/1"}}, "link_type": "LINKTYPE_VIRTUAL", "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "edge-net"}}, "endpoint_uuid": {"uuid": "eth1"}},
+                {"device_id": {"device_uuid": {"uuid": "p4-sw1"}},   "endpoint_uuid": {"uuid": "1"}}
             ]
         },
         {
-            "link_id": {
-                "link_uuid": {
-                    "uuid": "edge-net/eth1==p4-sw1/1"
-                }
-            },
-            "link_endpoint_ids": [
-                {
-                    "device_id": {
-                        "device_uuid": {
-                            "uuid": "edge-net"
-                        }
-                    },
-                    "endpoint_uuid": {
-                        "uuid": "eth1"
-                    }
-                },
-                {
-                    "device_id": {
-                        "device_uuid": {
-                            "uuid": "p4-sw1"
-                        }
-                    },
-                    "endpoint_uuid": {
-                        "uuid": "1"
-                    }
-                }
+            "link_id": {"link_uuid": {"uuid": "p4-sw1/2==corporate-net/eth1"}}, "link_type": "LINKTYPE_VIRTUAL", "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "p4-sw1"}},        "endpoint_uuid": {"uuid": "2"}},
+                {"device_id": {"device_uuid": {"uuid": "corporate-net"}}, "endpoint_uuid": {"uuid": "eth1"}}
             ]
         },
         {
-            "link_id": {
-                "link_uuid": {
-                    "uuid": "p4-sw1/2==corporate-net/eth1"
-                }
-            },
-            "link_endpoint_ids": [
-                {
-                    "device_id": {
-                        "device_uuid": {
-                            "uuid": "p4-sw1"
-                        }
-                    },
-                    "endpoint_uuid": {
-                        "uuid": "2"
-                    }
-                },
-                {
-                    "device_id": {
-                        "device_uuid": {
-                            "uuid": "corporate-net"
-                        }
-                    },
-                    "endpoint_uuid": {
-                        "uuid": "eth1"
-                    }
-                }
+            "link_id": {"link_uuid": {"uuid": "corporate-net/eth1==p4-sw1/2"}}, "link_type": "LINKTYPE_VIRTUAL", "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "corporate-net"}}, "endpoint_uuid": {"uuid": "eth1"}},
+                {"device_id": {"device_uuid": {"uuid": "p4-sw1"}},        "endpoint_uuid": {"uuid": "2"}}
             ]
         },
         {
-            "link_id": {
-                "link_uuid": {
-                    "uuid": "corporate-net/eth1==p4-sw1/2"
-                }
-            },
-            "link_endpoint_ids": [
-                {
-                    "device_id": {
-                        "device_uuid": {
-                            "uuid": "corporate-net"
-                        }
-                    },
-                    "endpoint_uuid": {
-                        "uuid": "eth1"
-                    }
-                },
-                {
-                    "device_id": {
-                        "device_uuid": {
-                            "uuid": "p4-sw1"
-                        }
-                    },
-                    "endpoint_uuid": {
-                        "uuid": "2"
-                    }
-                }
+            "link_id": {"link_uuid": {"uuid": "p4-sw1/3==tfs-sdn-controller/mgmt"}}, "link_type": "LINKTYPE_MANAGEMENT", "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "p4-sw1"}},             "endpoint_uuid": {"uuid": "3"}},
+                {"device_id": {"device_uuid": {"uuid": "tfs-sdn-controller"}}, "endpoint_uuid": {"uuid": "mgmt"}}
             ]
         }
     ]
diff --git a/src/tests/p4-int-routing-acl/run_test_02_rules_provision.sh b/src/tests/p4-int-routing-acl/run_test_02_sbi_rules_provision.sh
similarity index 95%
rename from src/tests/p4-int-routing-acl/run_test_02_rules_provision.sh
rename to src/tests/p4-int-routing-acl/run_test_02_sbi_rules_provision.sh
index 6709d66c6..7c485d401 100755
--- a/src/tests/p4-int-routing-acl/run_test_02_rules_provision.sh
+++ b/src/tests/p4-int-routing-acl/run_test_02_sbi_rules_provision.sh
@@ -14,4 +14,4 @@
 # limitations under the License.
 
 source tfs_runtime_env_vars.sh
-python3 -m pytest --verbose src/tests/p4-int-routing-acl/test_functional_rules_provision.py
+python3 -m pytest --verbose src/tests/p4-int-routing-acl/test_functional_sbi_rules_provision.py
diff --git a/src/tests/p4-int-routing-acl/run_test_03_rules_deprovision.sh b/src/tests/p4-int-routing-acl/run_test_03_sbi_rules_deprovision.sh
similarity index 95%
rename from src/tests/p4-int-routing-acl/run_test_03_rules_deprovision.sh
rename to src/tests/p4-int-routing-acl/run_test_03_sbi_rules_deprovision.sh
index 3a67fad8a..4032c01df 100755
--- a/src/tests/p4-int-routing-acl/run_test_03_rules_deprovision.sh
+++ b/src/tests/p4-int-routing-acl/run_test_03_sbi_rules_deprovision.sh
@@ -14,4 +14,4 @@
 # limitations under the License.
 
 source tfs_runtime_env_vars.sh
-python3 -m pytest --verbose src/tests/p4-int-routing-acl/test_functional_rules_deprovision.py
+python3 -m pytest --verbose src/tests/p4-int-routing-acl/test_functional_sbi_rules_deprovision.py
diff --git a/src/tests/p4-int-routing-acl/run_test_04_cleanup.sh b/src/tests/p4-int-routing-acl/run_test_06_cleanup.sh
similarity index 100%
rename from src/tests/p4-int-routing-acl/run_test_04_cleanup.sh
rename to src/tests/p4-int-routing-acl/run_test_06_cleanup.sh
diff --git a/src/tests/p4-int-routing-acl/test_common.py b/src/tests/p4-int-routing-acl/test_common.py
index 8254eddc5..f2d00f1dc 100644
--- a/src/tests/p4-int-routing-acl/test_common.py
+++ b/src/tests/p4-int-routing-acl/test_common.py
@@ -22,9 +22,9 @@ CONTEXT_NAME_P4 = DEFAULT_CONTEXT_NAME
 ADMIN_CONTEXT_ID = ContextId(**json_context_id(CONTEXT_NAME_P4))
 
 # Device and rule cardinality variables
-DEV_NB = 3
+DEV_NB = 4
 CONNECTION_RULES = 3
-ENDPOINT_RULES = 2
+ENDPOINT_RULES = 3
 DATAPLANE_RULES_NB_INT_B1 = 5
 DATAPLANE_RULES_NB_INT_B2 = 6
 DATAPLANE_RULES_NB_INT_B3 = 8
@@ -39,6 +39,11 @@ DATAPLANE_RULES_NB_TOT = \
     DATAPLANE_RULES_NB_RT_CORP +\
     DATAPLANE_RULES_NB_ACL
 
+# Service-related variables
+SVC_NB = 1
+NO_SERVICES = 0
+NO_SLICES = 0
+
 # Topology descriptor
 DESC_TOPO = os.path.join(
     os.path.dirname(
@@ -47,51 +52,51 @@ DESC_TOPO = os.path.join(
     'descriptors', 'topology.json'
 )
 
-# Rule insertion descriptors
+# SBI rule insertion descriptors
 # The switch cannot digest all rules at once, hence we insert in batches
 DESC_FILE_RULES_INSERT_INT_B1 = os.path.join(
     os.path.dirname(
         os.path.abspath(__file__)
     ),
-    'descriptors', 'rules-insert-int-b1.json'
+    'descriptors', 'sbi-rules-insert-int-b1.json'
 )
 DESC_FILE_RULES_INSERT_INT_B2 = os.path.join(
     os.path.dirname(
         os.path.abspath(__file__)
     ),
-    'descriptors', 'rules-insert-int-b2.json'
+    'descriptors', 'sbi-rules-insert-int-b2.json'
 )
 DESC_FILE_RULES_INSERT_INT_B3 = os.path.join(
     os.path.dirname(
         os.path.abspath(__file__)
     ),
-    'descriptors', 'rules-insert-int-b3.json'
+    'descriptors', 'sbi-rules-insert-int-b3.json'
 )
 DESC_FILE_RULES_INSERT_ROUTING_EDGE = os.path.join(
     os.path.dirname(
         os.path.abspath(__file__)
     ),
-    'descriptors', 'rules-insert-routing-edge.json'
+    'descriptors', 'sbi-rules-insert-routing-edge.json'
 )
 DESC_FILE_RULES_INSERT_ROUTING_CORP = os.path.join(
     os.path.dirname(
         os.path.abspath(__file__)
     ),
-    'descriptors', 'rules-insert-routing-corp.json'
+    'descriptors', 'sbi-rules-insert-routing-corp.json'
 )
 DESC_FILE_RULES_INSERT_ACL = os.path.join(
     os.path.dirname(
         os.path.abspath(__file__)
     ),
-    'descriptors', 'rules-insert-acl.json'
+    'descriptors', 'sbi-rules-insert-acl.json'
 )
 
-# Rule deletion descriptor
+# SBI rule deletion descriptor
 DESC_FILE_RULES_DELETE_ALL = os.path.join(
     os.path.dirname(
         os.path.abspath(__file__)
     ),
-    'descriptors', 'rules-remove.json'
+    'descriptors', 'sbi-rules-remove.json'
 )
 
 def verify_number_of_rules(devices, desired_rules_nb):
diff --git a/src/tests/p4-int-routing-acl/test_functional_cleanup.py b/src/tests/p4-int-routing-acl/test_functional_cleanup.py
index 60c8684b0..fc29be24d 100644
--- a/src/tests/p4-int-routing-acl/test_functional_cleanup.py
+++ b/src/tests/p4-int-routing-acl/test_functional_cleanup.py
@@ -14,7 +14,6 @@
 
 import logging, os
 from common.Constants import DEFAULT_CONTEXT_NAME
-from common.proto.context_pb2 import ContextId
 from common.tools.descriptor.Loader import DescriptorLoader, validate_empty_scenario
 from context.client.ContextClient import ContextClient
 from device.client.DeviceClient import DeviceClient
diff --git a/src/tests/p4-int-routing-acl/test_functional_rules_deprovision.py b/src/tests/p4-int-routing-acl/test_functional_sbi_rules_deprovision.py
similarity index 100%
rename from src/tests/p4-int-routing-acl/test_functional_rules_deprovision.py
rename to src/tests/p4-int-routing-acl/test_functional_sbi_rules_deprovision.py
diff --git a/src/tests/p4-int-routing-acl/test_functional_rules_provision.py b/src/tests/p4-int-routing-acl/test_functional_sbi_rules_provision.py
similarity index 100%
rename from src/tests/p4-int-routing-acl/test_functional_rules_provision.py
rename to src/tests/p4-int-routing-acl/test_functional_sbi_rules_provision.py
diff --git a/src/webui/service/static/topology_icons/p4-switch.png b/src/webui/service/static/topology_icons/p4-switch.png
index 9afcda1c0e38cb5757574024f1a3f96001b03943..178943d67e0b0a1e501d27b32a5356d8afdd4e56 100644
GIT binary patch
literal 244738
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
Rln8z>aw<3RH%$Ki{{Z3|?F|3`

literal 6288
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

-- 
GitLab


From 1338291b933e7851f9b6ef88ac9b6adf522f9f88 Mon Sep 17 00:00:00 2001
From: "Georgios P. Katsikas" <gkatsikas@ubitech.eu>
Date: Sat, 22 Mar 2025 08:09:29 +0000
Subject: [PATCH 02/14] fix: refactoring of p4 fabric tna testing suite

---
 .../service/service_handlers/__init__.py      |   4 +-
 .../{p4_l1 => p4_dummy_l1}/__init__.py        |   0
 .../p4_dummy_l1_service_handler.py}           |   4 +-
 .../README.md                                 |  40 ++--
 .../__init__.py                               |   0
 .../descriptors/sbi-rules-insert-acl.json     |   0
 .../descriptors/sbi-rules-insert-int-b1.json  |   0
 .../descriptors/sbi-rules-insert-int-b2.json  |   0
 .../descriptors/sbi-rules-insert-int-b3.json  |   0
 .../sbi-rules-insert-routing-corp.json        |   0
 .../sbi-rules-insert-routing-edge.json        |   0
 .../descriptors/sbi-rules-remove.json         |   0
 .../descriptors/topology.json                 |   0
 .../p4src/README.md                           |   0
 .../p4src/_pp.p4                              |   0
 .../p4src/bmv2.json                           |   0
 .../p4src/p4info.txt                          |   0
 .../run_test_01_bootstrap.sh                  |   2 +-
 ...n_test_02a_sbi_provision_int_l2_l3_acl.sh} |   2 +-
 ..._test_02b_sbi_deprovision_int_l2_l3_acl.sh |  17 ++
 .../run_test_07_cleanup.sh}                   |   2 +-
 .../run_test_08_purge.sh}                     |   2 +-
 .../setup.sh                                  |   4 +-
 .../test_functional_sbi_rules_deprovision.py  |   2 +-
 .../test_functional_sbi_rules_provision.py    |   2 +-
 .../tests-setup}/test_functional_bootstrap.py |   2 +-
 .../tests-setup}/test_functional_cleanup.py   |   5 +-
 .../tests-setup/test_functional_purge.py      |  81 +++++++++
 .../topology/README.md                        |   0
 .../topology/p4-switch-conf-common.sh         |   0
 .../topology/p4-switch-setup.sh               |   0
 .../topology/p4-switch-tear-down.sh           |   0
 ...witch-three-port-chassis-config-phy.pb.txt |   0
 .../topology/run-stratum.sh                   |   0
 src/tests/p4-int-routing-acl/test_common.py   | 116 ------------
 src/tests/tools/test_tools_p4.py              | 172 ++++++++++++++++++
 36 files changed, 309 insertions(+), 148 deletions(-)
 rename src/service/service/service_handlers/{p4_l1 => p4_dummy_l1}/__init__.py (100%)
 rename src/service/service/service_handlers/{p4_l1/p4_l1_service_handler.py => p4_dummy_l1/p4_dummy_l1_service_handler.py} (99%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/README.md (73%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/__init__.py (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/descriptors/sbi-rules-insert-acl.json (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/descriptors/sbi-rules-insert-int-b1.json (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/descriptors/sbi-rules-insert-int-b2.json (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/descriptors/sbi-rules-insert-int-b3.json (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/descriptors/sbi-rules-insert-routing-corp.json (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/descriptors/sbi-rules-insert-routing-edge.json (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/descriptors/sbi-rules-remove.json (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/descriptors/topology.json (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/p4src/README.md (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/p4src/_pp.p4 (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/p4src/bmv2.json (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/p4src/p4info.txt (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/run_test_01_bootstrap.sh (89%)
 rename src/tests/{p4-int-routing-acl/run_test_03_sbi_rules_deprovision.sh => p4-fabric-tna/run_test_02a_sbi_provision_int_l2_l3_acl.sh} (86%)
 create mode 100755 src/tests/p4-fabric-tna/run_test_02b_sbi_deprovision_int_l2_l3_acl.sh
 rename src/tests/{p4-int-routing-acl/run_test_02_sbi_rules_provision.sh => p4-fabric-tna/run_test_07_cleanup.sh} (87%)
 rename src/tests/{p4-int-routing-acl/run_test_06_cleanup.sh => p4-fabric-tna/run_test_08_purge.sh} (88%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/setup.sh (80%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna/tests-sbi}/test_functional_sbi_rules_deprovision.py (99%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna/tests-sbi}/test_functional_sbi_rules_provision.py (99%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna/tests-setup}/test_functional_bootstrap.py (98%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna/tests-setup}/test_functional_cleanup.py (94%)
 create mode 100644 src/tests/p4-fabric-tna/tests-setup/test_functional_purge.py
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/topology/README.md (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/topology/p4-switch-conf-common.sh (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/topology/p4-switch-setup.sh (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/topology/p4-switch-tear-down.sh (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/topology/p4-switch-three-port-chassis-config-phy.pb.txt (100%)
 rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/topology/run-stratum.sh (100%)
 delete mode 100644 src/tests/p4-int-routing-acl/test_common.py
 create mode 100644 src/tests/tools/test_tools_p4.py

diff --git a/src/service/service/service_handlers/__init__.py b/src/service/service/service_handlers/__init__.py
index 933725aa5..e03c1172e 100644
--- a/src/service/service/service_handlers/__init__.py
+++ b/src/service/service/service_handlers/__init__.py
@@ -25,7 +25,7 @@ from .l3nm_ietf_actn.L3NMIetfActnServiceHandler import L3NMIetfActnServiceHandle
 from .l3nm_nce.L3NMNCEServiceHandler import L3NMNCEServiceHandler
 from .l3slice_ietfslice.L3SliceIETFSliceServiceHandler import L3NMSliceIETFSliceServiceHandler
 from .microwave.MicrowaveServiceHandler import MicrowaveServiceHandler
-from .p4_l1.p4_l1_service_handler import P4L1ServiceHandler
+from .p4_dummy_l1.p4_dummy_l1_service_handler import P4DummyL1ServiceHandler
 from .tapi_tapi.TapiServiceHandler import TapiServiceHandler
 from .tapi_xr.TapiXrServiceHandler import TapiXrServiceHandler
 from .optical_tfs.OpticalTfsServiceHandler import OpticalTfsServiceHandler
@@ -105,7 +105,7 @@ SERVICE_HANDLERS = [
             FilterFieldEnum.DEVICE_DRIVER : [DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY, DeviceDriverEnum.DEVICEDRIVER_ONF_TR_532],
         }
     ]),
-    (P4L1ServiceHandler, [
+    (P4DummyL1ServiceHandler, [
         {
             FilterFieldEnum.SERVICE_TYPE: ServiceTypeEnum.SERVICETYPE_L1NM,
             FilterFieldEnum.DEVICE_DRIVER: DeviceDriverEnum.DEVICEDRIVER_P4,
diff --git a/src/service/service/service_handlers/p4_l1/__init__.py b/src/service/service/service_handlers/p4_dummy_l1/__init__.py
similarity index 100%
rename from src/service/service/service_handlers/p4_l1/__init__.py
rename to src/service/service/service_handlers/p4_dummy_l1/__init__.py
diff --git a/src/service/service/service_handlers/p4_l1/p4_l1_service_handler.py b/src/service/service/service_handlers/p4_dummy_l1/p4_dummy_l1_service_handler.py
similarity index 99%
rename from src/service/service/service_handlers/p4_l1/p4_l1_service_handler.py
rename to src/service/service/service_handlers/p4_dummy_l1/p4_dummy_l1_service_handler.py
index b1ff9c600..6e9141caf 100644
--- a/src/service/service/service_handlers/p4_l1/p4_l1_service_handler.py
+++ b/src/service/service/service_handlers/p4_dummy_l1/p4_dummy_l1_service_handler.py
@@ -29,7 +29,7 @@ from service.service.task_scheduler.TaskExecutor import TaskExecutor
 
 LOGGER = logging.getLogger(__name__)
 
-METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'p4_l1'})
+METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'p4_dummy_l1'})
 
 def create_rule_set(endpoint_a, endpoint_b):
     return json_config_rule_set(
@@ -83,7 +83,7 @@ def find_names(uuid_a, uuid_b, device_endpoints):
 
     return (endpoint_a, endpoint_b)
 
-class P4L1ServiceHandler(_ServiceHandler):
+class P4DummyL1ServiceHandler(_ServiceHandler):
     def __init__(   # pylint: disable=super-init-not-called
         self, service : Service, task_executor : TaskExecutor, **settings
     ) -> None:
diff --git a/src/tests/p4-int-routing-acl/README.md b/src/tests/p4-fabric-tna/README.md
similarity index 73%
rename from src/tests/p4-int-routing-acl/README.md
rename to src/tests/p4-fabric-tna/README.md
index fa935e1b2..fc49276a9 100644
--- a/src/tests/p4-int-routing-acl/README.md
+++ b/src/tests/p4-fabric-tna/README.md
@@ -1,6 +1,7 @@
 # Tests for P4 routing, ACL, and In-Band Network Telemetry functions
 
-This directory contains the necessary scripts and configurations to run tests atop a Stratum-based P4 whitebox that performs a set of network functions, including routing, access control list (ACL), and In-Band Network Telemetry (INT).
+This directory contains the necessary scripts and configurations to run tests atop a Stratum-based P4 whitebox that performs a set of network functions, including forwarding (L2), routing (L3), L3/L4 access control list (ACL), and In-Band Network Telemetry (INT).
+The P4 data plane is based on ONF's SD-Fabric implementation, titled [fabric-tna](https://github.com/stratum/fabric-tna)
 
 ## Prerequisites
 
@@ -16,6 +17,7 @@ pip3 install grpcio-tools
 ```
 
 The versions used for this test are:
+
 - `protobuf` 3.20.3
 - `grpclib` 0.4.4
 - `grpcio` 1.47.5
@@ -29,11 +31,11 @@ First we copy it to /usr/local/bin/:
 ```
 
 Then, we include this path to the PYTHONPATH:
+
 ```shell
 export PYTHONPATH="${PYTHONPATH}:/usr/local/bin/protoc-gen-grpclib_python"
 ```
 
-
 You need to build and deploy a software-based Stratum switch, before being able to use TFS to control it.
 To do so, follow the instructions in the `./topology` folder.
 
@@ -41,7 +43,7 @@ To do so, follow the instructions in the `./topology` folder.
 
 To conduct this test, follow the steps below.
 
-### TFS re-deploy
+### Deploy TFS
 
 ```shell
 cd ~/tfs-ctrl/
@@ -67,7 +69,7 @@ The `./setup.sh` script copies from this directory. If you need to change the P4
 
 ## Tests
 
-The following tests are implemented.
+A set of tests is implemented, each focusing on different aspects of TFS.
 For each of these tests, an auxiliary bash script allows to run it with less typing.
 
 |                 Test                 |              Bash Runner           |                Purpose             |
@@ -80,7 +82,7 @@ For each of these tests, an auxiliary bash script allows to run it with less typ
 
 Each of the tests above is described in detail below.
 
-### Step 1: Copy the necessary P4 artifacts into the TFS SBI service pod
+### Step 0: Copy the necessary P4 artifacts into the TFS SBI service pod
 
 The setup script copies the necessary artifacts to the SBI service pod.
 It should be run just once, after a fresh install of TFS.
@@ -89,34 +91,33 @@ If you `deploy/all.sh` again, you need to repeat this step.
 ```shell
 cd ~/tfs-ctrl/
 source my_deploy.sh && source tfs_runtime_env_vars.sh
-bash src/tests/p4-int-routing-acl/setup.sh
+bash src/tests/p4-fabric-tna/setup.sh
 ```
 
-### Step 2: Bootstrap topology
+### Step 1: Bootstrap topology
 
 The bootstrap script registers the context, topology, links, and devices to TFS.
 
 ```shell
 cd ~/tfs-ctrl/
-bash src/tests/p4-int-routing-acl/run_test_01_bootstrap.sh
+bash src/tests/p4-fabric-tna/run_test_01_bootstrap.sh
 ```
 
-### Step 3: Provision rules via the SBI API
+### Step 2: Manage L2, L3, ACL, and INT via the SBI API (rules)
 
-Implement routing, ACL, and INT functions by installing P4 rules to the Stratum switch via the TFS SBI API.
+Implement forwarding, routing, ACL, and INT network functions by installing P4 rules to the Stratum switch via the TFS SBI API.
+In this test, these rules are installed in batches, as the switch cannot digest all these rules at once.
 
 ```shell
 cd ~/tfs-ctrl/
-bash src/tests/p4-int-routing-acl/run_test_02_rules_provision.sh
+bash src/tests/p4-fabric-tna/run_test_02a_sbi_provision_int_l2_l3_acl.sh
 ```
 
-### Step 4: Deprovision rules via the SBI API
-
-Deprovision the routing, ACL, and INT network functions by removing the previously installed P4 rules (via the TFS SBI API) from the Stratum switch.
+Deprovision forwarding, routing, ACL, and INT network functions by removing the previously installed P4 rules (via the TFS SBI API) from the Stratum switch.
 
 ```shell
 cd ~/tfs-ctrl/
-bash src/tests/p4-int-routing-acl/run_test_03_rules_deprovision.sh
+bash src/tests/p4-fabric-tna/run_test_02b_sbi_deprovision_int_l2_l3_acl.sh
 ```
 
 ### Step 4: Deprovision topology
@@ -125,5 +126,12 @@ Delete all the objects (context, topology, links, devices) from TFS:
 
 ```shell
 cd ~/tfs-ctrl/
-bash src/tests/p4-int-routing-acl/run_test_04_cleanup.sh
+bash src/tests/p4-fabric-tna/run_test_07_cleanup.sh
+```
+
+Alternatively, a purge test is implemented; this test removes services, links, devices, topology, and context in this order.
+
+```shell
+cd ~/tfs-ctrl/
+bash src/tests/p4-fabric-tna/run_test_08_purge.sh
 ```
diff --git a/src/tests/p4-int-routing-acl/__init__.py b/src/tests/p4-fabric-tna/__init__.py
similarity index 100%
rename from src/tests/p4-int-routing-acl/__init__.py
rename to src/tests/p4-fabric-tna/__init__.py
diff --git a/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-acl.json b/src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-acl.json
similarity index 100%
rename from src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-acl.json
rename to src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-acl.json
diff --git a/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b1.json b/src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-int-b1.json
similarity index 100%
rename from src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b1.json
rename to src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-int-b1.json
diff --git a/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b2.json b/src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-int-b2.json
similarity index 100%
rename from src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b2.json
rename to src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-int-b2.json
diff --git a/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b3.json b/src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-int-b3.json
similarity index 100%
rename from src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b3.json
rename to src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-int-b3.json
diff --git a/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-routing-corp.json b/src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-routing-corp.json
similarity index 100%
rename from src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-routing-corp.json
rename to src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-routing-corp.json
diff --git a/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-routing-edge.json b/src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-routing-edge.json
similarity index 100%
rename from src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-routing-edge.json
rename to src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-routing-edge.json
diff --git a/src/tests/p4-int-routing-acl/descriptors/sbi-rules-remove.json b/src/tests/p4-fabric-tna/descriptors/sbi-rules-remove.json
similarity index 100%
rename from src/tests/p4-int-routing-acl/descriptors/sbi-rules-remove.json
rename to src/tests/p4-fabric-tna/descriptors/sbi-rules-remove.json
diff --git a/src/tests/p4-int-routing-acl/descriptors/topology.json b/src/tests/p4-fabric-tna/descriptors/topology.json
similarity index 100%
rename from src/tests/p4-int-routing-acl/descriptors/topology.json
rename to src/tests/p4-fabric-tna/descriptors/topology.json
diff --git a/src/tests/p4-int-routing-acl/p4src/README.md b/src/tests/p4-fabric-tna/p4src/README.md
similarity index 100%
rename from src/tests/p4-int-routing-acl/p4src/README.md
rename to src/tests/p4-fabric-tna/p4src/README.md
diff --git a/src/tests/p4-int-routing-acl/p4src/_pp.p4 b/src/tests/p4-fabric-tna/p4src/_pp.p4
similarity index 100%
rename from src/tests/p4-int-routing-acl/p4src/_pp.p4
rename to src/tests/p4-fabric-tna/p4src/_pp.p4
diff --git a/src/tests/p4-int-routing-acl/p4src/bmv2.json b/src/tests/p4-fabric-tna/p4src/bmv2.json
similarity index 100%
rename from src/tests/p4-int-routing-acl/p4src/bmv2.json
rename to src/tests/p4-fabric-tna/p4src/bmv2.json
diff --git a/src/tests/p4-int-routing-acl/p4src/p4info.txt b/src/tests/p4-fabric-tna/p4src/p4info.txt
similarity index 100%
rename from src/tests/p4-int-routing-acl/p4src/p4info.txt
rename to src/tests/p4-fabric-tna/p4src/p4info.txt
diff --git a/src/tests/p4-int-routing-acl/run_test_01_bootstrap.sh b/src/tests/p4-fabric-tna/run_test_01_bootstrap.sh
similarity index 89%
rename from src/tests/p4-int-routing-acl/run_test_01_bootstrap.sh
rename to src/tests/p4-fabric-tna/run_test_01_bootstrap.sh
index 76469ca55..81d87476e 100755
--- a/src/tests/p4-int-routing-acl/run_test_01_bootstrap.sh
+++ b/src/tests/p4-fabric-tna/run_test_01_bootstrap.sh
@@ -18,4 +18,4 @@
 # - tfs_runtime_env_vars.sh
 
 source tfs_runtime_env_vars.sh
-python3 -m pytest --verbose src/tests/p4-int-routing-acl/test_functional_bootstrap.py
+python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-setup/test_functional_bootstrap.py
diff --git a/src/tests/p4-int-routing-acl/run_test_03_sbi_rules_deprovision.sh b/src/tests/p4-fabric-tna/run_test_02a_sbi_provision_int_l2_l3_acl.sh
similarity index 86%
rename from src/tests/p4-int-routing-acl/run_test_03_sbi_rules_deprovision.sh
rename to src/tests/p4-fabric-tna/run_test_02a_sbi_provision_int_l2_l3_acl.sh
index 4032c01df..a3ab51c22 100755
--- a/src/tests/p4-int-routing-acl/run_test_03_sbi_rules_deprovision.sh
+++ b/src/tests/p4-fabric-tna/run_test_02a_sbi_provision_int_l2_l3_acl.sh
@@ -14,4 +14,4 @@
 # limitations under the License.
 
 source tfs_runtime_env_vars.sh
-python3 -m pytest --verbose src/tests/p4-int-routing-acl/test_functional_sbi_rules_deprovision.py
+python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-sbi/test_functional_sbi_rules_provision.py
diff --git a/src/tests/p4-fabric-tna/run_test_02b_sbi_deprovision_int_l2_l3_acl.sh b/src/tests/p4-fabric-tna/run_test_02b_sbi_deprovision_int_l2_l3_acl.sh
new file mode 100755
index 000000000..49a686638
--- /dev/null
+++ b/src/tests/p4-fabric-tna/run_test_02b_sbi_deprovision_int_l2_l3_acl.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source tfs_runtime_env_vars.sh
+python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-sbi/test_functional_sbi_rules_deprovision.py
diff --git a/src/tests/p4-int-routing-acl/run_test_02_sbi_rules_provision.sh b/src/tests/p4-fabric-tna/run_test_07_cleanup.sh
similarity index 87%
rename from src/tests/p4-int-routing-acl/run_test_02_sbi_rules_provision.sh
rename to src/tests/p4-fabric-tna/run_test_07_cleanup.sh
index 7c485d401..c7b829168 100755
--- a/src/tests/p4-int-routing-acl/run_test_02_sbi_rules_provision.sh
+++ b/src/tests/p4-fabric-tna/run_test_07_cleanup.sh
@@ -14,4 +14,4 @@
 # limitations under the License.
 
 source tfs_runtime_env_vars.sh
-python3 -m pytest --verbose src/tests/p4-int-routing-acl/test_functional_sbi_rules_provision.py
+python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-setup/test_functional_cleanup.py
diff --git a/src/tests/p4-int-routing-acl/run_test_06_cleanup.sh b/src/tests/p4-fabric-tna/run_test_08_purge.sh
similarity index 88%
rename from src/tests/p4-int-routing-acl/run_test_06_cleanup.sh
rename to src/tests/p4-fabric-tna/run_test_08_purge.sh
index 917a2af2d..9aef079f1 100755
--- a/src/tests/p4-int-routing-acl/run_test_06_cleanup.sh
+++ b/src/tests/p4-fabric-tna/run_test_08_purge.sh
@@ -14,4 +14,4 @@
 # limitations under the License.
 
 source tfs_runtime_env_vars.sh
-python3 -m pytest --verbose src/tests/p4-int-routing-acl/test_functional_cleanup.py
+python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-setup/test_functional_purge.py
diff --git a/src/tests/p4-int-routing-acl/setup.sh b/src/tests/p4-fabric-tna/setup.sh
similarity index 80%
rename from src/tests/p4-int-routing-acl/setup.sh
rename to src/tests/p4-fabric-tna/setup.sh
index c77164276..9418ac3d7 100755
--- a/src/tests/p4-int-routing-acl/setup.sh
+++ b/src/tests/p4-fabric-tna/setup.sh
@@ -18,5 +18,5 @@ export POD_NAME=$(kubectl get pods -n=tfs | grep device | awk '{print $1}')
 
 kubectl exec ${POD_NAME} -n=tfs -c=server -- mkdir -p /root/p4
 
-kubectl cp src/tests/p4-int-routing-acl/p4src/p4info.txt tfs/${POD_NAME}:/root/p4 -c=server
-kubectl cp src/tests/p4-int-routing-acl/p4src/bmv2.json tfs/${POD_NAME}:/root/p4 -c=server
+kubectl cp src/tests/p4-fabric-tna/p4src/p4info.txt tfs/${POD_NAME}:/root/p4 -c=server
+kubectl cp src/tests/p4-fabric-tna/p4src/bmv2.json tfs/${POD_NAME}:/root/p4 -c=server
diff --git a/src/tests/p4-int-routing-acl/test_functional_sbi_rules_deprovision.py b/src/tests/p4-fabric-tna/tests-sbi/test_functional_sbi_rules_deprovision.py
similarity index 99%
rename from src/tests/p4-int-routing-acl/test_functional_sbi_rules_deprovision.py
rename to src/tests/p4-fabric-tna/tests-sbi/test_functional_sbi_rules_deprovision.py
index 2d54ae908..6d5f7dfd2 100644
--- a/src/tests/p4-int-routing-acl/test_functional_sbi_rules_deprovision.py
+++ b/src/tests/p4-fabric-tna/tests-sbi/test_functional_sbi_rules_deprovision.py
@@ -18,7 +18,7 @@ from common.tools.grpc.Tools import grpc_message_to_json_string
 from context.client.ContextClient import ContextClient
 from device.client.DeviceClient import DeviceClient
 from tests.Fixtures import context_client, device_client   # pylint: disable=unused-import
-from test_common import *
+from tests.tools.test_tools_p4 import *
 
 LOGGER = logging.getLogger(__name__)
 LOGGER.setLevel(logging.DEBUG)
diff --git a/src/tests/p4-int-routing-acl/test_functional_sbi_rules_provision.py b/src/tests/p4-fabric-tna/tests-sbi/test_functional_sbi_rules_provision.py
similarity index 99%
rename from src/tests/p4-int-routing-acl/test_functional_sbi_rules_provision.py
rename to src/tests/p4-fabric-tna/tests-sbi/test_functional_sbi_rules_provision.py
index 86a82d212..49d9aba4d 100644
--- a/src/tests/p4-int-routing-acl/test_functional_sbi_rules_provision.py
+++ b/src/tests/p4-fabric-tna/tests-sbi/test_functional_sbi_rules_provision.py
@@ -18,7 +18,7 @@ from common.tools.grpc.Tools import grpc_message_to_json_string
 from context.client.ContextClient import ContextClient
 from device.client.DeviceClient import DeviceClient
 from tests.Fixtures import context_client, device_client # pylint: disable=unused-import
-from test_common import *
+from tests.tools.test_tools_p4 import *
 
 LOGGER = logging.getLogger(__name__)
 LOGGER.setLevel(logging.DEBUG)
diff --git a/src/tests/p4-int-routing-acl/test_functional_bootstrap.py b/src/tests/p4-fabric-tna/tests-setup/test_functional_bootstrap.py
similarity index 98%
rename from src/tests/p4-int-routing-acl/test_functional_bootstrap.py
rename to src/tests/p4-fabric-tna/tests-setup/test_functional_bootstrap.py
index b5b72cc33..2f9130ad0 100644
--- a/src/tests/p4-int-routing-acl/test_functional_bootstrap.py
+++ b/src/tests/p4-fabric-tna/tests-setup/test_functional_bootstrap.py
@@ -19,7 +19,7 @@ from common.tools.descriptor.Loader import DescriptorLoader, \
 from context.client.ContextClient import ContextClient
 from device.client.DeviceClient import DeviceClient
 from tests.Fixtures import context_client, device_client # pylint: disable=unused-import
-from test_common import *
+from tests.tools.test_tools_p4 import *
 
 LOGGER = logging.getLogger(__name__)
 LOGGER.setLevel(logging.DEBUG)
diff --git a/src/tests/p4-int-routing-acl/test_functional_cleanup.py b/src/tests/p4-fabric-tna/tests-setup/test_functional_cleanup.py
similarity index 94%
rename from src/tests/p4-int-routing-acl/test_functional_cleanup.py
rename to src/tests/p4-fabric-tna/tests-setup/test_functional_cleanup.py
index fc29be24d..4d98c9e05 100644
--- a/src/tests/p4-int-routing-acl/test_functional_cleanup.py
+++ b/src/tests/p4-fabric-tna/tests-setup/test_functional_cleanup.py
@@ -12,13 +12,12 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import logging, os
-from common.Constants import DEFAULT_CONTEXT_NAME
+import logging
 from common.tools.descriptor.Loader import DescriptorLoader, validate_empty_scenario
 from context.client.ContextClient import ContextClient
 from device.client.DeviceClient import DeviceClient
 from tests.Fixtures import context_client, device_client # pylint: disable=unused-import
-from test_common import *
+from tests.tools.test_tools_p4 import *
 
 LOGGER = logging.getLogger(__name__)
 LOGGER.setLevel(logging.DEBUG)
diff --git a/src/tests/p4-fabric-tna/tests-setup/test_functional_purge.py b/src/tests/p4-fabric-tna/tests-setup/test_functional_purge.py
new file mode 100644
index 000000000..ba37fbd89
--- /dev/null
+++ b/src/tests/p4-fabric-tna/tests-setup/test_functional_purge.py
@@ -0,0 +1,81 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+from common.proto.context_pb2 import ServiceId, DeviceId, LinkId, ServiceStatusEnum, ServiceTypeEnum
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from common.tools.object_factory.Service import json_service_id
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from service.client.ServiceClient import ServiceClient
+from tests.Fixtures import context_client, device_client, service_client # pylint: disable=unused-import
+from tests.tools.test_tools_p4 import *
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+def test_clean_services(
+    context_client : ContextClient,  # pylint: disable=redefined-outer-name
+    service_client : ServiceClient  # pylint: disable=redefined-outer-name
+) -> None:
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    LOGGER.warning('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response)))
+    
+    for service in response.services:
+        service_id = service.service_id
+        assert service_id
+
+        service_uuid = service_id.service_uuid.uuid
+        context_uuid = service_id.context_id.context_uuid.uuid
+        assert service.service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE
+        assert service.service_type == ServiceTypeEnum.SERVICETYPE_INT
+
+        # Delete service
+        service_client.DeleteService(ServiceId(**json_service_id(service_uuid, json_context_id(context_uuid))))
+
+def test_clean_links(
+    context_client : ContextClient,  # pylint: disable=redefined-outer-name
+) -> None:
+    response = context_client.ListLinks(ADMIN_CONTEXT_ID)
+    
+    for link in response.links:
+        link_id = link.link_id
+
+        # Delete link
+        context_client.RemoveLink(LinkId(**link_id))
+
+def test_clean_devices(
+    context_client : ContextClient,  # pylint: disable=redefined-outer-name
+    device_client : DeviceClient   # pylint: disable=redefined-outer-name
+) -> None:
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    LOGGER.warning('Devices[{:d}] = {:s}'.format(len(response.devices), grpc_message_to_json_string(response)))
+    
+    for device in response.devices:
+        device_id = device.device_id
+
+        # Delete device
+        device_client.DeleteDevice(DeviceId(**device_id))
+
+def test_clean_context(
+    context_client : ContextClient  # pylint: disable=redefined-outer-name
+) -> None:
+    # Verify the scenario has no services/slices
+    response = context_client.ListTopologies(ADMIN_CONTEXT_ID)
+
+    for topology in response.topologies:
+        topology_id = topology.topology_id
+        response = context_client.RemoveTopology(topology_id)
+
+    response = context_client.RemoveContext(ADMIN_CONTEXT_ID)
diff --git a/src/tests/p4-int-routing-acl/topology/README.md b/src/tests/p4-fabric-tna/topology/README.md
similarity index 100%
rename from src/tests/p4-int-routing-acl/topology/README.md
rename to src/tests/p4-fabric-tna/topology/README.md
diff --git a/src/tests/p4-int-routing-acl/topology/p4-switch-conf-common.sh b/src/tests/p4-fabric-tna/topology/p4-switch-conf-common.sh
similarity index 100%
rename from src/tests/p4-int-routing-acl/topology/p4-switch-conf-common.sh
rename to src/tests/p4-fabric-tna/topology/p4-switch-conf-common.sh
diff --git a/src/tests/p4-int-routing-acl/topology/p4-switch-setup.sh b/src/tests/p4-fabric-tna/topology/p4-switch-setup.sh
similarity index 100%
rename from src/tests/p4-int-routing-acl/topology/p4-switch-setup.sh
rename to src/tests/p4-fabric-tna/topology/p4-switch-setup.sh
diff --git a/src/tests/p4-int-routing-acl/topology/p4-switch-tear-down.sh b/src/tests/p4-fabric-tna/topology/p4-switch-tear-down.sh
similarity index 100%
rename from src/tests/p4-int-routing-acl/topology/p4-switch-tear-down.sh
rename to src/tests/p4-fabric-tna/topology/p4-switch-tear-down.sh
diff --git a/src/tests/p4-int-routing-acl/topology/p4-switch-three-port-chassis-config-phy.pb.txt b/src/tests/p4-fabric-tna/topology/p4-switch-three-port-chassis-config-phy.pb.txt
similarity index 100%
rename from src/tests/p4-int-routing-acl/topology/p4-switch-three-port-chassis-config-phy.pb.txt
rename to src/tests/p4-fabric-tna/topology/p4-switch-three-port-chassis-config-phy.pb.txt
diff --git a/src/tests/p4-int-routing-acl/topology/run-stratum.sh b/src/tests/p4-fabric-tna/topology/run-stratum.sh
similarity index 100%
rename from src/tests/p4-int-routing-acl/topology/run-stratum.sh
rename to src/tests/p4-fabric-tna/topology/run-stratum.sh
diff --git a/src/tests/p4-int-routing-acl/test_common.py b/src/tests/p4-int-routing-acl/test_common.py
deleted file mode 100644
index f2d00f1dc..000000000
--- a/src/tests/p4-int-routing-acl/test_common.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-from common.Constants import DEFAULT_CONTEXT_NAME
-from common.proto.context_pb2 import ContextId, DeviceOperationalStatusEnum
-from common.tools.object_factory.Context import json_context_id
-
-# Context info
-CONTEXT_NAME_P4 = DEFAULT_CONTEXT_NAME
-ADMIN_CONTEXT_ID = ContextId(**json_context_id(CONTEXT_NAME_P4))
-
-# Device and rule cardinality variables
-DEV_NB = 4
-CONNECTION_RULES = 3
-ENDPOINT_RULES = 3
-DATAPLANE_RULES_NB_INT_B1 = 5
-DATAPLANE_RULES_NB_INT_B2 = 6
-DATAPLANE_RULES_NB_INT_B3 = 8
-DATAPLANE_RULES_NB_RT_EDGE = 7
-DATAPLANE_RULES_NB_RT_CORP = 7
-DATAPLANE_RULES_NB_ACL = 1
-DATAPLANE_RULES_NB_TOT = \
-    DATAPLANE_RULES_NB_INT_B1 +\
-    DATAPLANE_RULES_NB_INT_B2 +\
-    DATAPLANE_RULES_NB_INT_B3 +\
-    DATAPLANE_RULES_NB_RT_EDGE +\
-    DATAPLANE_RULES_NB_RT_CORP +\
-    DATAPLANE_RULES_NB_ACL
-
-# Service-related variables
-SVC_NB = 1
-NO_SERVICES = 0
-NO_SLICES = 0
-
-# Topology descriptor
-DESC_TOPO = os.path.join(
-    os.path.dirname(
-        os.path.abspath(__file__)
-    ),
-    'descriptors', 'topology.json'
-)
-
-# SBI rule insertion descriptors
-# The switch cannot digest all rules at once, hence we insert in batches
-DESC_FILE_RULES_INSERT_INT_B1 = os.path.join(
-    os.path.dirname(
-        os.path.abspath(__file__)
-    ),
-    'descriptors', 'sbi-rules-insert-int-b1.json'
-)
-DESC_FILE_RULES_INSERT_INT_B2 = os.path.join(
-    os.path.dirname(
-        os.path.abspath(__file__)
-    ),
-    'descriptors', 'sbi-rules-insert-int-b2.json'
-)
-DESC_FILE_RULES_INSERT_INT_B3 = os.path.join(
-    os.path.dirname(
-        os.path.abspath(__file__)
-    ),
-    'descriptors', 'sbi-rules-insert-int-b3.json'
-)
-DESC_FILE_RULES_INSERT_ROUTING_EDGE = os.path.join(
-    os.path.dirname(
-        os.path.abspath(__file__)
-    ),
-    'descriptors', 'sbi-rules-insert-routing-edge.json'
-)
-DESC_FILE_RULES_INSERT_ROUTING_CORP = os.path.join(
-    os.path.dirname(
-        os.path.abspath(__file__)
-    ),
-    'descriptors', 'sbi-rules-insert-routing-corp.json'
-)
-DESC_FILE_RULES_INSERT_ACL = os.path.join(
-    os.path.dirname(
-        os.path.abspath(__file__)
-    ),
-    'descriptors', 'sbi-rules-insert-acl.json'
-)
-
-# SBI rule deletion descriptor
-DESC_FILE_RULES_DELETE_ALL = os.path.join(
-    os.path.dirname(
-        os.path.abspath(__file__)
-    ),
-    'descriptors', 'sbi-rules-remove.json'
-)
-
-def verify_number_of_rules(devices, desired_rules_nb):
-    # Iterate all devices
-    for device in devices:
-        # Skip non-P4 devices
-        if device.device_type != "p4-switch": continue
-
-        # We want the device to be active
-        assert \
-            device.device_operational_status == DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
-
-        # Get the configuration rules of this device
-        config_rules = device.device_config.config_rules
-
-        # Expected rule cardinality
-        assert len(config_rules) == desired_rules_nb
diff --git a/src/tests/tools/test_tools_p4.py b/src/tests/tools/test_tools_p4.py
new file mode 100644
index 000000000..4557fef61
--- /dev/null
+++ b/src/tests/tools/test_tools_p4.py
@@ -0,0 +1,172 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+from common.Constants import DEFAULT_CONTEXT_NAME
+from common.proto.context_pb2 import ContextId, DeviceOperationalStatusEnum,\
+    DeviceDriverEnum, ServiceTypeEnum, ServiceStatusEnum
+from common.tools.object_factory.Context import json_context_id
+
+# Context info
+CONTEXT_NAME_P4 = DEFAULT_CONTEXT_NAME
+ADMIN_CONTEXT_ID = ContextId(**json_context_id(CONTEXT_NAME_P4))
+
+# Device and rule cardinality variables
+DEV_NB = 4
+P4_DEV_NB = 1
+CONNECTION_RULES = 3
+ENDPOINT_RULES = 3
+INT_RULES = 19
+L2_RULES = 8
+L3_RULES = 8
+ACL_RULES = 1
+
+DATAPLANE_RULES_NB_INT_B1 = 5
+DATAPLANE_RULES_NB_INT_B2 = 6
+DATAPLANE_RULES_NB_INT_B3 = 8
+DATAPLANE_RULES_NB_RT_EDGE = 7
+DATAPLANE_RULES_NB_RT_CORP = 7
+DATAPLANE_RULES_NB_ACL = 1
+DATAPLANE_RULES_NB_TOT = \
+    DATAPLANE_RULES_NB_INT_B1 +\
+    DATAPLANE_RULES_NB_INT_B2 +\
+    DATAPLANE_RULES_NB_INT_B3 +\
+    DATAPLANE_RULES_NB_RT_EDGE +\
+    DATAPLANE_RULES_NB_RT_CORP +\
+    DATAPLANE_RULES_NB_ACL
+
+# Service-related variables
+SVC_NB = 1
+NO_SERVICES = 0
+NO_SLICES = 0
+
+TEST_PATH = os.path.join(
+    os.path.dirname(os.path.dirname(
+        os.path.abspath(__file__)
+    )) + '/p4-fabric-tna/descriptors')
+assert os.path.exists(TEST_PATH), "Invalid path to P4 SD-Fabric tests"
+
+# Topology descriptor
+DESC_TOPO = os.path.join(TEST_PATH, 'topology.json')
+assert os.path.exists(DESC_TOPO), "Invalid path to the SD-Fabric topology descriptor"
+
+# SBI descriptors
+# The switch cannot digest all rules at once, hence we insert in batches
+DESC_FILE_RULES_INSERT_INT_B1 = os.path.join(TEST_PATH, 'sbi-rules-insert-int-b1.json')
+assert os.path.exists(DESC_FILE_RULES_INSERT_INT_B1),\
+    "Invalid path to the SD-Fabric INT SBI descriptor (batch #1)"
+
+DESC_FILE_RULES_INSERT_INT_B2 = os.path.join(TEST_PATH, 'sbi-rules-insert-int-b2.json')
+assert os.path.exists(DESC_FILE_RULES_INSERT_INT_B2),\
+    "Invalid path to the SD-Fabric INT SBI descriptor (batch #2)"
+
+DESC_FILE_RULES_INSERT_INT_B3 = os.path.join(TEST_PATH, 'sbi-rules-insert-int-b3.json')
+assert os.path.exists(DESC_FILE_RULES_INSERT_INT_B3),\
+    "Invalid path to the SD-Fabric INT SBI descriptor (batch #3)"
+
+DESC_FILE_RULES_INSERT_ROUTING_EDGE = os.path.join(TEST_PATH, 'sbi-rules-insert-routing-edge.json')
+assert os.path.exists(DESC_FILE_RULES_INSERT_ROUTING_EDGE),\
+    "Invalid path to the SD-Fabric routing SBI descriptor (domain1-side)"
+
+DESC_FILE_RULES_INSERT_ROUTING_CORP = os.path.join(TEST_PATH, 'sbi-rules-insert-routing-corp.json')
+assert os.path.exists(DESC_FILE_RULES_INSERT_ROUTING_CORP),\
+    "Invalid path to the SD-Fabric routing SBI descriptor (domain2-side)"
+
+DESC_FILE_RULES_INSERT_ACL = os.path.join(TEST_PATH, 'sbi-rules-insert-acl.json')
+assert os.path.exists(DESC_FILE_RULES_INSERT_ACL),\
+    "Invalid path to the SD-Fabric ACL SBI descriptor"
+
+DESC_FILE_RULES_DELETE_ALL = os.path.join(TEST_PATH, 'sbi-rules-remove.json')
+assert os.path.exists(DESC_FILE_RULES_DELETE_ALL),\
+    "Invalid path to the SD-Fabric rule removal SBI descriptor"
+
+# Service descriptors
+DESC_FILE_SERVICE_CREATE_INT = os.path.join(TEST_PATH, 'service-create-int.json')
+assert os.path.exists(DESC_FILE_SERVICE_CREATE_INT),\
+    "Invalid path to the SD-Fabric INT service descriptor"
+
+DESC_FILE_SERVICE_CREATE_L2 = os.path.join(TEST_PATH, 'service-create-l2.json')
+assert os.path.exists(DESC_FILE_SERVICE_CREATE_L2),\
+    "Invalid path to the SD-Fabric L2 service descriptor"
+
+DESC_FILE_SERVICE_CREATE_L3 = os.path.join(TEST_PATH, 'service-create-l3.json')
+assert os.path.exists(DESC_FILE_SERVICE_CREATE_L3),\
+    "Invalid path to the SD-Fabric L3 service descriptor"
+
+DESC_FILE_SERVICE_CREATE_ACL = os.path.join(TEST_PATH, 'service-create-acl.json')
+assert os.path.exists(DESC_FILE_SERVICE_CREATE_ACL),\
+    "Invalid path to the SD-Fabric ACL service descriptor"
+
+def identify_number_of_p4_devices(devices) -> int:
+    p4_dev_no = 0
+
+    # Iterate all devices
+    for device in devices:
+        # Skip non-P4 devices
+        if not DeviceDriverEnum.DEVICEDRIVER_P4 in device.device_drivers: continue
+
+        p4_dev_no += 1
+    
+    return p4_dev_no
+
+def get_number_of_rules(devices) -> int:
+    total_rules_no = 0
+
+    # Iterate all devices
+    for device in devices:
+        # Skip non-P4 devices
+        if not DeviceDriverEnum.DEVICEDRIVER_P4 in device.device_drivers: continue
+
+        # We want the device to be active
+        assert device.device_operational_status == \
+            DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
+
+        # Get the configuration rules of this device
+        config_rules = device.device_config.config_rules
+
+        # Expected rule cardinality
+        total_rules_no += len(config_rules)
+    
+    return total_rules_no
+
+def verify_number_of_rules(devices, desired_rules_nb : int) -> None:
+    # Iterate all devices
+    for device in devices:
+        # Skip non-P4 devices
+        if not DeviceDriverEnum.DEVICEDRIVER_P4 in device.device_drivers: continue
+
+        # We want the device to be active
+        assert device.device_operational_status == \
+            DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
+
+        # Get the configuration rules of this device
+        config_rules = device.device_config.config_rules
+
+        # Expected rule cardinality
+        assert len(config_rules) == desired_rules_nb
+
+def verify_active_service_type(services, target_service_type : ServiceTypeEnum) -> bool: # type: ignore
+    # Iterate all services
+    for service in services:
+        # Ignore services of other types
+        if service.service_type != target_service_type:
+            continue
+
+        service_id = service.service_id
+        assert service_id
+        assert service.service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE
+        assert service.service_config
+        return True
+    
+    return False
-- 
GitLab


From 578f87b930361b7589ab6e3747b1a7de65caed0e Mon Sep 17 00:00:00 2001
From: "Georgios P. Katsikas" <gkatsikas@ubitech.eu>
Date: Sat, 22 Mar 2025 08:20:56 +0000
Subject: [PATCH 03/14] feat: common service library for the SD-Fabric P4
 dataplane

---
 .../p4_fabric_tna_commons.py                  | 908 ++++++++++++++++++
 1 file changed, 908 insertions(+)
 create mode 100644 src/service/service/service_handlers/p4_fabric_tna_commons/p4_fabric_tna_commons.py

diff --git a/src/service/service/service_handlers/p4_fabric_tna_commons/p4_fabric_tna_commons.py b/src/service/service/service_handlers/p4_fabric_tna_commons/p4_fabric_tna_commons.py
new file mode 100644
index 000000000..eb8077ff3
--- /dev/null
+++ b/src/service/service/service_handlers/p4_fabric_tna_commons/p4_fabric_tna_commons.py
@@ -0,0 +1,908 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Common objects and methods for the SD-Fabric (fabric TNA) dataplane.
+This dataplane covers both software based and hardware-based Stratum-enabled P4 switches,
+such as the BMv2 software switch and Intel's Tofino/Tofino-2 switches.
+
+SD-Fabric repo: https://github.com/stratum/fabric-tna
+SD-Fabric docs: https://docs.sd-fabric.org/master/index.html
+"""
+
+import time
+import logging
+import struct
+from common.proto.context_pb2 import ConfigActionEnum, ConfigRule
+from common.tools.object_factory.ConfigRule import json_config_rule
+from common.type_checkers.Checkers import chk_address_mac, chk_vlan_id, \
+    chk_address_ipv4, chk_transport_port
+from random import randint
+from typing import List, Tuple
+
+LOGGER = logging.getLogger(__name__)
+
+# Common service handler settings
+TARGET_P4_ARCH = "target_p4_arch"
+SWITCH_DATAPLANE_ID_MAP = "switch_dataplane_id_map"
+VLAN_ID = "vlan_id"
+
+# P4 architectures
+TARGET_ARCH_TNA = "tna"
+TARGET_ARCH_V1MODEL = "v1model"
+SUPPORTED_TARGET_ARCH_LIST = [TARGET_ARCH_TNA, TARGET_ARCH_V1MODEL]
+
+# Recirculation ports for various targets
+RECIRCULATION_PORTS_TNA = [68, 196, 324, 452]    # Tofino-2 (2-pipe switches use only the first 2 entries)
+RECIRCULATION_PORTS_V1MODEL = [510]              # Variable FAKE_V1MODEL_RECIRC_PORT in p4 source program
+
+# P4 tables
+TABLE_INGRESS_VLAN = "FabricIngress.filtering.ingress_port_vlan"
+TABLE_EGRESS_VLAN = "FabricEgress.egress_next.egress_vlan"
+TABLE_FWD_CLASSIFIER = "FabricIngress.filtering.fwd_classifier"
+TABLE_BRIDGING = "FabricIngress.forwarding.bridging"
+TABLE_ROUTING_V4 = "FabricIngress.forwarding.routing_v4"
+TABLE_NEXT_SIMPLE = "FabricIngress.next.simple"
+TABLE_NEXT_HASHED = "FabricIngress.next.hashed"
+TABLE_ACL = "FabricIngress.acl.acl"
+
+# Action profile members
+ACTION_PROFILE_NEXT_HASHED = "FabricIngress.next.hashed_profile"
+
+# Clone sessions
+CLONE_SESSION = "/clone_sessions/clone_session"
+
+# Forwarding types
+FORWARDING_TYPE_BRIDGING = 0
+FORWARDING_TYPE_MPLS = 1
+FORWARDING_TYPE_UNICAST_IPV4 = 2
+FORWARDING_TYPE_IPV4_MULTICAST = 3
+FORWARDING_TYPE_IPV6_UNICAST = 4
+FORWARDING_TYPE_IPV6_MULTICAST = 5
+FORWARDING_TYPE_UNKNOWN = 7
+
+FORWARDING_TYPES_VALID = [
+    FORWARDING_TYPE_BRIDGING,
+    FORWARDING_TYPE_MPLS,
+    FORWARDING_TYPE_UNICAST_IPV4,
+    FORWARDING_TYPE_IPV4_MULTICAST,
+    FORWARDING_TYPE_IPV6_UNICAST,
+    FORWARDING_TYPE_IPV6_MULTICAST,
+    FORWARDING_TYPE_UNKNOWN
+]
+
+# Port types
+PORT_TYPE_INT = "int"
+PORT_TYPE_HOST = "host"
+PORT_TYPE_SWITCH = "switch"
+
+PORT_TYPE_ACTION_EDGE = 1
+PORT_TYPE_ACTION_INFRA = 2
+PORT_TYPE_ACTION_INTERNAL = 3
+
+PORT_TYPE_MAP = {
+    PORT_TYPE_INT: PORT_TYPE_ACTION_INTERNAL,
+    PORT_TYPE_HOST: PORT_TYPE_ACTION_EDGE,
+    PORT_TYPE_SWITCH: PORT_TYPE_ACTION_INFRA
+}
+
+PORT_TYPES_STR_VALID = [PORT_TYPE_INT, PORT_TYPE_HOST, PORT_TYPE_SWITCH]
+PORT_TYPES_INT_VALID = [PORT_TYPE_ACTION_EDGE, PORT_TYPE_ACTION_INFRA, PORT_TYPE_ACTION_INTERNAL]
+
+# Bridged metadata type
+BRIDGED_MD_TYPE_EGRESS_MIRROR = 2
+BRIDGED_MD_TYPE_INGRESS_MIRROR = 3
+BRIDGED_MD_TYPE_INT_INGRESS_DROP = 4
+BRIDGED_MD_TYPE_DEFLECTED = 5
+
+# Mirror types
+MIRROR_TYPE_INVALID = 0
+MIRROR_TYPE_INT_REPORT = 1
+
+# VLAN
+VLAN_DEF = 4094
+
+# Supported Ethernet types
+ETHER_TYPE_IPV4 = "0x0800"
+ETHER_TYPE_IPV6 = "0x86DD"
+
+# Member ID
+NEXT_MEMBER_ID = 1
+
+# Time interval in seconds for consecutive rule management (insert/delete) operations
+RULE_CONF_INTERVAL_SEC = 0.1
+
+################################################################################################################
+### Miscellaneous methods
+################################################################################################################
+
+def arch_tna(arch : str) -> bool:
+    return arch == TARGET_ARCH_TNA
+    
+def arch_v1model(arch : str) -> bool:
+    return not arch_tna(arch)
+
+def generate_random_mac() -> str:
+    mac = [randint(0x00, 0xff)] * 6
+    mac_str = ':'.join(map(lambda x: "%02x" % x, mac))
+    chk_address_mac(mac_str), "Invalid MAC address generated"
+
+    return mac_str
+
+def prefix_to_hex_mask(prefix_len):
+    # Calculate the binary mask
+    binary_mask = (1 << 32) - (1 << (32 - prefix_len))
+    
+    # Convert the binary mask to the 4 octets (32 bits)
+    mask = struct.pack('!I', binary_mask)
+    
+    # Convert to a string of hex values
+    hex_mask = ''.join(f'{byte:02x}' for byte in mask)
+    
+    return "0x"+hex_mask.upper()
+
+def sleep_for(time_sec : int) -> None:
+    assert time_sec > 0, "Invalid sleep period in seconds"
+    time.sleep(time_sec)
+
+################################################################################################################
+### Rule generation methods
+################################################################################################################
+
+###################################
+### A. Port setup
+###################################
+
+def rules_set_up_port_ingress(
+        ingress_port : int,
+        port_type : str,
+        vlan_id: int,
+        action : ConfigActionEnum) -> List [Tuple]: # type: ignore
+    assert ingress_port >= 0, "Invalid ingress port to configure ingress port"
+    assert port_type.lower() in PORT_TYPES_STR_VALID, "Invalid port type to configure ingress port"
+    assert chk_vlan_id(vlan_id), "Invalid VLAN ID to configure ingress port"
+    
+    rule_no = cache_rule(TABLE_INGRESS_VLAN, action)
+
+    port_type_int = PORT_TYPE_MAP[port_type.lower()]
+    assert port_type_int in PORT_TYPES_INT_VALID, "Invalid port type to configure ingress filtering"
+
+    rules_filtering_vlan_ingress = []
+    rules_filtering_vlan_ingress.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_INGRESS_VLAN+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_INGRESS_VLAN,
+                'match-fields': [
+                    {
+                        'match-field': 'ig_port',
+                        'match-value': str(ingress_port)
+                    },
+                    {
+                        'match-field': 'vlan_is_valid',
+                        'match-value': '0'
+                    }
+                ],
+                'action-name': 'FabricIngress.filtering.permit_with_internal_vlan',
+                'action-params': [
+                    {
+                        'action-param': 'port_type',
+                        'action-value': str(port_type_int)
+                    },
+                    {
+                        'action-param': 'vlan_id',
+                        'action-value': str(vlan_id)
+                    }
+                ],
+                'priority': 10
+            }
+        )
+    )
+
+    return rules_filtering_vlan_ingress
+
+def rules_set_up_port_egress(
+        egress_port : int,
+        vlan_id: int,
+        action : ConfigActionEnum) -> List [Tuple]: # type: ignore
+    assert egress_port >= 0, "Invalid egress port to configure egress vlan"
+    assert chk_vlan_id(vlan_id), "Invalid VLAN ID to configure egress vlan"
+
+    rule_no = cache_rule(TABLE_EGRESS_VLAN, action)
+
+    rules_vlan_egress = []
+    rules_vlan_egress.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_EGRESS_VLAN+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_EGRESS_VLAN,
+                'match-fields': [
+                    {
+                        'match-field': 'eg_port',
+                        'match-value': str(egress_port)
+                    },
+                    {
+                        'match-field': 'vlan_id',
+                        'match-value': str(vlan_id)
+                    }
+                ],
+                'action-name': 'FabricEgress.egress_next.pop_vlan',
+                'action-params': []
+            }
+        )
+    )
+
+    return rules_vlan_egress
+
+def rules_set_up_fwd_classifier(
+        ingress_port : int,
+        fwd_type : int,
+        eth_type: str,
+        action : ConfigActionEnum) -> List [Tuple]: # type: ignore
+    assert ingress_port >= 0, "Invalid ingress port to configure forwarding classifier"
+    assert fwd_type in FORWARDING_TYPES_VALID, "Invalid forwarding type to configure forwarding classifier"
+
+    rule_no = cache_rule(TABLE_FWD_CLASSIFIER, action)
+
+    rules_filtering_fwd_classifier = []
+    rules_filtering_fwd_classifier.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_FWD_CLASSIFIER+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_FWD_CLASSIFIER,
+                'match-fields': [
+                    {
+                        'match-field': 'ig_port',
+                        'match-value': str(ingress_port)
+                    },
+                    {
+                        'match-field': 'eth_type',
+                        'match-value': eth_type
+                    }
+                ],
+                'action-name': 'FabricIngress.filtering.set_forwarding_type',
+                'action-params': [
+                    {
+                        'action-param': 'fwd_type',
+                        'action-value': str(FORWARDING_TYPE_UNICAST_IPV4)
+                    },
+                ],
+                'priority': 10
+            }
+        )
+    )
+
+    return rules_filtering_fwd_classifier
+
+def rules_set_up_port(
+        port : int,
+        port_type : str,
+        fwd_type : int,
+        vlan_id : int,
+        action : ConfigActionEnum, # type: ignore
+        eth_type=ETHER_TYPE_IPV4):
+    rules_list = []
+
+    rules_list.extend(
+        rules_set_up_port_ingress(
+            ingress_port=port,
+            port_type=port_type,
+            vlan_id=vlan_id,
+            action=action
+        )
+    )
+    rules_list.extend(
+        rules_set_up_fwd_classifier(
+            ingress_port=port,
+            fwd_type=fwd_type,
+            eth_type=eth_type,
+            action=action
+        )
+    )
+    rules_list.extend(
+        rules_set_up_port_egress(
+            egress_port=port,
+            vlan_id=vlan_id,
+            action=action
+        )
+    )
+    LOGGER.debug("Port configured:{}".format(port))
+
+    return rules_list
+
+###################################
+### A. End of port setup
+###################################
+
+
+###################################
+### B. L2 setup
+###################################
+
+def rules_set_up_fwd_bridging(
+        vlan_id: int,
+        eth_dst : str,
+        egress_port : int,
+        action : ConfigActionEnum) -> List [Tuple]: # type: ignore
+    assert chk_vlan_id(vlan_id), "Invalid VLAN ID to configure bridging"
+    assert chk_address_mac(eth_dst), "Invalid destination Ethernet address to configure bridging"
+    assert egress_port >= 0, "Invalid outport to configure bridging"
+
+    rule_no = cache_rule(TABLE_BRIDGING, action)
+
+    rules_fwd_bridging = []
+    rules_fwd_bridging.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_BRIDGING+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_BRIDGING,
+                'match-fields': [
+                    {
+                        'match-field': 'vlan_id',
+                        'match-value': str(vlan_id)
+                    },
+                    {
+                        'match-field': 'eth_dst',
+                        'match-value': eth_dst
+                    }
+                ],
+                'action-name': 'FabricIngress.forwarding.set_next_id_bridging',
+                'action-params': [
+                    {
+                        'action-param': 'next_id',
+                        'action-value': str(egress_port)
+                    }
+                ],
+                'priority': 1
+            }
+        )
+    )
+
+    return rules_fwd_bridging
+
+def rules_set_up_next_output_simple(
+        egress_port : int,
+        eth_src : str,
+        eth_dst : str,
+        action : ConfigActionEnum) -> List [Tuple]: # type: ignore
+    assert egress_port >= 0, "Invalid outport to configure next output simple"
+    assert chk_address_mac(eth_src), "Invalid source Ethernet address to configure next output simple"
+    assert chk_address_mac(eth_dst), "Invalid destination Ethernet address to configure next output simple"
+
+    rule_no = cache_rule(TABLE_NEXT_SIMPLE, action)
+
+    rules_next_output_simple = []
+    rules_next_output_simple.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_NEXT_SIMPLE+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_NEXT_SIMPLE,
+                'match-fields': [
+                    {
+                        'match-field': 'next_id',
+                        'match-value': str(egress_port)
+                    }
+                ],
+                'action-name': 'FabricIngress.next.output_simple',
+                'action-params': [
+                    {
+                        'action-param': 'port_num',
+                        'action-value': str(egress_port)
+                    }
+                ]
+            }
+        )
+    )
+
+    return rules_next_output_simple
+
+def rules_set_up_next_output_hashed(
+        egress_port : int,
+        action : ConfigActionEnum, # type: ignore
+        next_id = None) -> List [Tuple]:
+    assert egress_port >= 0, "Invalid outport to configure next output hashed"
+
+    if next_id is None:
+        next_id = egress_port
+
+    global NEXT_MEMBER_ID
+
+    rule_no = cache_rule(ACTION_PROFILE_NEXT_HASHED, action)
+
+    rules_next_output_hashed = []
+    rules_next_output_hashed.append(
+        json_config_rule(
+            action,
+            '/action_profiles/action_profile/'+ACTION_PROFILE_NEXT_HASHED+'['+str(rule_no)+']',
+            {
+                'action-profile-name': ACTION_PROFILE_NEXT_HASHED,
+                'member-id': NEXT_MEMBER_ID,
+                'action-name': 'FabricIngress.next.output_hashed',
+                'action-params': [
+                    {
+                        'action-param': 'port_num',
+                        'action-value': str(egress_port)
+                    }
+                ]
+            }
+        )
+    )
+
+    rule_no = cache_rule(TABLE_NEXT_HASHED, action)
+
+    rules_next_output_hashed.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_NEXT_HASHED+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_NEXT_HASHED,
+                'member-id': NEXT_MEMBER_ID,
+                'match-fields': [
+                    {
+                        'match-field': 'next_id',
+                        'match-value': str(next_id)
+                    }
+                ]
+            }
+        )
+    )
+
+    NEXT_MEMBER_ID += 1
+
+    return rules_next_output_hashed
+
+###################################
+### B. End of L2 setup
+###################################
+
+
+###################################
+### C. L3 setup
+###################################
+
+def rules_set_up_routing(
+        ipv4_dst : str,
+        egress_port : int,
+        action : ConfigActionEnum) -> List [Tuple]: # type: ignore
+    assert chk_address_ipv4(ipv4_dst), "Invalid destination IPv4 address to configure routing"
+    assert egress_port >= 0, "Invalid outport to configure routing"
+
+    rule_no = cache_rule(TABLE_ROUTING_V4, action)
+
+    rules_routing = []
+    rules_routing.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_ROUTING_V4+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_ROUTING_V4,
+                'match-fields': [
+                    {
+                        'match-field': 'ipv4_dst',
+                        'match-value': ipv4_dst
+                    }
+                ],
+                'action-name': 'FabricIngress.forwarding.set_next_id_routing_v4',
+                'action-params': [
+                    {
+                        'action-param': 'next_id',
+                        'action-value': str(egress_port)
+                    }
+                ]
+            }
+        )
+    )
+
+    return rules_routing
+
+def rules_set_up_next_routing_simple(
+        egress_port : int,
+        eth_src : str,
+        eth_dst : str,
+        action : ConfigActionEnum) -> List [Tuple]: # type: ignore
+    assert egress_port >= 0, "Invalid outport to configure next routing simple"
+    assert chk_address_mac(eth_src), "Invalid source Ethernet address to configure next routing simple"
+    assert chk_address_mac(eth_dst), "Invalid destination Ethernet address to configure next routing simple"
+
+    rule_no = cache_rule(TABLE_NEXT_SIMPLE, action)
+
+    rules_next_routing_simple = []
+    rules_next_routing_simple.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_NEXT_SIMPLE+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_NEXT_SIMPLE,
+                'match-fields': [
+                    {
+                        'match-field': 'next_id',
+                        'match-value': str(egress_port)
+                    }
+                ],
+                'action-name': 'FabricIngress.next.routing_simple',
+                'action-params': [
+                    {
+                        'action-param': 'port_num',
+                        'action-value': str(egress_port)
+                    },
+                    {
+                        'action-param': 'smac',
+                        'action-value': eth_src
+                    },
+                    {
+                        'action-param': 'dmac',
+                        'action-value': eth_dst
+                    }
+                ]
+            }
+        )
+    )
+
+    return rules_next_routing_simple
+
+def rules_set_up_next_routing_hashed(
+        egress_port : int,
+        action : ConfigActionEnum, # type: ignore
+        next_id = None) -> List [Tuple]:
+    assert egress_port >= 0, "Invalid outport to configure next routing hashed"
+    random_mac_src = generate_random_mac()
+    random_mac_dst = generate_random_mac()
+    if next_id is None:
+        next_id = egress_port
+
+    global NEXT_MEMBER_ID
+
+    rule_no = cache_rule(ACTION_PROFILE_NEXT_HASHED, action)
+
+    rules_next_routing_hashed = []
+    rules_next_routing_hashed.append(
+        json_config_rule(
+            action,
+            '/action_profiles/action_profile/'+ACTION_PROFILE_NEXT_HASHED+'['+str(rule_no)+']',
+            {
+                'action-profile-name': ACTION_PROFILE_NEXT_HASHED,
+                'member-id': NEXT_MEMBER_ID,
+                'action-name': 'FabricIngress.next.routing_hashed',
+                'action-params': [
+                    {
+                        'action-param': 'port_num',
+                        'action-value': str(egress_port)
+                    },
+                    {
+                        'action-param': 'smac',
+                        'action-value': random_mac_src
+                    },
+                    {
+                        'action-param': 'dmac',
+                        'action-value': random_mac_dst
+                    }
+                ]
+            }
+        )
+    )
+
+    rule_no = cache_rule(TABLE_NEXT_HASHED, action)
+
+    rules_next_routing_hashed.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_NEXT_HASHED+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_NEXT_HASHED,
+                'member-id': NEXT_MEMBER_ID,
+                'match-fields': [
+                    {
+                        'match-field': 'next_id',
+                        'match-value': str(next_id)
+                    }
+                ]
+            }
+        )
+    )
+
+    return rules_next_routing_hashed
+
+###################################
+### C. End of L3 setup
+###################################
+
+
+###################################
+### D. Flow mirroring
+###################################
+
+def rules_set_up_report_mirror_flow(
+        recirculation_port_list : List,
+        report_mirror_id_list : List,
+        action : ConfigActionEnum) -> List [Tuple]: # type: ignore
+    rules_list = []
+
+    for i, mirror_id in enumerate(report_mirror_id_list):
+        LOGGER.debug("Mirror ID:{} - Recirculation port: {}".format(
+            mirror_id, recirculation_port_list[i]))
+        rules_list.extend(
+            rules_set_up_clone_session(
+                session_id=mirror_id,
+                egress_port=recirculation_port_list[i],
+                instance=0,
+                action=action
+            )
+        )
+
+    return rules_list
+
+def rules_set_up_clone_session(
+        session_id : int,
+        egress_port : int,
+        instance : int,
+        action : ConfigActionEnum) -> List [Tuple]: # type: ignore
+    assert session_id >= 0, "Invalid session identifier to configure clone session"
+    assert egress_port >= 0, "Invalid egress port number to configure clone session"
+    assert instance >= 0, "Invalid instance number to configure clone session"
+
+    rule_no = cache_rule(CLONE_SESSION, action)
+
+    #TODO: For TNA pass also: packet_length_bytes = 128
+    packet_length_bytes = 128
+
+    rules_clone_session = []
+
+    rules_clone_session.append(
+        json_config_rule(
+            action,
+            CLONE_SESSION+'['+str(rule_no)+']',
+            {
+                'session-id': session_id,
+                'replicas': [
+                    {
+                        'egress-port': egress_port,
+                        'instance': instance
+                    }
+                ]
+            }
+        )
+    )
+
+    return rules_clone_session
+
+###################################
+### D. End of flow mirroring
+###################################
+
+
+###################################
+### E. Access Control Lists
+###################################
+
+def rules_set_up_acl_filter_host(
+        ingress_port : int,
+        ip_address : str,
+        prefix_len : int,
+        action : ConfigActionEnum) -> List [Tuple]: # type: ignore
+    assert ingress_port >= 0, "Invalid ingress port to configure ACL"
+    assert chk_address_ipv4(ip_address), "Invalid IP address to configure ACL"
+    assert 0 < prefix_len <= 32, "Invalid IP address prefix length to configure ACL"
+
+    prefix_len_hex = prefix_to_hex_mask(prefix_len)
+
+    rule_no = cache_rule(TABLE_ACL, action)
+
+    rules_acl = []
+    rules_acl.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_ACL+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_ACL,
+                'match-fields': [
+                    {
+                        'match-field': 'ig_port',
+                        'match-value': str(ingress_port)
+                    },
+                    {
+                        'match-field': 'ipv4_src',
+                        'match-value': '%s&&&%s' % (ip_address, prefix_len_hex)
+                    }
+                ],
+                'action-name': 'FabricIngress.acl.drop',
+                'action-params': [],
+                'priority': 1
+            }
+        )
+    )
+
+    return rules_acl
+
+def rules_set_up_acl_filter_port(
+        ingress_port : int,
+        transport_port : int,
+        action : ConfigActionEnum) -> List [Tuple]: # type: ignore
+    assert ingress_port >= 0, "Invalid ingress port to configure ACL"
+    assert chk_transport_port(transport_port), "Invalid transport port to configure ACL"
+
+    rule_no = cache_rule(TABLE_ACL, action)
+
+    rules_acl = []
+    rules_acl.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_ACL+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_ACL,
+                'match-fields': [
+                    {
+                        'match-field': 'ig_port',
+                        'match-value': str(ingress_port)
+                    },
+                    {
+                        'match-field': 'l4_dport',
+                        'match-value': str(transport_port)
+                    }
+                ],
+                'action-name': 'FabricIngress.acl.drop',
+                'action-params': [],
+                'priority': 1
+            }
+        )
+    )
+
+    return rules_acl
+
+###########################################
+### E. End of Access Control Lists
+###########################################
+
+################################################################################################################
+### Rule management methods
+################################################################################################################
+
+def apply_rules(task_executor, device_obj, json_config_rules):
+    applied_rules = 0
+    failed_rules = 0
+    total_rules = len(json_config_rules)
+    assert device_obj, "Cannot apply rules to invalid device object"
+
+    if total_rules == 0:
+        return applied_rules, failed_rules
+
+    # Provision rules one-by-one
+    for i, json_config_rule in enumerate(json_config_rules):
+        LOGGER.debug("Applying rule #{}: {}".format(i, json_config_rule))
+        try:
+            # Cleanup the rules of this particular object
+            del device_obj.device_config.config_rules[:]
+
+            # Add the new rule to apply
+            device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule))
+
+            # Configure the device via the SBI
+            # TODO: Acquire status of this RPC to ensure that the rule is actually applied
+            task_executor.configure_device(device_obj)
+
+            # Sleep for some time till the next operation
+            sleep_for(RULE_CONF_INTERVAL_SEC)
+
+            applied_rules += 1
+        except Exception as ex:
+            LOGGER.error("Error while applying rule #{}: {}".format(i, ex))
+            failed_rules += 1
+
+    LOGGER.info("Batch rules: {}/{} applied".format(applied_rules, total_rules))
+    LOGGER.info("Batch rules: {}/{} failed".format(failed_rules, total_rules))
+
+    return applied_rules, failed_rules
+
+# Map for keeping rule counts per table
+RULE_ENTRY_MAP = {}
+
+def cache_rule(
+        table_name : str,
+        action : ConfigActionEnum) -> int: # type: ignore
+    rule_no = -1
+
+    if action == ConfigActionEnum.CONFIGACTION_SET:
+        rule_no = add_rule_to_map(table_name)
+    elif action == ConfigActionEnum.CONFIGACTION_DELETE:
+        rule_no = delete_rule_from_map(table_name)
+    else:
+        assert True, "Invalid rule configuration action"
+
+    assert rule_no > 0, "Invalid rule identifier to configure table {}".format(table_name)
+
+    return rule_no
+
+def add_rule_to_map(table_name : str) -> int:
+    if table_name not in RULE_ENTRY_MAP:
+        RULE_ENTRY_MAP[table_name] = []
+
+    # Current number of rules
+    rules_no = len(RULE_ENTRY_MAP[table_name])
+
+    # Get a new valid rule index
+    new_index = find_minimum_available_rule_index(RULE_ENTRY_MAP[table_name])
+    LOGGER.debug("Minimum available rule index for table {} is: {}".format(table_name, new_index))
+    assert new_index > 0, "Invalid rule index for table {}".format(table_name)
+
+    # New entry
+    new_rule_entry = table_name+"["+str(new_index)+"]"
+
+    # Add entry to the list
+    RULE_ENTRY_MAP[table_name].append(new_rule_entry)
+    assert len(RULE_ENTRY_MAP[table_name]) == rules_no + 1
+
+    return new_index
+
+def delete_rule_from_map(table_name : str) -> int:
+    if table_name not in RULE_ENTRY_MAP:
+        LOGGER.error("Table {} has no entries".format(table_name))
+        return -1
+
+    # Current number of rules
+    rules_no = len(RULE_ENTRY_MAP[table_name])
+
+    # Remove last rule
+    rule_entry = RULE_ENTRY_MAP[table_name].pop()
+    # Get its index
+    rule_no = int(rule_entry.split('[')[1].split(']')[0])
+
+    assert len(RULE_ENTRY_MAP[table_name]) == rules_no - 1
+
+    # Return the index of the removed rule
+    return rule_no
+
+def string_contains_number(input_string : str, target_number : int) -> bool:
+    return str(target_number) in input_string
+
+def rule_index_exists(rule_entry_list : List, target_rule_index : int) -> bool:
+    # Rule indices start from 1
+    if target_rule_index <= 0:
+        return False
+
+    rules_no = len(rule_entry_list)
+    if rules_no == 0:
+        return False
+
+    for rule in rule_entry_list:
+        if string_contains_number(rule, target_rule_index):
+            return True
+
+    return False
+
+def find_minimum_available_rule_index(rule_entry_list : List) -> int:
+    rules_no = len(rule_entry_list)
+    if rules_no == 0:
+        return 1
+
+    min_index = -1
+    for i, _ in enumerate(rule_entry_list):
+        index = i+1
+        idx_exists = rule_index_exists(rule_entry_list, index)
+        # This index is not present in the rule list, so it is available
+        if not idx_exists and min_index < index:
+            min_index = index
+
+    # All of the existing rule indices are taken, proceed to the next one
+    if min_index == -1:
+        min_index = rules_no + 1
+
+    return min_index
+
+def print_rule_map() -> None:
+    for k in RULE_ENTRY_MAP.keys():
+        LOGGER.info("Table {} entries: {}".format(k, RULE_ENTRY_MAP[k]))
-- 
GitLab


From afbe8b59cf07312e05ad1e378e40df7ea259c52e Mon Sep 17 00:00:00 2001
From: "Georgios P. Katsikas" <gkatsikas@ubitech.eu>
Date: Sat, 22 Mar 2025 08:27:07 +0000
Subject: [PATCH 04/14] fix: remove unecessary whitespaces

---
 .../p4_fabric_tna_commons/p4_fabric_tna_commons.py     | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/service/service/service_handlers/p4_fabric_tna_commons/p4_fabric_tna_commons.py b/src/service/service/service_handlers/p4_fabric_tna_commons/p4_fabric_tna_commons.py
index eb8077ff3..4b60f9118 100644
--- a/src/service/service/service_handlers/p4_fabric_tna_commons/p4_fabric_tna_commons.py
+++ b/src/service/service/service_handlers/p4_fabric_tna_commons/p4_fabric_tna_commons.py
@@ -129,7 +129,7 @@ RULE_CONF_INTERVAL_SEC = 0.1
 
 def arch_tna(arch : str) -> bool:
     return arch == TARGET_ARCH_TNA
-    
+
 def arch_v1model(arch : str) -> bool:
     return not arch_tna(arch)
 
@@ -143,13 +143,13 @@ def generate_random_mac() -> str:
 def prefix_to_hex_mask(prefix_len):
     # Calculate the binary mask
     binary_mask = (1 << 32) - (1 << (32 - prefix_len))
-    
+
     # Convert the binary mask to the 4 octets (32 bits)
     mask = struct.pack('!I', binary_mask)
-    
+
     # Convert to a string of hex values
     hex_mask = ''.join(f'{byte:02x}' for byte in mask)
-    
+
     return "0x"+hex_mask.upper()
 
 def sleep_for(time_sec : int) -> None:
@@ -172,7 +172,7 @@ def rules_set_up_port_ingress(
     assert ingress_port >= 0, "Invalid ingress port to configure ingress port"
     assert port_type.lower() in PORT_TYPES_STR_VALID, "Invalid port type to configure ingress port"
     assert chk_vlan_id(vlan_id), "Invalid VLAN ID to configure ingress port"
-    
+
     rule_no = cache_rule(TABLE_INGRESS_VLAN, action)
 
     port_type_int = PORT_TYPE_MAP[port_type.lower()]
-- 
GitLab


From 7b9e30103abab96bf40473c3203666257557e4eb Mon Sep 17 00:00:00 2001
From: "Georgios P. Katsikas" <gkatsikas@ubitech.eu>
Date: Mon, 31 Mar 2025 06:30:53 +0000
Subject: [PATCH 05/14] feat: support for more NFs and fixes

---
 src/common/type_checkers/Checkers.py          |  9 ++
 .../p4_fabric_tna_commons.py                  | 96 ++++++++++++++-----
 .../service/task_scheduler/TaskExecutor.py    |  2 +-
 src/tests/tools/test_tools_p4.py              |  6 +-
 4 files changed, 87 insertions(+), 26 deletions(-)

diff --git a/src/common/type_checkers/Checkers.py b/src/common/type_checkers/Checkers.py
index 694f14102..e797d6441 100644
--- a/src/common/type_checkers/Checkers.py
+++ b/src/common/type_checkers/Checkers.py
@@ -140,6 +140,15 @@ def chk_address_ipv4(ip_addr : str):
     except ValueError:
         return False
 
+def chk_prefix_len_ipv4(ip_prefix_len : int):
+    """
+    Check whether input integer is a valid IPv4 address prefix length.
+
+    :param ip_prefix_len: IPv4 address prefix length
+    :return: boolean status
+    """
+    return 0 <= ip_prefix_len <= 32
+
 def chk_address_ipv6(ip_addr : str):
     """
     Check whether input string is a valid IPv6 address or not.
diff --git a/src/service/service/service_handlers/p4_fabric_tna_commons/p4_fabric_tna_commons.py b/src/service/service/service_handlers/p4_fabric_tna_commons/p4_fabric_tna_commons.py
index 4b60f9118..a97bce07f 100644
--- a/src/service/service/service_handlers/p4_fabric_tna_commons/p4_fabric_tna_commons.py
+++ b/src/service/service/service_handlers/p4_fabric_tna_commons/p4_fabric_tna_commons.py
@@ -24,19 +24,37 @@ SD-Fabric docs: https://docs.sd-fabric.org/master/index.html
 import time
 import logging
 import struct
-from common.proto.context_pb2 import ConfigActionEnum, ConfigRule
-from common.tools.object_factory.ConfigRule import json_config_rule
-from common.type_checkers.Checkers import chk_address_mac, chk_vlan_id, \
-    chk_address_ipv4, chk_transport_port
 from random import randint
 from typing import List, Tuple
+from common.proto.context_pb2 import ConfigActionEnum, ConfigRule, Device, EndPoint
+from common.tools.object_factory.ConfigRule import json_config_rule
+from common.type_checkers.Checkers import chk_address_mac, chk_vlan_id, \
+    chk_address_ipv4, chk_prefix_len_ipv4, chk_transport_port
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
 
 LOGGER = logging.getLogger(__name__)
 
 # Common service handler settings
-TARGET_P4_ARCH = "target_p4_arch"
-SWITCH_DATAPLANE_ID_MAP = "switch_dataplane_id_map"
+SWITCH_INFO = "switch_info"
+ARCH = "arch"
+DPID = "dpid"
+MAC = "mac"
+IP = "ip"
+PORT = "port"                        # Dataplane port
+PORT_ID = "port_id"
+PORT_TYPE = "port_type"
 VLAN_ID = "vlan_id"
+RECIRCULATION_PORT_LIST = "recirculation_port_list"
+PORT_LIST = "port_list"
+PORT_PREFIX = "port-"
+ROUTING_LIST = "routing_list"
+MAC_SRC = "mac_src"
+MAC_DST = "mac_dst"
+IPV4_SRC = "ipv4_src"
+IPV4_DST = "ipv4_dst"
+IPV4_PREFIX_LEN = "ipv4_prefix_len"
+TRN_PORT_SRC = "trn_port_src"        # Transport network port (TCP, UDP)
+TRN_PORT_DST = "trn_port_dst"
 
 # P4 architectures
 TARGET_ARCH_TNA = "tna"
@@ -140,7 +158,7 @@ def generate_random_mac() -> str:
 
     return mac_str
 
-def prefix_to_hex_mask(prefix_len):
+def prefix_to_hex_mask(prefix_len : int) -> str:
     # Calculate the binary mask
     binary_mask = (1 << 32) - (1 << (32 - prefix_len))
 
@@ -156,6 +174,30 @@ def sleep_for(time_sec : int) -> None:
     assert time_sec > 0, "Invalid sleep period in seconds"
     time.sleep(time_sec)
 
+def find_port_id_in_endpoint(endpoint : EndPoint, target_endpoint_uuid : str) -> int: # type: ignore
+    assert endpoint, "Invalid device endpoint"
+    endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid
+    assert endpoint_uuid, "Invalid device endpoint UUID"
+    if endpoint_uuid == target_endpoint_uuid:
+        try:
+            dpid = int(endpoint.name)  # P4 devices have integer dataplane port IDs
+            assert dpid > 0, "Invalid device endpoint DPID"
+        except Exception as ex:
+            LOGGER.error(ex)
+            return -1
+        return dpid
+
+    return -1
+
+def find_port_id_in_endpoint_list(endpoint_list : List, target_endpoint_uuid : str) -> int:
+    assert endpoint_list, "Invalid device endpoint list"
+    for endpoint in endpoint_list:
+        result = find_port_id_in_endpoint(endpoint, target_endpoint_uuid)
+        if result != -1:
+            return result
+
+    return -1
+
 ################################################################################################################
 ### Rule generation methods
 ################################################################################################################
@@ -173,6 +215,9 @@ def rules_set_up_port_ingress(
     assert port_type.lower() in PORT_TYPES_STR_VALID, "Invalid port type to configure ingress port"
     assert chk_vlan_id(vlan_id), "Invalid VLAN ID to configure ingress port"
 
+    # VLAN support if 1
+    vlan_is_valid = 1 if vlan_id != VLAN_DEF else 0
+
     rule_no = cache_rule(TABLE_INGRESS_VLAN, action)
 
     port_type_int = PORT_TYPE_MAP[port_type.lower()]
@@ -192,7 +237,7 @@ def rules_set_up_port_ingress(
                     },
                     {
                         'match-field': 'vlan_is_valid',
-                        'match-value': '0'
+                        'match-value': str(vlan_is_valid)
                     }
                 ],
                 'action-name': 'FabricIngress.filtering.permit_with_internal_vlan',
@@ -270,7 +315,7 @@ def rules_set_up_fwd_classifier(
                         'match-value': str(ingress_port)
                     },
                     {
-                        'match-field': 'eth_type',
+                        'match-field': 'ip_eth_type',
                         'match-value': eth_type
                     }
                 ],
@@ -278,10 +323,10 @@ def rules_set_up_fwd_classifier(
                 'action-params': [
                     {
                         'action-param': 'fwd_type',
-                        'action-value': str(FORWARDING_TYPE_UNICAST_IPV4)
+                        'action-value': str(fwd_type)
                     },
                 ],
-                'priority': 10
+                'priority': 1
             }
         )
     )
@@ -294,7 +339,7 @@ def rules_set_up_port(
         fwd_type : int,
         vlan_id : int,
         action : ConfigActionEnum, # type: ignore
-        eth_type=ETHER_TYPE_IPV4):
+        eth_type=ETHER_TYPE_IPV4) -> List [Tuple]:
     rules_list = []
 
     rules_list.extend(
@@ -377,12 +422,8 @@ def rules_set_up_fwd_bridging(
 
 def rules_set_up_next_output_simple(
         egress_port : int,
-        eth_src : str,
-        eth_dst : str,
         action : ConfigActionEnum) -> List [Tuple]: # type: ignore
     assert egress_port >= 0, "Invalid outport to configure next output simple"
-    assert chk_address_mac(eth_src), "Invalid source Ethernet address to configure next output simple"
-    assert chk_address_mac(eth_dst), "Invalid destination Ethernet address to configure next output simple"
 
     rule_no = cache_rule(TABLE_NEXT_SIMPLE, action)
 
@@ -478,9 +519,11 @@ def rules_set_up_next_output_hashed(
 
 def rules_set_up_routing(
         ipv4_dst : str,
+        ipv4_prefix_len : int,
         egress_port : int,
         action : ConfigActionEnum) -> List [Tuple]: # type: ignore
     assert chk_address_ipv4(ipv4_dst), "Invalid destination IPv4 address to configure routing"
+    assert chk_prefix_len_ipv4(ipv4_prefix_len), "Invalid IPv4 prefix length"
     assert egress_port >= 0, "Invalid outport to configure routing"
 
     rule_no = cache_rule(TABLE_ROUTING_V4, action)
@@ -495,7 +538,7 @@ def rules_set_up_routing(
                 'match-fields': [
                     {
                         'match-field': 'ipv4_dst',
-                        'match-value': ipv4_dst
+                        'match-value': ipv4_dst + "/" + str(ipv4_prefix_len)
                     }
                 ],
                 'action-name': 'FabricIngress.forwarding.set_next_id_routing_v4',
@@ -694,11 +737,14 @@ def rules_set_up_acl_filter_host(
         ingress_port : int,
         ip_address : str,
         prefix_len : int,
+        ip_direction : str,
         action : ConfigActionEnum) -> List [Tuple]: # type: ignore
     assert ingress_port >= 0, "Invalid ingress port to configure ACL"
     assert chk_address_ipv4(ip_address), "Invalid IP address to configure ACL"
     assert 0 < prefix_len <= 32, "Invalid IP address prefix length to configure ACL"
 
+    ip_match = "ipv4_src" if ip_direction == "src" else "ipv4_dst"
+
     prefix_len_hex = prefix_to_hex_mask(prefix_len)
 
     rule_no = cache_rule(TABLE_ACL, action)
@@ -716,7 +762,7 @@ def rules_set_up_acl_filter_host(
                         'match-value': str(ingress_port)
                     },
                     {
-                        'match-field': 'ipv4_src',
+                        'match-field': ip_match,
                         'match-value': '%s&&&%s' % (ip_address, prefix_len_hex)
                     }
                 ],
@@ -732,10 +778,13 @@ def rules_set_up_acl_filter_host(
 def rules_set_up_acl_filter_port(
         ingress_port : int,
         transport_port : int,
+        transport_direction : str,
         action : ConfigActionEnum) -> List [Tuple]: # type: ignore
     assert ingress_port >= 0, "Invalid ingress port to configure ACL"
     assert chk_transport_port(transport_port), "Invalid transport port to configure ACL"
 
+    trn_match = "l4_sport" if transport_direction == "src" else "l4_dport"
+
     rule_no = cache_rule(TABLE_ACL, action)
 
     rules_acl = []
@@ -751,7 +800,7 @@ def rules_set_up_acl_filter_port(
                         'match-value': str(ingress_port)
                     },
                     {
-                        'match-field': 'l4_dport',
+                        'match-field': trn_match,
                         'match-value': str(transport_port)
                     }
                 ],
@@ -772,7 +821,10 @@ def rules_set_up_acl_filter_port(
 ### Rule management methods
 ################################################################################################################
 
-def apply_rules(task_executor, device_obj, json_config_rules):
+def apply_rules(
+        task_executor : TaskExecutor,
+        device_obj : Device,       # type: ignore
+        json_config_rules : List): # type: ignore
     applied_rules = 0
     failed_rules = 0
     total_rules = len(json_config_rules)
@@ -802,9 +854,9 @@ def apply_rules(task_executor, device_obj, json_config_rules):
         except Exception as ex:
             LOGGER.error("Error while applying rule #{}: {}".format(i, ex))
             failed_rules += 1
+            raise Exception(ex)
 
-    LOGGER.info("Batch rules: {}/{} applied".format(applied_rules, total_rules))
-    LOGGER.info("Batch rules: {}/{} failed".format(failed_rules, total_rules))
+    LOGGER.debug("Batch rules: {}/{} applied".format(applied_rules, total_rules))
 
     return applied_rules, failed_rules
 
diff --git a/src/service/service/task_scheduler/TaskExecutor.py b/src/service/service/task_scheduler/TaskExecutor.py
index 51fc42a5a..8f797882f 100644
--- a/src/service/service/task_scheduler/TaskExecutor.py
+++ b/src/service/service/task_scheduler/TaskExecutor.py
@@ -203,7 +203,7 @@ class TaskExecutor:
         self, service_id : ServiceId, config_key : str, config_value : str
     ):
         service_configRule = ServiceConfigRule()
-        service_configRule.service_id.CopyFrom( service_id)
+        service_configRule.service_id.CopyFrom(service_id)
         service_configRule.configrule_custom.resource_key = config_key
         service_configRule.configrule_custom.resource_value = config_value
         try:
diff --git a/src/tests/tools/test_tools_p4.py b/src/tests/tools/test_tools_p4.py
index 4557fef61..65257aefc 100644
--- a/src/tests/tools/test_tools_p4.py
+++ b/src/tests/tools/test_tools_p4.py
@@ -28,9 +28,9 @@ P4_DEV_NB = 1
 CONNECTION_RULES = 3
 ENDPOINT_RULES = 3
 INT_RULES = 19
-L2_RULES = 8
-L3_RULES = 8
-ACL_RULES = 1
+L2_RULES = 10
+L3_RULES = 4
+ACL_RULES = 2
 
 DATAPLANE_RULES_NB_INT_B1 = 5
 DATAPLANE_RULES_NB_INT_B2 = 6
-- 
GitLab


From 80b308271192264727d37722f52ab3798074f9c2 Mon Sep 17 00:00:00 2001
From: "Georgios P. Katsikas" <gkatsikas@ubitech.eu>
Date: Mon, 31 Mar 2025 06:42:01 +0000
Subject: [PATCH 06/14] feat: P4 In-band Network Telemetry (INT) service
 hnalder

---
 .../service/service_handlers/__init__.py      |   7 +
 .../p4_fabric_tna_int/__init__.py             |  13 +
 .../p4_fabric_tna_int_config.py               | 425 ++++++++++++++++
 .../p4_fabric_tna_int_service_handler.py      | 467 ++++++++++++++++++
 src/tests/p4-fabric-tna/README.md             |  19 +
 .../descriptors/service-create-int.json       |  53 ++
 .../run_test_06a_service_provision_int.sh     |  17 +
 .../run_test_06b_service_deprovision_int.sh   |  17 +
 ...test_functional_service_deprovision_int.py |  78 +++
 .../test_functional_service_provision_int.py  |  73 +++
 10 files changed, 1169 insertions(+)
 create mode 100644 src/service/service/service_handlers/p4_fabric_tna_int/__init__.py
 create mode 100644 src/service/service/service_handlers/p4_fabric_tna_int/p4_fabric_tna_int_config.py
 create mode 100644 src/service/service/service_handlers/p4_fabric_tna_int/p4_fabric_tna_int_service_handler.py
 create mode 100644 src/tests/p4-fabric-tna/descriptors/service-create-int.json
 create mode 100755 src/tests/p4-fabric-tna/run_test_06a_service_provision_int.sh
 create mode 100755 src/tests/p4-fabric-tna/run_test_06b_service_deprovision_int.sh
 create mode 100644 src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_int.py
 create mode 100644 src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_int.py

diff --git a/src/service/service/service_handlers/__init__.py b/src/service/service/service_handlers/__init__.py
index e03c1172e..76107f03d 100644
--- a/src/service/service/service_handlers/__init__.py
+++ b/src/service/service/service_handlers/__init__.py
@@ -26,6 +26,7 @@ from .l3nm_nce.L3NMNCEServiceHandler import L3NMNCEServiceHandler
 from .l3slice_ietfslice.L3SliceIETFSliceServiceHandler import L3NMSliceIETFSliceServiceHandler
 from .microwave.MicrowaveServiceHandler import MicrowaveServiceHandler
 from .p4_dummy_l1.p4_dummy_l1_service_handler import P4DummyL1ServiceHandler
+from .p4_fabric_tna_int.p4_fabric_tna_int_service_handler import P4FabricINTServiceHandler
 from .tapi_tapi.TapiServiceHandler import TapiServiceHandler
 from .tapi_xr.TapiXrServiceHandler import TapiXrServiceHandler
 from .optical_tfs.OpticalTfsServiceHandler import OpticalTfsServiceHandler
@@ -111,6 +112,12 @@ SERVICE_HANDLERS = [
             FilterFieldEnum.DEVICE_DRIVER: DeviceDriverEnum.DEVICEDRIVER_P4,
         }
     ]),
+    (P4FabricINTServiceHandler, [
+        {
+            FilterFieldEnum.SERVICE_TYPE: ServiceTypeEnum.SERVICETYPE_INT,
+            FilterFieldEnum.DEVICE_DRIVER: DeviceDriverEnum.DEVICEDRIVER_P4,
+        }
+    ]),
     (L2NM_IETFL2VPN_ServiceHandler, [
         {
             FilterFieldEnum.SERVICE_TYPE  : ServiceTypeEnum.SERVICETYPE_L2NM,
diff --git a/src/service/service/service_handlers/p4_fabric_tna_int/__init__.py b/src/service/service/service_handlers/p4_fabric_tna_int/__init__.py
new file mode 100644
index 000000000..023830645
--- /dev/null
+++ b/src/service/service/service_handlers/p4_fabric_tna_int/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/src/service/service/service_handlers/p4_fabric_tna_int/p4_fabric_tna_int_config.py b/src/service/service/service_handlers/p4_fabric_tna_int/p4_fabric_tna_int_config.py
new file mode 100644
index 000000000..8fb22ee97
--- /dev/null
+++ b/src/service/service/service_handlers/p4_fabric_tna_int/p4_fabric_tna_int_config.py
@@ -0,0 +1,425 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Common objects and methods for In-band Network Telemetry (INT) dataplane
+based on the SD-Fabric dataplane model.
+This dataplane covers both software based and hardware-based Stratum-enabled P4 switches,
+such as the BMv2 software switch and Intel's Tofino/Tofino-2 switches.
+
+SD-Fabric repo: https://github.com/stratum/fabric-tna
+SD-Fabric docs: https://docs.sd-fabric.org/master/index.html
+"""
+
+import logging
+from typing import List, Tuple
+from common.proto.context_pb2 import ConfigActionEnum
+from common.tools.object_factory.ConfigRule import json_config_rule
+from common.type_checkers.Checkers import chk_address_ipv4, chk_transport_port
+
+from service.service.service_handlers.p4_fabric_tna_commons.p4_fabric_tna_commons import *
+
+LOGGER = logging.getLogger(__name__)
+
+# INT service handler settings
+INT_COLLECTOR_INFO = "int_collector_info"
+INT_REPORT_MIRROR_ID_LIST = "int_report_mirror_id_list"
+PORT_INT = "int_port"           # In-band Network Telemetry transport port (of the collector)
+
+# INT tables
+TABLE_INT_WATCHLIST = "FabricIngress.int_watchlist.watchlist"
+TABLE_INT_EGRESS_REPORT = "FabricEgress.int_egress.report"
+
+# Mirror IDs for INT reports
+INT_REPORT_MIRROR_ID_LIST_TNA = [0x200, 0x201, 0x202, 0x203]  # Tofino-2 (2-pipe Tofino switches use only the first 2 entries)
+INT_REPORT_MIRROR_ID_LIST_V1MODEL = [0x1FA]                   # Variable V1MODEL_INT_MIRROR_SESSION in p4 source program
+
+# INT report types
+INT_REPORT_TYPE_NO_REPORT = 0
+INT_REPORT_TYPE_FLOW = 1
+INT_REPORT_TYPE_QUEUE = 2
+INT_REPORT_TYPE_DROP = 4
+
+
+def rules_set_up_int_watchlist(action : ConfigActionEnum) -> List [Tuple]: # type: ignore
+    rule_no = cache_rule(TABLE_INT_WATCHLIST, action)
+
+    rules_int_watchlist = []
+    rules_int_watchlist.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_INT_WATCHLIST+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_INT_WATCHLIST,
+                'match-fields': [
+                    {
+                        'match-field': 'ipv4_valid',
+                        'match-value': '1'
+                    }
+                ],
+                'action-name': 'FabricIngress.int_watchlist.mark_to_report',
+                'action-params': [],
+                'priority': 1
+            }
+        )
+    )
+
+    return rules_int_watchlist
+
+def rules_set_up_int_report_collector(
+        int_collector_ip : str,
+        action : ConfigActionEnum) -> List [Tuple]: # type: ignore
+    assert chk_address_ipv4(int_collector_ip), "Invalid INT collector IPv4 address to configure watchlist"
+
+    rule_no = cache_rule(TABLE_INT_WATCHLIST, action)
+
+    rules_int_col_report = []
+    rules_int_col_report.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_INT_WATCHLIST+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_INT_WATCHLIST,
+                'match-fields': [
+                    {
+                        'match-field': 'ipv4_valid',
+                        'match-value': '1'
+                    },
+                    {
+                        'match-field': 'ipv4_dst',
+                        'match-value': int_collector_ip+'&&&0xFFFFFFFF'
+                    }
+                ],
+                'action-name': 'FabricIngress.int_watchlist.no_report_collector',
+                'action-params': [],
+                'priority': 10
+            }
+        )
+    )
+
+    return rules_int_col_report
+
+def rules_set_up_int_recirculation_ports(
+        recirculation_port_list : List,
+        port_type : str,
+        fwd_type : int,
+        vlan_id : int,
+        action : ConfigActionEnum): # type: ignore
+    rules_list = []
+
+    for port in recirculation_port_list:
+        rules_list.extend(
+            rules_set_up_port(
+                port=port,
+                port_type=port_type,
+                fwd_type=fwd_type,
+                vlan_id=vlan_id,
+                action=action
+            )
+        )
+
+    LOGGER.debug("INT recirculation ports configured:{}".format(recirculation_port_list))
+
+    return rules_list
+
+def rules_set_up_int_report_flow(
+        switch_id : int,
+        src_ip : str,
+        int_collector_ip : str,
+        int_collector_port : int,
+        action : ConfigActionEnum) -> List [Tuple]: # type: ignore
+    assert switch_id > 0, "Invalid switch identifier to configure egress INT report"
+    assert chk_address_ipv4(src_ip), "Invalid source IPv4 address to configure egress INT report"
+    assert chk_address_ipv4(int_collector_ip), "Invalid INT collector IPv4 address to configure egress INT report"
+    assert chk_transport_port(int_collector_port), "Invalid INT collector port number to configure egress INT report"
+
+    rule_no = cache_rule(TABLE_INT_EGRESS_REPORT, action)
+
+    rules_int_egress = []
+
+    # Rule #1
+    rules_int_egress.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_INT_EGRESS_REPORT+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_INT_EGRESS_REPORT,
+                'match-fields': [
+                    {
+                        'match-field': 'bmd_type',
+                        'match-value': str(BRIDGED_MD_TYPE_INT_INGRESS_DROP)
+                    },
+                    {
+                        'match-field': 'mirror_type',
+                        'match-value': str(MIRROR_TYPE_INVALID)
+                    },
+                    {
+                        'match-field': 'int_report_type',
+                        'match-value': str(INT_REPORT_TYPE_DROP)
+                    }
+                ],
+                'action-name': 'FabricEgress.int_egress.do_drop_report_encap',
+                'action-params': [
+                    {
+                        'action-param': 'switch_id',
+                        'action-value': str(switch_id)
+                    },
+                    {
+                        'action-param': 'src_ip',
+                        'action-value': src_ip
+                    },
+                    {
+                        'action-param': 'mon_ip',
+                        'action-value': int_collector_ip
+                    },
+                    {
+                        'action-param': 'mon_port',
+                        'action-value': str(int_collector_port)
+                    }
+                ]
+            }
+        )
+    )
+
+    rule_no = cache_rule(TABLE_INT_EGRESS_REPORT, action)
+
+    # Rule #2
+    rules_int_egress.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_INT_EGRESS_REPORT+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_INT_EGRESS_REPORT,
+                'match-fields': [
+                    {
+                        'match-field': 'bmd_type',
+                        'match-value': str(BRIDGED_MD_TYPE_EGRESS_MIRROR)
+                    },
+                    {
+                        'match-field': 'mirror_type',
+                        'match-value': str(MIRROR_TYPE_INT_REPORT)
+                    },
+                    {
+                        'match-field': 'int_report_type',
+                        'match-value': str(INT_REPORT_TYPE_DROP)
+                    }
+                ],
+                'action-name': 'FabricEgress.int_egress.do_drop_report_encap',
+                'action-params': [
+                    {
+                        'action-param': 'switch_id',
+                        'action-value': str(switch_id)
+                    },
+                    {
+                        'action-param': 'src_ip',
+                        'action-value': src_ip
+                    },
+                    {
+                        'action-param': 'mon_ip',
+                        'action-value': int_collector_ip
+                    },
+                    {
+                        'action-param': 'mon_port',
+                        'action-value': str(int_collector_port)
+                    }
+                ]
+            }
+        )
+    )
+
+    rule_no = cache_rule(TABLE_INT_EGRESS_REPORT, action)
+
+    # Rule #3
+    rules_int_egress.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_INT_EGRESS_REPORT+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_INT_EGRESS_REPORT,
+                'match-fields': [
+                    {
+                        'match-field': 'bmd_type',
+                        'match-value': str(BRIDGED_MD_TYPE_EGRESS_MIRROR)
+                    },
+                    {
+                        'match-field': 'mirror_type',
+                        'match-value': str(MIRROR_TYPE_INT_REPORT)
+                    },
+                    {
+                        'match-field': 'int_report_type',
+                        'match-value': str(INT_REPORT_TYPE_FLOW)
+                    }
+                ],
+                'action-name': 'FabricEgress.int_egress.do_local_report_encap',
+                'action-params': [
+                    {
+                        'action-param': 'switch_id',
+                        'action-value': str(switch_id)
+                    },
+                    {
+                        'action-param': 'src_ip',
+                        'action-value': src_ip
+                    },
+                    {
+                        'action-param': 'mon_ip',
+                        'action-value': int_collector_ip
+                    },
+                    {
+                        'action-param': 'mon_port',
+                        'action-value': str(int_collector_port)
+                    }
+                ]
+            }
+        )
+    )
+
+    rule_no = cache_rule(TABLE_INT_EGRESS_REPORT, action)
+
+    # Rule #4
+    rules_int_egress.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_INT_EGRESS_REPORT+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_INT_EGRESS_REPORT,
+                'match-fields': [
+                    {
+                        'match-field': 'bmd_type',
+                        'match-value': str(BRIDGED_MD_TYPE_DEFLECTED)
+                    },
+                    {
+                        'match-field': 'mirror_type',
+                        'match-value': str(MIRROR_TYPE_INVALID)
+                    },
+                    {
+                        'match-field': 'int_report_type',
+                        'match-value': str(INT_REPORT_TYPE_DROP)
+                    }
+                ],
+                'action-name': 'FabricEgress.int_egress.do_drop_report_encap',
+                'action-params': [
+                    {
+                        'action-param': 'switch_id',
+                        'action-value': str(switch_id)
+                    },
+                    {
+                        'action-param': 'src_ip',
+                        'action-value': src_ip
+                    },
+                    {
+                        'action-param': 'mon_ip',
+                        'action-value': int_collector_ip
+                    },
+                    {
+                        'action-param': 'mon_port',
+                        'action-value': str(int_collector_port)
+                    }
+                ]
+            }
+        )
+    )
+
+    rule_no = cache_rule(TABLE_INT_EGRESS_REPORT, action)
+
+    # Rule #5
+    rules_int_egress.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_INT_EGRESS_REPORT+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_INT_EGRESS_REPORT,
+                'match-fields': [
+                    {
+                        'match-field': 'bmd_type',
+                        'match-value': str(BRIDGED_MD_TYPE_EGRESS_MIRROR)
+                    },
+                    {
+                        'match-field': 'mirror_type',
+                        'match-value': str(MIRROR_TYPE_INT_REPORT)
+                    },
+                    {
+                        'match-field': 'int_report_type',
+                        'match-value': str(INT_REPORT_TYPE_QUEUE)
+                    }
+                ],
+                'action-name': 'FabricEgress.int_egress.do_local_report_encap',
+                'action-params': [
+                    {
+                        'action-param': 'switch_id',
+                        'action-value': str(switch_id)
+                    },
+                    {
+                        'action-param': 'src_ip',
+                        'action-value': src_ip
+                    },
+                    {
+                        'action-param': 'mon_ip',
+                        'action-value': int_collector_ip
+                    },
+                    {
+                        'action-param': 'mon_port',
+                        'action-value': str(int_collector_port)
+                    }
+                ]
+            }
+        )
+    )
+
+    rule_no = cache_rule(TABLE_INT_EGRESS_REPORT, action)
+
+    # Rule #6
+    rules_int_egress.append(
+        json_config_rule(
+            action,
+            '/tables/table/'+TABLE_INT_EGRESS_REPORT+'['+str(rule_no)+']',
+            {
+                'table-name': TABLE_INT_EGRESS_REPORT,
+                'match-fields': [
+                    {
+                        'match-field': 'bmd_type',
+                        'match-value': str(BRIDGED_MD_TYPE_EGRESS_MIRROR)
+                    },
+                    {
+                        'match-field': 'mirror_type',
+                        'match-value': str(MIRROR_TYPE_INT_REPORT)
+                    },
+                    {
+                        'match-field': 'int_report_type',
+                        'match-value': str(INT_REPORT_TYPE_QUEUE | INT_REPORT_TYPE_FLOW)
+                    }
+                ],
+                'action-name': 'FabricEgress.int_egress.do_local_report_encap',
+                'action-params': [
+                    {
+                        'action-param': 'switch_id',
+                        'action-value': str(switch_id)
+                    },
+                    {
+                        'action-param': 'src_ip',
+                        'action-value': src_ip
+                    },
+                    {
+                        'action-param': 'mon_ip',
+                        'action-value': int_collector_ip
+                    },
+                    {
+                        'action-param': 'mon_port',
+                        'action-value': str(int_collector_port)
+                    }
+                ]
+            }
+        )
+    )
+
+    return rules_int_egress
diff --git a/src/service/service/service_handlers/p4_fabric_tna_int/p4_fabric_tna_int_service_handler.py b/src/service/service/service_handlers/p4_fabric_tna_int/p4_fabric_tna_int_service_handler.py
new file mode 100644
index 000000000..efdac5fea
--- /dev/null
+++ b/src/service/service/service_handlers/p4_fabric_tna_int/p4_fabric_tna_int_service_handler.py
@@ -0,0 +1,467 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Service handler for P4-based In-band Network Telemetry (INT) v0.5.
+The spec. is based on P4.org Application WG INT Dataplane
+Specification v0.5 (2017-12):
+
+https://p4.org/p4-spec/docs/INT_v0_5.pdf
+"""
+
+import logging
+from typing import Any, List, Optional, Tuple, Union
+from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method
+from common.proto.context_pb2 import ConfigActionEnum, DeviceId, Service, Device
+from common.tools.object_factory.Device import json_device_id
+from common.type_checkers.Checkers import chk_type, chk_address_mac, chk_address_ipv4,\
+    chk_transport_port, chk_vlan_id
+from service.service.service_handler_api._ServiceHandler import _ServiceHandler
+from service.service.service_handler_api.SettingsHandler import SettingsHandler
+from service.service.service_handlers.p4_fabric_tna_commons.p4_fabric_tna_commons import *
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
+
+from .p4_fabric_tna_int_config import *
+
+LOGGER = logging.getLogger(__name__)
+
+METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'p4_fabric_tna_int'})
+
+class P4FabricINTServiceHandler(_ServiceHandler):
+    def __init__(   # pylint: disable=super-init-not-called
+        self, service : Service, task_executor : TaskExecutor, **settings # type: ignore
+    ) -> None:
+        """ Initialize Driver.
+            Parameters:
+                service
+                    The service instance (gRPC message) to be managed.
+                task_executor
+                    An instance of Task Executor providing access to the
+                    service handlers factory, the context and device clients,
+                    and an internal cache of already-loaded gRPC entities.
+                **settings
+                    Extra settings required by the service handler.
+
+        """
+        self.__service_label = "P4 In-band Network Telemetry (INT) connectivity service"
+        self.__service = service
+        self.__task_executor = task_executor
+        self.__settings_handler = SettingsHandler(self.__service.service_config, **settings)
+
+        self._init_settings()
+        self._parse_settings()
+        self._print_settings()
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetEndpoint(
+        self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None
+    ) -> List[Union[bool, Exception]]:
+        """ Create/Update service endpoints from a list.
+            Parameters:
+                endpoints: List[Tuple[str, str, Optional[str]]]
+                    List of tuples, each containing a device_uuid,
+                    endpoint_uuid and, optionally, the topology_uuid
+                    of the endpoint to be added.
+                connection_uuid : Optional[str]
+                    If specified, is the UUID of the connection this endpoint is associated to.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for endpoint changes requested.
+                    Return values must be in the same order as the requested
+                    endpoints. If an endpoint is properly added, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        chk_type('endpoints', endpoints, list)
+        if len(endpoints) == 0: return []
+
+        LOGGER.info("{} - Provision service configuration".format(
+            self.__service_label))
+
+        visited = set()
+        results = []
+        for endpoint in endpoints:
+            device_uuid, _ = endpoint[0:2]
+            device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+
+            # Skip already visited devices
+            if device.name in visited:
+                continue
+            LOGGER.info("Device {} - Setting up In-band Network Telemetry (INT) configuration".format(
+                device.name))
+
+            rules = []
+            actual_rules = -1
+            applied_rules, failed_rules = 0, -1
+
+            # Create and apply rules
+            try:
+                rules = self._create_rules(device_obj=device, action=ConfigActionEnum.CONFIGACTION_SET)
+                actual_rules = len(rules)
+                applied_rules, failed_rules = apply_rules(
+                    task_executor=self.__task_executor,
+                    device_obj=device,
+                    json_config_rules=rules
+                )
+            except Exception as ex:
+                LOGGER.error("Failed to insert INT rules on device {} due to {}".format(device.name, ex))
+            finally:
+                rules.clear()
+
+            # Ensure correct status
+            results.append(True) if (failed_rules == 0) and (applied_rules == actual_rules) \
+                else results.append(False)
+
+            # You should no longer visit this device again
+            visited.add(device.name)
+
+            LOGGER.info("Installed {}/{} INT rules on device {}".format(
+                applied_rules, actual_rules, device.name))
+
+        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]]:
+        """ Delete service endpoints from a list.
+            Parameters:
+                endpoints: List[Tuple[str, str, Optional[str]]]
+                    List of tuples, each containing a device_uuid,
+                    endpoint_uuid, and the topology_uuid of the endpoint
+                    to be removed.
+                connection_uuid : Optional[str]
+                    If specified, is the UUID of the connection this endpoint is associated to.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for endpoint deletions requested.
+                    Return values must be in the same order as the requested
+                    endpoints. If an endpoint is properly deleted, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        chk_type('endpoints', endpoints, list)
+        if len(endpoints) == 0: return []
+
+        LOGGER.info("{} - Deprovision service configuration".format(
+            self.__service_label))
+
+        visited = set()
+        results = []
+        for endpoint in endpoints:
+            device_uuid, _ = endpoint[0:2]
+            device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+
+            # Skip already visited devices
+            if device.name in visited:
+                continue
+            LOGGER.info("Device {} - Removing In-band Network Telemetry (INT) configuration".format(
+                device.name))
+
+            rules = []
+            actual_rules = -1
+            applied_rules, failed_rules = 0, -1
+
+            # Create and apply rules
+            try:
+                rules = self._create_rules(device_obj=device, action=ConfigActionEnum.CONFIGACTION_DELETE)
+                actual_rules = len(rules)
+                applied_rules, failed_rules = apply_rules(
+                task_executor=self.__task_executor, device_obj=device, json_config_rules=rules)
+            except Exception as ex:
+                LOGGER.error("Failed to delete INT rules from device {} due to {}".format(device.name, ex))
+            finally:
+                rules.clear()
+
+            # Ensure correct status
+            results.append(True) if (failed_rules == 0) and (applied_rules == actual_rules) \
+                else results.append(False)
+
+            # You should no longer visit this device again
+            visited.add(device.name)
+
+            LOGGER.info("Deleted {}/{} INT rules from device {}".format(
+                applied_rules, actual_rules, device.name))
+
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetConstraint(self, constraints: List[Tuple[str, Any]]) \
+            -> List[Union[bool, Exception]]:
+        """ Create/Update service constraints.
+            Parameters:
+                constraints: List[Tuple[str, Any]]
+                    List of tuples, each containing a constraint_type and the
+                    new constraint_value to be set.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for constraint changes requested.
+                    Return values must be in the same order as the requested
+                    constraints. If a constraint is properly set, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        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]]:
+        """ Delete service constraints.
+            Parameters:
+                constraints: List[Tuple[str, Any]]
+                    List of tuples, each containing a constraint_type pointing
+                    to the constraint to be deleted, and a constraint_value
+                    containing possible additionally required values to locate
+                    the constraint to be removed.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for constraint deletions requested.
+                    Return values must be in the same order as the requested
+                    constraints. If a constraint is properly deleted, True must
+                    be returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        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]]:
+        """ Create/Update configuration for a list of service resources.
+            Parameters:
+                resources: List[Tuple[str, Any]]
+                    List of tuples, each containing a resource_key pointing to
+                    the resource to be modified, and a resource_value
+                    containing the new value to be set.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for resource key changes requested.
+                    Return values must be in the same order as the requested
+                    resource keys. If a resource is properly set, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        chk_type('resources', resources, list)
+        if len(resources) == 0: return []
+
+        msg = '[SetConfig] Method not implemented. Resources({:s}) are being ignored.'
+        LOGGER.warning(msg.format(str(resources)))
+        return [True for _ in range(len(resources))]
+
+    @metered_subclass_method(METRICS_POOL)
+    def DeleteConfig(self, resources: List[Tuple[str, Any]]) \
+            -> List[Union[bool, Exception]]:
+        """ Delete configuration for a list of service resources.
+            Parameters:
+                resources: List[Tuple[str, Any]]
+                    List of tuples, each containing a resource_key pointing to
+                    the resource to be modified, and a resource_value containing
+                    possible additionally required values to locate the value
+                    to be removed.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for resource key deletions requested.
+                    Return values must be in the same order as the requested
+                    resource keys. If a resource is properly deleted, True must
+                    be returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        chk_type('resources', resources, list)
+        if len(resources) == 0: return []
+
+        msg = '[SetConfig] Method not implemented. Resources({:s}) are being ignored.'
+        LOGGER.warning(msg.format(str(resources)))
+        return [True for _ in range(len(resources))]
+
+    def _init_settings(self):
+        self.__switch_info = {}
+        self.__int_collector_info = {}
+        self.__int_collector_mac = ""
+        self.__int_collector_ip = ""
+        self.__int_collector_port = -1
+        self.__int_vlan_id = -1
+
+        try:
+            self.__settings = self.__settings_handler.get('/settings')
+            LOGGER.info("{} with settings: {}".format(self.__service_label, self.__settings))
+        except Exception as ex:
+            self.__settings = {}
+            LOGGER.error("Failed to parse service settings: {}".format(ex))
+
+    def _default_settings(self):
+        switch_info = {
+            "p4-sw1": {
+                ARCH: TARGET_ARCH_V1MODEL,
+                DPID: 1,
+                MAC: "fa:16:3e:93:8c:c0",
+                IP: "10.10.10.120",
+                PORT_INT: {
+                    PORT_ID: 3,
+                    PORT_TYPE: "host"
+                },
+                RECIRCULATION_PORT_LIST: RECIRCULATION_PORTS_V1MODEL,
+                INT_REPORT_MIRROR_ID_LIST: INT_REPORT_MIRROR_ID_LIST_V1MODEL
+            }
+        }
+        int_collector_info = {
+            MAC: "fa:16:3e:fb:cf:96",
+            IP: "10.10.10.41",
+            PORT: 32766,
+            VLAN_ID: 4094
+        }
+        self.__settings = {
+            SWITCH_INFO: switch_info,
+            INT_COLLECTOR_INFO: int_collector_info
+        }
+
+    def _parse_settings(self):
+        #TODO: Pass settings in a correct way
+        try:
+            self.__switch_info = self.__settings[SWITCH_INFO]
+        except Exception as ex:
+            LOGGER.error("Failed to parse settings: {}".format(ex))
+            self._default_settings() #TODO: Remove when bug is fixed
+            self.__switch_info = self.__settings[SWITCH_INFO]
+        assert isinstance(self.__switch_info, dict), "Switch info object must be a map with switch names as keys"
+
+        for switch_name, switch_info in self.__switch_info.items():
+            assert switch_name, "Invalid P4 switch name"
+            assert isinstance(switch_info, dict), "Switch {} info must be a map with arch, dpid, mac, ip, and int_port items)"
+            assert switch_info[ARCH] in SUPPORTED_TARGET_ARCH_LIST, \
+                "Switch {} - Supported P4 architectures are: {}".format(switch_name, ','.join(SUPPORTED_TARGET_ARCH_LIST))
+            assert switch_info[DPID] > 0, "Switch {} - P4 switch dataplane ID must be a positive integer".format(switch_name, switch_info[DPID])
+            assert chk_address_mac(switch_info[MAC]), "Switch {} - Invalid source Ethernet address".format(switch_name)
+            assert chk_address_ipv4(switch_info[IP]), "Switch {} - Invalid source IP address".format(switch_name)
+            assert isinstance(switch_info[PORT_INT], dict), "Switch {} - INT port object must be a map with port_id and port_type items".format(switch_name)
+            assert switch_info[PORT_INT][PORT_ID] >= 0, "Switch {} - Invalid P4 switch port ID".format(switch_name)
+            assert switch_info[PORT_INT][PORT_TYPE] in PORT_TYPES_STR_VALID, "Switch {} - Valid P4 switch port types are: {}".format(
+                switch_name, ','.join(PORT_TYPES_STR_VALID))
+            if arch_tna(switch_info[ARCH]):
+                switch_info[RECIRCULATION_PORT_LIST] = RECIRCULATION_PORTS_TNA
+                switch_info[INT_REPORT_MIRROR_ID_LIST] = INT_REPORT_MIRROR_ID_LIST_TNA
+            else:
+                switch_info[RECIRCULATION_PORT_LIST] = RECIRCULATION_PORTS_V1MODEL
+                switch_info[INT_REPORT_MIRROR_ID_LIST] = INT_REPORT_MIRROR_ID_LIST_V1MODEL
+            assert isinstance(switch_info[RECIRCULATION_PORT_LIST], list), "Switch {} - Recirculation ports must be described as a list".format(switch_name)
+
+        self.__int_collector_info = self.__settings[INT_COLLECTOR_INFO]
+        assert isinstance(self.__int_collector_info, dict), "INT collector info object must be a map with mac, ip, port, and vlan_id keys)"
+
+        self.__int_collector_mac = self.__int_collector_info[MAC]
+        assert chk_address_mac(self.__int_collector_mac), "Invalid P4 INT collector MAC address"
+
+        self.__int_collector_ip = self.__int_collector_info[IP]
+        assert chk_address_ipv4(self.__int_collector_ip), "Invalid P4 INT collector IPv4 address"
+
+        self.__int_collector_port = self.__int_collector_info[PORT]
+        assert chk_transport_port(self.__int_collector_port), "Invalid P4 INT collector transport port"
+
+        self.__int_vlan_id = self.__int_collector_info[VLAN_ID]
+        assert chk_vlan_id(self.__int_vlan_id), "Invalid VLAN ID"
+
+    def _print_settings(self):
+        LOGGER.info("-------------------- {} settings --------------------".format(self.__service.name))
+        LOGGER.info("--- Topology info")
+        for switch_name, switch_info in self.__switch_info.items():
+            LOGGER.info("\t Device {}".format(switch_name))
+            LOGGER.info("\t\t|  Target P4 architecture: {}".format(switch_info[ARCH]))
+            LOGGER.info("\t\t|           Data plane ID: {}".format(switch_info[DPID]))
+            LOGGER.info("\t\t|      Source MAC address: {}".format(switch_info[MAC]))
+            LOGGER.info("\t\t|      Source  IP address: {}".format(switch_info[IP]))
+            LOGGER.info("\t\t|           INT port   ID: {}".format(switch_info[PORT_INT][PORT_ID]))
+            LOGGER.info("\t\t|           INT port type: {}".format(switch_info[PORT_INT][PORT_TYPE]))
+            LOGGER.info("\t\t| Recirculation port list: {}".format(switch_info[RECIRCULATION_PORT_LIST]))
+            LOGGER.info("\t\t|   Report mirror ID list: {}".format(switch_info[INT_REPORT_MIRROR_ID_LIST]))
+        LOGGER.info("--- INT collector  MAC: {}".format(self.__int_collector_mac))
+        LOGGER.info("--- INT collector   IP: {}".format(self.__int_collector_ip))
+        LOGGER.info("--- INT collector port: {}".format(self.__int_collector_port))
+        LOGGER.info("--- INT        VLAN ID: {}".format(self.__int_vlan_id))
+        LOGGER.info("-----------------------------------------------------------------")
+
+    def _create_rules(self, device_obj : Device, action : ConfigActionEnum): # type: ignore
+        dev_name = device_obj.name
+        rules  = []
+
+        try:
+            ### INT reporting rules
+            rules += rules_set_up_int_watchlist(action=action)
+            rules += rules_set_up_int_recirculation_ports(
+                recirculation_port_list=self.__switch_info[dev_name][RECIRCULATION_PORT_LIST],
+                port_type=PORT_TYPE_INT,
+                fwd_type=FORWARDING_TYPE_UNICAST_IPV4,
+                vlan_id=self.__int_vlan_id,
+                action=action
+            )
+            rules += rules_set_up_int_report_collector(
+                int_collector_ip=self.__int_collector_ip,
+                action=action
+            )
+            rules += rules_set_up_int_report_flow(
+                switch_id=self.__switch_info[dev_name][DPID],
+                src_ip=self.__switch_info[dev_name][IP],
+                int_collector_ip=self.__int_collector_ip,
+                int_collector_port=self.__int_collector_port,
+                action=action
+            )
+            rules += rules_set_up_report_mirror_flow(
+                recirculation_port_list=self.__switch_info[dev_name][RECIRCULATION_PORT_LIST],
+                report_mirror_id_list=self.__switch_info[dev_name][INT_REPORT_MIRROR_ID_LIST],
+                action=action
+            )
+            ### INT port setup rules
+            rules += rules_set_up_port(
+                port=self.__switch_info[dev_name][PORT_INT][PORT_ID],
+                port_type=PORT_TYPE_HOST,
+                fwd_type=FORWARDING_TYPE_BRIDGING,
+                vlan_id=self.__int_vlan_id,
+                action=action
+            )
+            ### INT port forwarding rules
+            rules += rules_set_up_fwd_bridging(
+                vlan_id=self.__int_vlan_id,
+                eth_dst=self.__int_collector_mac,
+                egress_port=self.__switch_info[dev_name][PORT_INT][PORT_ID],
+                action=action
+            )
+            rules += rules_set_up_next_output_simple(
+                egress_port=self.__switch_info[dev_name][PORT_INT][PORT_ID],
+                action=action
+            )
+            ### INT packet routing rules
+            rules += rules_set_up_next_routing_simple(
+                egress_port=self.__switch_info[dev_name][PORT_INT][PORT_ID],
+                eth_src=self.__switch_info[dev_name][MAC],
+                eth_dst=self.__int_collector_mac,
+                action=action
+            )
+            rules += rules_set_up_routing(
+                ipv4_dst=self.__int_collector_ip,
+                ipv4_prefix_len=32,
+                egress_port=self.__switch_info[dev_name][PORT_INT][PORT_ID],
+                action=action
+            )
+        except Exception as ex:
+            LOGGER.error("Error while creating rules")
+            raise Exception(ex)
+
+        return rules
diff --git a/src/tests/p4-fabric-tna/README.md b/src/tests/p4-fabric-tna/README.md
index fc49276a9..10303009d 100644
--- a/src/tests/p4-fabric-tna/README.md
+++ b/src/tests/p4-fabric-tna/README.md
@@ -120,6 +120,25 @@ cd ~/tfs-ctrl/
 bash src/tests/p4-fabric-tna/run_test_02b_sbi_deprovision_int_l2_l3_acl.sh
 ```
 
+### Step 3: Manage L2, L3, ACL, and INT via the Service API
+
+To avoid interacting with the switch using low-level P4 rules (via the SBI), we created modular network services, which allow users to easily provision L2, L3, ACL, and INT network functions.
+These services require users to define the service endpoints as well as some high-level service configuration, while leaving the rest of complexity to tailored service handlers that interact with the SBI on behalf of the user.
+
+#### Provision INT service via the Service API
+
+```shell
+cd ~/tfs-ctrl/
+bash src/tests/p4-fabric-tna/run_test_06a_service_provision_int.sh
+```
+
+#### Deprovision INT service via the Service API
+
+```shell
+cd ~/tfs-ctrl/
+bash src/tests/p4-fabric-tna/run_test_06b_service_deprovision_int.sh
+```
+
 ### Step 4: Deprovision topology
 
 Delete all the objects (context, topology, links, devices) from TFS:
diff --git a/src/tests/p4-fabric-tna/descriptors/service-create-int.json b/src/tests/p4-fabric-tna/descriptors/service-create-int.json
new file mode 100644
index 000000000..98956b959
--- /dev/null
+++ b/src/tests/p4-fabric-tna/descriptors/service-create-int.json
@@ -0,0 +1,53 @@
+{
+    "services": [
+        {
+            "service_id": {
+                "context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "p4-service-int"}
+            },
+            "name": "p4-service-int",
+            "service_type": "SERVICETYPE_INT",
+            "service_status": {"service_status": "SERVICESTATUS_PLANNED"},
+            "service_endpoint_ids": [
+                {
+                    "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+                    "endpoint_uuid": {"uuid": "1"}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+                    "endpoint_uuid": {"uuid": "2"}
+                }
+            ],
+            "service_config": {
+                "config_rules": [
+                    {
+                        "action": "CONFIGACTION_SET",
+                        "custom": {
+                            "resource_key": "/settings",
+                            "resource_value": {
+                                "switch_info": {
+                                    "p4-sw1": {
+                                        "arch": "v1model",
+                                        "dpid": 1,
+                                        "mac": "fa:16:3e:93:8c:c0",
+                                        "ip": "10.10.10.120",
+                                        "int_port": {
+                                            "port_id": 3,
+                                            "port_type": "host"
+                                        }
+                                    }
+                                },
+                                "int_collector_info": {
+                                    "mac": "fa:16:3e:fb:cf:96",
+                                    "ip": "10.10.10.41",
+                                    "port": 32766,
+                                    "vlan_id": 4094
+                                }
+                            }
+                        }
+                    }
+                ]
+            },
+            "service_constraints": []
+        }
+    ]
+}
diff --git a/src/tests/p4-fabric-tna/run_test_06a_service_provision_int.sh b/src/tests/p4-fabric-tna/run_test_06a_service_provision_int.sh
new file mode 100755
index 000000000..12bc82352
--- /dev/null
+++ b/src/tests/p4-fabric-tna/run_test_06a_service_provision_int.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source tfs_runtime_env_vars.sh
+python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_int.py
diff --git a/src/tests/p4-fabric-tna/run_test_06b_service_deprovision_int.sh b/src/tests/p4-fabric-tna/run_test_06b_service_deprovision_int.sh
new file mode 100755
index 000000000..a501de770
--- /dev/null
+++ b/src/tests/p4-fabric-tna/run_test_06b_service_deprovision_int.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source tfs_runtime_env_vars.sh
+python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_int.py
diff --git a/src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_int.py b/src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_int.py
new file mode 100644
index 000000000..f29f6b17c
--- /dev/null
+++ b/src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_int.py
@@ -0,0 +1,78 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+from common.proto.context_pb2 import ServiceId, ServiceStatusEnum, ServiceTypeEnum
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from common.tools.object_factory.Service import json_service_id
+from context.client.ContextClient import ContextClient
+from service.client.ServiceClient import ServiceClient
+from tests.Fixtures import context_client, service_client # pylint: disable=unused-import
+from tests.tools.test_tools_p4 import *
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+def test_service_deletion_int(
+    context_client : ContextClient, # pylint: disable=redefined-outer-name
+    service_client : ServiceClient  # pylint: disable=redefined-outer-name
+) -> None:
+    # Get the current number of devices
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    LOGGER.warning('Devices[{:d}] = {:s}'.format(len(response.devices), grpc_message_to_json_string(response)))
+
+    # Total devices
+    dev_nb = len(response.devices)
+    assert dev_nb == DEV_NB
+
+    # P4 devices
+    p4_dev_nb = identify_number_of_p4_devices(response.devices)
+    assert p4_dev_nb == P4_DEV_NB
+
+    # Get the current number of rules in the P4 devices
+    p4_rules_before_deletion = get_number_of_rules(response.devices)
+
+    # Get the current number of services
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    services_nb_before_deletion = len(response.services)
+    assert verify_active_service_type(response.services, ServiceTypeEnum.SERVICETYPE_INT)
+
+    for service in response.services:
+        # Ignore services of other types
+        if service.service_type != ServiceTypeEnum.SERVICETYPE_INT:
+            continue
+
+        service_id = service.service_id
+        assert service_id
+
+        service_uuid = service_id.service_uuid.uuid
+        context_uuid = service_id.context_id.context_uuid.uuid
+        assert service.service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE
+
+        # Delete INT service
+        service_client.DeleteService(ServiceId(**json_service_id(service_uuid, json_context_id(context_uuid))))
+
+    # Get an updated view of the services
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    services_nb_after_deletion = len(response.services)
+    assert services_nb_after_deletion == services_nb_before_deletion - 1, "Exactly one new service must be deleted"
+
+    # Get an updated view of the devices
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    p4_rules_after_deletion = get_number_of_rules(response.devices)
+
+    rules_diff = p4_rules_before_deletion - p4_rules_after_deletion
+
+    assert p4_rules_after_deletion < p4_rules_before_deletion, "INT service must contain some rules"
+    assert rules_diff == P4_DEV_NB * INT_RULES, "INT service must contain {} rules per device".format(INT_RULES)
diff --git a/src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_int.py b/src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_int.py
new file mode 100644
index 000000000..7a875c66a
--- /dev/null
+++ b/src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_int.py
@@ -0,0 +1,73 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+from common.proto.context_pb2 import ServiceTypeEnum
+from common.tools.descriptor.Loader import DescriptorLoader, check_descriptor_load_results
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from service.client.ServiceClient import ServiceClient
+from tests.Fixtures import context_client, device_client, service_client # pylint: disable=unused-import
+from tests.tools.test_tools_p4 import *
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+def test_service_creation_int(
+    context_client : ContextClient, # pylint: disable=redefined-outer-name
+    device_client  : DeviceClient,  # pylint: disable=redefined-outer-name
+    service_client : ServiceClient  # pylint: disable=redefined-outer-name
+) -> None:
+    # Get the current number of services
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    services_nb_before = len(response.services)
+
+    # Get the current number of devices
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    LOGGER.warning('Devices[{:d}] = {:s}'.format(len(response.devices), grpc_message_to_json_string(response)))
+
+    # Total devices
+    dev_nb = len(response.devices)
+    assert dev_nb == DEV_NB
+
+    # P4 devices
+    p4_dev_nb = identify_number_of_p4_devices(response.devices)
+    assert p4_dev_nb == P4_DEV_NB
+
+    # Get the current number of rules in the P4 devices
+    p4_rules_before = get_number_of_rules(response.devices)
+
+    # Load service
+    descriptor_loader = DescriptorLoader(
+        descriptors_file=DESC_FILE_SERVICE_CREATE_INT,
+        context_client=context_client, device_client=device_client, service_client=service_client
+    )
+    results = descriptor_loader.process()
+    check_descriptor_load_results(results, descriptor_loader)
+
+    # Get an updated view of the services
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    services_nb_after = len(response.services)
+    assert services_nb_after == services_nb_before + 1, "Exactly one new service must be in place"
+    assert verify_active_service_type(response.services, ServiceTypeEnum.SERVICETYPE_INT)
+
+    # Get an updated view of the devices
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    p4_rules_after = get_number_of_rules(response.devices)
+
+    rules_diff = p4_rules_after - p4_rules_before
+
+    assert p4_rules_after > p4_rules_before, "INT service must install some rules"
+    assert rules_diff == P4_DEV_NB * INT_RULES, "INT service must install {} rules per device".format(INT_RULES)
-- 
GitLab


From e071dfc4d9ef68a79e7c828c9bc251f682ae4896 Mon Sep 17 00:00:00 2001
From: "Georgios P. Katsikas" <gkatsikas@ubitech.eu>
Date: Mon, 31 Mar 2025 07:12:29 +0000
Subject: [PATCH 07/14] feat: P4 L2 simple service handler

---
 .../service/service_handlers/__init__.py      |   7 +
 .../p4_fabric_tna_l2_simple/__init__.py       |  13 +
 .../p4_fabric_tna_l2_simple_config.py         |  69 +++
 ...p4_fabric_tna_l2_simple_service_handler.py | 518 ++++++++++++++++++
 src/tests/p4-fabric-tna/README.md             |  14 +
 .../descriptors/service-create-l2-simple.json |  63 +++
 .../run_test_03a_service_provision_l2.sh      |  17 +
 .../run_test_03b_service_deprovision_l2.sh    |  17 +
 .../test_functional_service_deprovision_l2.py |  78 +++
 .../test_functional_service_provision_l2.py   |  73 +++
 src/tests/tools/test_tools_p4.py              |   6 +-
 11 files changed, 872 insertions(+), 3 deletions(-)
 create mode 100644 src/service/service/service_handlers/p4_fabric_tna_l2_simple/__init__.py
 create mode 100644 src/service/service/service_handlers/p4_fabric_tna_l2_simple/p4_fabric_tna_l2_simple_config.py
 create mode 100644 src/service/service/service_handlers/p4_fabric_tna_l2_simple/p4_fabric_tna_l2_simple_service_handler.py
 create mode 100644 src/tests/p4-fabric-tna/descriptors/service-create-l2-simple.json
 create mode 100755 src/tests/p4-fabric-tna/run_test_03a_service_provision_l2.sh
 create mode 100755 src/tests/p4-fabric-tna/run_test_03b_service_deprovision_l2.sh
 create mode 100644 src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_l2.py
 create mode 100644 src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_l2.py

diff --git a/src/service/service/service_handlers/__init__.py b/src/service/service/service_handlers/__init__.py
index 76107f03d..756d0fffb 100644
--- a/src/service/service/service_handlers/__init__.py
+++ b/src/service/service/service_handlers/__init__.py
@@ -27,6 +27,7 @@ from .l3slice_ietfslice.L3SliceIETFSliceServiceHandler import L3NMSliceIETFSlice
 from .microwave.MicrowaveServiceHandler import MicrowaveServiceHandler
 from .p4_dummy_l1.p4_dummy_l1_service_handler import P4DummyL1ServiceHandler
 from .p4_fabric_tna_int.p4_fabric_tna_int_service_handler import P4FabricINTServiceHandler
+from .p4_fabric_tna_l2_simple.p4_fabric_tna_l2_simple_service_handler import P4FabricL2SimpleServiceHandler
 from .tapi_tapi.TapiServiceHandler import TapiServiceHandler
 from .tapi_xr.TapiXrServiceHandler import TapiXrServiceHandler
 from .optical_tfs.OpticalTfsServiceHandler import OpticalTfsServiceHandler
@@ -118,6 +119,12 @@ SERVICE_HANDLERS = [
             FilterFieldEnum.DEVICE_DRIVER: DeviceDriverEnum.DEVICEDRIVER_P4,
         }
     ]),
+    (P4FabricL2SimpleServiceHandler, [
+        {
+            FilterFieldEnum.SERVICE_TYPE: ServiceTypeEnum.SERVICETYPE_L2NM,
+            FilterFieldEnum.DEVICE_DRIVER: DeviceDriverEnum.DEVICEDRIVER_P4,
+        }
+    ]),
     (L2NM_IETFL2VPN_ServiceHandler, [
         {
             FilterFieldEnum.SERVICE_TYPE  : ServiceTypeEnum.SERVICETYPE_L2NM,
diff --git a/src/service/service/service_handlers/p4_fabric_tna_l2_simple/__init__.py b/src/service/service/service_handlers/p4_fabric_tna_l2_simple/__init__.py
new file mode 100644
index 000000000..023830645
--- /dev/null
+++ b/src/service/service/service_handlers/p4_fabric_tna_l2_simple/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/src/service/service/service_handlers/p4_fabric_tna_l2_simple/p4_fabric_tna_l2_simple_config.py b/src/service/service/service_handlers/p4_fabric_tna_l2_simple/p4_fabric_tna_l2_simple_config.py
new file mode 100644
index 000000000..5e2aed066
--- /dev/null
+++ b/src/service/service/service_handlers/p4_fabric_tna_l2_simple/p4_fabric_tna_l2_simple_config.py
@@ -0,0 +1,69 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Common objects and methods for L2 forwarding based on the SD-Fabric dataplane model.
+This dataplane covers both software based and hardware-based Stratum-enabled P4 switches,
+such as the BMv2 software switch and Intel's Tofino/Tofino-2 switches.
+
+SD-Fabric repo: https://github.com/stratum/fabric-tna
+SD-Fabric docs: https://docs.sd-fabric.org/master/index.html
+"""
+
+import logging
+from common.proto.context_pb2 import ConfigActionEnum
+
+from service.service.service_handlers.p4_fabric_tna_commons.p4_fabric_tna_commons import *
+
+LOGGER = logging.getLogger(__name__)
+
+# L2 simple service handler settings
+FORWARDING_LIST = "fwd_list"
+HOST_MAC = "host_mac"
+
+def rules_set_up_port_host(
+        port : int,
+        vlan_id : int,
+        action : ConfigActionEnum, # type: ignore
+        fwd_type=FORWARDING_TYPE_BRIDGING,
+        eth_type=ETHER_TYPE_IPV4):
+    # This is a host facing port
+    port_type = PORT_TYPE_HOST
+
+    return rules_set_up_port(
+        port=port,
+        port_type=port_type,
+        fwd_type=fwd_type,
+        vlan_id=vlan_id,
+        action=action,
+        eth_type=eth_type
+    )
+
+def rules_set_up_port_switch(
+        port : int,
+        vlan_id : int,
+        action : ConfigActionEnum, # type: ignore
+        fwd_type=FORWARDING_TYPE_BRIDGING,
+        eth_type=ETHER_TYPE_IPV4):
+    # This is a switch facing port
+    port_type = PORT_TYPE_SWITCH
+
+    return rules_set_up_port(
+        port=port,
+        port_type=port_type,
+        fwd_type=fwd_type,
+        vlan_id=vlan_id,
+        action=action,
+        eth_type=eth_type
+    )
diff --git a/src/service/service/service_handlers/p4_fabric_tna_l2_simple/p4_fabric_tna_l2_simple_service_handler.py b/src/service/service/service_handlers/p4_fabric_tna_l2_simple/p4_fabric_tna_l2_simple_service_handler.py
new file mode 100644
index 000000000..c25fb087c
--- /dev/null
+++ b/src/service/service/service_handlers/p4_fabric_tna_l2_simple/p4_fabric_tna_l2_simple_service_handler.py
@@ -0,0 +1,518 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Service handler for P4-based L2 forwarding using the SD-Fabric P4 dataplane
+for BMv2 and Intel Tofino switches.
+"""
+
+import logging
+from typing import Any, List, Dict, Optional, Tuple, Union
+from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method
+from common.proto.context_pb2 import ConfigActionEnum, DeviceId, Service, Device
+from common.tools.object_factory.Device import json_device_id
+from common.type_checkers.Checkers import chk_type, chk_address_mac, chk_vlan_id
+from service.service.service_handler_api._ServiceHandler import _ServiceHandler
+from service.service.service_handler_api.SettingsHandler import SettingsHandler
+from service.service.service_handlers.p4_fabric_tna_commons.p4_fabric_tna_commons import *
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
+
+from .p4_fabric_tna_l2_simple_config import *
+
+LOGGER = logging.getLogger(__name__)
+
+METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'p4_fabric_tna_l2_simple'})
+
+class P4FabricL2SimpleServiceHandler(_ServiceHandler):
+    def __init__(   # pylint: disable=super-init-not-called
+        self, service : Service, task_executor : TaskExecutor, **settings # type: ignore
+    ) -> None:
+        """ Initialize Driver.
+            Parameters:
+                service
+                    The service instance (gRPC message) to be managed.
+                task_executor
+                    An instance of Task Executor providing access to the
+                    service handlers factory, the context and device clients,
+                    and an internal cache of already-loaded gRPC entities.
+                **settings
+                    Extra settings required by the service handler.
+
+        """
+        self.__service_label = "P4 L2 simple connectivity service"
+        self.__service = service
+        self.__task_executor = task_executor
+        self.__settings_handler = SettingsHandler(self.__service.service_config, **settings)
+
+        self._init_settings()
+        self._parse_settings()
+        self._print_settings()
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetEndpoint(
+        self, endpoints : List[Tuple[str, str, Optional[str]]],
+        connection_uuid : Optional[str] = None
+    ) -> List[Union[bool, Exception]]:
+        """ Create/Update service endpoints from a list.
+            Parameters:
+                endpoints: List[Tuple[str, str, Optional[str]]]
+                    List of tuples, each containing a device_uuid,
+                    endpoint_uuid and, optionally, the topology_uuid
+                    of the endpoint to be added.
+                connection_uuid : Optional[str]
+                    If specified, is the UUID of the connection this endpoint is associated to.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for endpoint changes requested.
+                    Return values must be in the same order as the requested
+                    endpoints. If an endpoint is properly added, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        chk_type('endpoints', endpoints, list)
+        if len(endpoints) == 0: return []
+
+        LOGGER.info("{} - Provision service configuration".format(
+            self.__service_label))
+
+        visited = set()
+        results = []
+        for endpoint in endpoints:
+            device_uuid, endpoint_uuid = endpoint[0:2]
+            device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+            device_name = device.name
+
+            LOGGER.info("Device {}".format(device_name))
+            LOGGER.info("\t | Service endpoint UUID: {}".format(endpoint_uuid))
+
+            port_id = find_port_id_in_endpoint_list(device.device_endpoints, endpoint_uuid)
+            LOGGER.info("\t | Service port ID: {}".format(port_id))
+
+            dev_port_key = device_name + "-" + PORT_PREFIX + str(port_id)
+
+            # Skip already visited device ports
+            if dev_port_key in visited:
+                continue
+
+            rules = []
+            actual_rules = -1
+            applied_rules, failed_rules = 0, -1
+
+            # Create and apply rules
+            try:
+                rules = self._create_rules(
+                    device_obj=device, port_id=port_id, action=ConfigActionEnum.CONFIGACTION_SET)
+                actual_rules = len(rules)
+                applied_rules, failed_rules = apply_rules(
+                    task_executor=self.__task_executor,
+                    device_obj=device,
+                    json_config_rules=rules
+                )
+            except Exception as ex:
+                LOGGER.error("Failed to insert L2 rules on device {} due to {}".format(device.name, ex))
+            finally:
+                rules.clear()
+
+            # Ensure correct status
+            results.append(True) if (failed_rules == 0) and (applied_rules == actual_rules) \
+                else results.append(False)
+
+            # You should no longer visit this device port again
+            visited.add(dev_port_key)
+
+            LOGGER.info("Installed {}/{} L2 rules on device {} and port {}".format(
+                applied_rules, actual_rules, device_name, port_id))
+
+        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]]:
+        """ Delete service endpoints from a list.
+            Parameters:
+                endpoints: List[Tuple[str, str, Optional[str]]]
+                    List of tuples, each containing a device_uuid,
+                    endpoint_uuid, and the topology_uuid of the endpoint
+                    to be removed.
+                connection_uuid : Optional[str]
+                    If specified, is the UUID of the connection this endpoint is associated to.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for endpoint deletions requested.
+                    Return values must be in the same order as the requested
+                    endpoints. If an endpoint is properly deleted, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        chk_type('endpoints', endpoints, list)
+        if len(endpoints) == 0: return []
+
+        LOGGER.info("{} - Deprovision service configuration".format(
+            self.__service_label))
+
+        visited = set()
+        results = []
+        for endpoint in endpoints:
+            device_uuid, endpoint_uuid = endpoint[0:2]
+            device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+            device_name = device.name
+
+            LOGGER.info("Device {}".format(device_name))
+            LOGGER.info("\t | Service endpoint UUID: {}".format(endpoint_uuid))
+
+            port_id = find_port_id_in_endpoint_list(device.device_endpoints, endpoint_uuid)
+            LOGGER.info("\t | Service port ID: {}".format(port_id))
+
+            dev_port_key = device_name + "-" + PORT_PREFIX + str(port_id)
+
+            # Skip already visited device ports
+            if dev_port_key in visited:
+                continue
+
+            rules = []
+            actual_rules = -1
+            applied_rules, failed_rules = 0, -1
+
+            # Create and apply rules
+            try:
+                rules = self._create_rules(
+                    device_obj=device, port_id=port_id, action=ConfigActionEnum.CONFIGACTION_DELETE)
+                actual_rules = len(rules)
+                applied_rules, failed_rules = apply_rules(
+                    task_executor=self.__task_executor,
+                    device_obj=device,
+                    json_config_rules=rules
+                )
+            except Exception as ex:
+                LOGGER.error("Failed to insert L2 rules on device {} due to {}".format(device.name, ex))
+            finally:
+                rules.clear()
+
+            # Ensure correct status
+            results.append(True) if (failed_rules == 0) and (applied_rules == actual_rules) \
+                else results.append(False)
+
+            # You should no longer visit this device port again
+            visited.add(dev_port_key)
+
+            LOGGER.info("Deleted {}/{} L2 rules from device {} and port {}".format(
+                applied_rules, actual_rules, device_name, port_id))
+
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetConstraint(self, constraints: List[Tuple[str, Any]]) \
+            -> List[Union[bool, Exception]]:
+        """ Create/Update service constraints.
+            Parameters:
+                constraints: List[Tuple[str, Any]]
+                    List of tuples, each containing a constraint_type and the
+                    new constraint_value to be set.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for constraint changes requested.
+                    Return values must be in the same order as the requested
+                    constraints. If a constraint is properly set, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        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]]:
+        """ Delete service constraints.
+            Parameters:
+                constraints: List[Tuple[str, Any]]
+                    List of tuples, each containing a constraint_type pointing
+                    to the constraint to be deleted, and a constraint_value
+                    containing possible additionally required values to locate
+                    the constraint to be removed.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for constraint deletions requested.
+                    Return values must be in the same order as the requested
+                    constraints. If a constraint is properly deleted, True must
+                    be returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        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]]:
+        """ Create/Update configuration for a list of service resources.
+            Parameters:
+                resources: List[Tuple[str, Any]]
+                    List of tuples, each containing a resource_key pointing to
+                    the resource to be modified, and a resource_value
+                    containing the new value to be set.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for resource key changes requested.
+                    Return values must be in the same order as the requested
+                    resource keys. If a resource is properly set, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        chk_type('resources', resources, list)
+        if len(resources) == 0: return []
+
+        msg = '[SetConfig] Method not implemented. Resources({:s}) are being ignored.'
+        LOGGER.warning(msg.format(str(resources)))
+        return [True for _ in range(len(resources))]
+
+    @metered_subclass_method(METRICS_POOL)
+    def DeleteConfig(self, resources: List[Tuple[str, Any]]) \
+            -> List[Union[bool, Exception]]:
+        """ Delete configuration for a list of service resources.
+            Parameters:
+                resources: List[Tuple[str, Any]]
+                    List of tuples, each containing a resource_key pointing to
+                    the resource to be modified, and a resource_value containing
+                    possible additionally required values to locate the value
+                    to be removed.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for resource key deletions requested.
+                    Return values must be in the same order as the requested
+                    resource keys. If a resource is properly deleted, True must
+                    be returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        chk_type('resources', resources, list)
+        if len(resources) == 0: return []
+
+        msg = '[SetConfig] Method not implemented. Resources({:s}) are being ignored.'
+        LOGGER.warning(msg.format(str(resources)))
+        return [True for _ in range(len(resources))]
+
+    def _init_settings(self):
+        self.__switch_info = {}
+        self.__port_map = {}
+
+        try:
+            self.__settings = self.__settings_handler.get('/settings')
+            LOGGER.info("{} with settings: {}".format(self.__service_label, self.__settings))
+        except Exception as ex:
+            self.__settings = {}
+            LOGGER.error("Failed to parse service settings: {}".format(ex))
+
+    def _default_settings(self):
+        port_list = [
+            {
+                PORT_ID: 1,
+                PORT_TYPE: "host",
+                VLAN_ID: 4094
+            },
+            {
+                PORT_ID: 2,
+                PORT_TYPE: "host",
+                VLAN_ID: 4094
+            },
+        ]
+        fwd_list = [
+            {
+                PORT_ID: 1,
+                HOST_MAC: "fa:16:3e:75:9c:e5"
+            },
+            {
+                PORT_ID: 2,
+                HOST_MAC: "fa:16:3e:e2:af:28"
+            }
+        ]
+        switch_info = {
+            "p4-sw1": {
+                ARCH: TARGET_ARCH_V1MODEL,
+                DPID: 1,
+                PORT_LIST: port_list,
+                FORWARDING_LIST: fwd_list
+            }
+        }
+        self.__settings = {
+            SWITCH_INFO: switch_info
+        }
+
+        # port_map = {
+        #     "p4-sw1": {
+        #         "port-1": {
+        #             PORT_ID: 1,
+        #             PORT_TYPE: PORT_TYPE_HOST,
+        #             VLAN_ID: 4094,
+        #             FORWARDING_LIST: ["fa:16:3e:75:9c:e5"]
+        #         },
+        #         "port-2": {
+        #             PORT_ID: 2,
+        #             PORT_TYPE: PORT_TYPE_HOST,
+        #             VLAN_ID: 4094,
+        #             FORWARDING_LIST: ["fa:16:3e:e2:af:28"]
+        #         }
+        #     }
+        # }
+
+    def _parse_settings(self):
+        #TODO: Pass settings in a correct way
+        try:
+            self.__switch_info = self.__settings[SWITCH_INFO]
+        except Exception as ex:
+            LOGGER.error("Failed to parse settings: {}".format(ex))
+            self._default_settings() #TODO: Remove when bug is fixed
+            self.__switch_info = self.__settings[SWITCH_INFO]
+        assert isinstance(self.__switch_info, dict), "Switch info object must be a map with switch names as keys"
+
+        for switch_name, switch_info in self.__switch_info.items():
+            assert switch_name, "Invalid P4 switch name"
+            assert isinstance(switch_info, dict), "Switch {} info must be a map with arch, dpid, and fwd_list items)"
+            assert switch_info[ARCH] in SUPPORTED_TARGET_ARCH_LIST, \
+                "Switch {} - Supported P4 architectures are: {}".format(switch_name, ','.join(SUPPORTED_TARGET_ARCH_LIST))
+            switch_dpid = switch_info[DPID]
+            assert switch_dpid > 0, "Switch {} - P4 switch dataplane ID must be a positive integer".format(switch_name, switch_info[DPID])
+
+            # Port list
+            port_list = switch_info[PORT_LIST]
+            assert isinstance(port_list, list), "Switch {} port list must be a list with port_id, port_type, and vlan_id items)"
+            for port in port_list:
+                port_id = port[PORT_ID]
+                assert port_id >= 0, "Switch {} - Invalid P4 switch port ID".format(switch_name)
+                port_type = port[PORT_TYPE]
+                assert port_type in PORT_TYPES_STR_VALID, "Switch {} - Valid P4 switch port types are: {}".format(
+                    switch_name, ','.join(PORT_TYPES_STR_VALID))
+                vlan_id = port[VLAN_ID]
+                assert chk_vlan_id(vlan_id), "Switch {} - Invalid VLAN ID for port {}".format(switch_name, port_id)
+                
+                if switch_name not in self.__port_map:
+                    self.__port_map[switch_name] = {}
+                port_key = PORT_PREFIX + str(port_id)
+                if port_key not in self.__port_map[switch_name]:
+                    self.__port_map[switch_name][port_key] = {}
+                self.__port_map[switch_name][port_key][PORT_ID] = port_id
+                self.__port_map[switch_name][port_key][PORT_TYPE] = port_type
+                self.__port_map[switch_name][port_key][VLAN_ID] = vlan_id
+                self.__port_map[switch_name][port_key][FORWARDING_LIST] = []
+
+            # Forwarding list
+            fwd_list = switch_info[FORWARDING_LIST]
+            assert isinstance(fwd_list, list), "Switch {} forwarding list be a list)"
+            for fwd_entry in fwd_list:
+                port_id = fwd_entry[PORT_ID]
+                assert port_id >= 0, "Invalid port ID: {}".format(port_id)
+                host_mac = fwd_entry[HOST_MAC]
+                assert chk_address_mac(host_mac), "Invalid host MAC address {}".format(host_mac)
+
+                # Retrieve entry from the port map
+                switch_port_entry = self._get_switch_port_in_port_map(switch_name, port_id)
+
+                host_facing_port = self._is_host_facing_port(switch_name, port_id)
+                LOGGER.info("Switch {} - Port {}: Is host facing: {}".format(switch_name, port_id, "True" if host_facing_port else "False"))
+                switch_port_entry[FORWARDING_LIST].append(host_mac)
+
+    def _print_settings(self):
+        LOGGER.info("--------------- {} settings ---------------".format(self.__service.name))
+        LOGGER.info("--- Topology info")
+        for switch_name, switch_info in self.__switch_info.items():
+            LOGGER.info("\t Device {}".format(switch_name))
+            LOGGER.info("\t\t| Target P4 architecture: {}".format(switch_info[ARCH]))
+            LOGGER.info("\t\t|          Data plane ID: {}".format(switch_info[DPID]))
+            LOGGER.info("\t\t|               Port map: {}".format(self.__port_map[switch_name]))
+        LOGGER.info("-------------------------------------------------------")
+
+    def _get_switch_port_in_port_map(self, switch_name : str, port_id : int) -> Dict:
+        assert switch_name, "A valid switch name must be used as a key to the port map"
+        assert port_id > 0, "A valid switch port ID must be used as a key to a switch's port map"
+        switch_entry = self.__port_map[switch_name]
+        assert switch_entry, "Switch {} does not exist in the port map".format(switch_name)
+        port_key = PORT_PREFIX + str(port_id)
+        assert switch_entry[port_key], "Port with ID {} does not exist in the switch map".format(port_id)
+
+        return switch_entry[port_key]
+
+    def _get_port_type_of_switch_port(self, switch_name : str, port_id : int) -> str:
+        switch_port_entry = self._get_switch_port_in_port_map(switch_name, port_id)
+        return switch_port_entry[PORT_TYPE]
+
+    def _get_vlan_id_of_switch_port(self, switch_name : str, port_id : int) -> int:
+        switch_port_entry = self._get_switch_port_in_port_map(switch_name, port_id)
+        return switch_port_entry[VLAN_ID]
+
+    def _get_fwd_list_of_switch_port(self, switch_name : str, port_id : int) -> List [Tuple]:
+        switch_port_entry = self._get_switch_port_in_port_map(switch_name, port_id)
+        return switch_port_entry[FORWARDING_LIST]
+
+    def _is_host_facing_port(self, switch_name : str, port_id : int) -> bool:
+        return self._get_port_type_of_switch_port(switch_name, port_id) == PORT_TYPE_HOST
+
+    def _create_rules(self, device_obj : Device, port_id : int, action : ConfigActionEnum): # type: ignore
+        dev_name = device_obj.name
+
+        host_facing_port = self._is_host_facing_port(dev_name, port_id)
+        LOGGER.info("\t | Service endpoint is host facing: {}".format("True" if host_facing_port else "False"))
+
+        rules  = []
+
+        try:
+            ### Port setup rules
+            if host_facing_port:
+                rules += rules_set_up_port_host(
+                    port=port_id,
+                    vlan_id=self._get_vlan_id_of_switch_port(switch_name=dev_name, port_id=port_id),
+                    action=action
+                )
+            else:
+                rules += rules_set_up_port_switch(
+                    port=port_id,
+                    vlan_id=self._get_vlan_id_of_switch_port(switch_name=dev_name, port_id=port_id),
+                    action=action
+                )
+        except Exception as ex:
+            LOGGER.error("Error while creating port setup rules")
+            raise Exception(ex)
+
+        fwd_list = self._get_fwd_list_of_switch_port(switch_name=dev_name, port_id=port_id)
+        for mac in fwd_list:
+            LOGGER.info("Switch {} - Port {} - Creating rule for host MAC: {}".format(dev_name, port_id, mac))
+            try:
+                ### Bridging rules
+                rules += rules_set_up_fwd_bridging(
+                    vlan_id=self._get_vlan_id_of_switch_port(switch_name=dev_name, port_id=port_id),
+                    eth_dst=mac,
+                    egress_port=port_id,
+                    action=action
+                )
+            except Exception as ex:
+                LOGGER.error("Error while creating bridging rules")
+                raise Exception(ex)
+        
+        try:
+            ### Next output rule
+            rules += rules_set_up_next_output_simple(
+                egress_port=port_id,
+                action=action
+            )
+        except Exception as ex:
+            LOGGER.error("Error while creating next output L2 rules")
+            raise Exception(ex)
+
+        return rules
diff --git a/src/tests/p4-fabric-tna/README.md b/src/tests/p4-fabric-tna/README.md
index 10303009d..b96bb02e9 100644
--- a/src/tests/p4-fabric-tna/README.md
+++ b/src/tests/p4-fabric-tna/README.md
@@ -125,6 +125,20 @@ bash src/tests/p4-fabric-tna/run_test_02b_sbi_deprovision_int_l2_l3_acl.sh
 To avoid interacting with the switch using low-level P4 rules (via the SBI), we created modular network services, which allow users to easily provision L2, L3, ACL, and INT network functions.
 These services require users to define the service endpoints as well as some high-level service configuration, while leaving the rest of complexity to tailored service handlers that interact with the SBI on behalf of the user.
 
+#### Provision L2 network service via the Service API
+
+```shell
+cd ~/tfs-ctrl/
+bash src/tests/p4-fabric-tna/run_test_03a_service_provision_l2.sh
+```
+
+#### Deprovision L2 network service via the Service API
+
+```shell
+cd ~/tfs-ctrl/
+bash src/tests/p4-fabric-tna/run_test_03b_service_deprovision_l2.sh
+```
+
 #### Provision INT service via the Service API
 
 ```shell
diff --git a/src/tests/p4-fabric-tna/descriptors/service-create-l2-simple.json b/src/tests/p4-fabric-tna/descriptors/service-create-l2-simple.json
new file mode 100644
index 000000000..5a659f3d9
--- /dev/null
+++ b/src/tests/p4-fabric-tna/descriptors/service-create-l2-simple.json
@@ -0,0 +1,63 @@
+{
+    "services": [
+        {
+            "service_id": {
+                "context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "p4-service-l2"}
+            },
+            "name": "p4-service-l2",
+            "service_type": "SERVICETYPE_L2NM",
+            "service_status": {"service_status": "SERVICESTATUS_PLANNED"},
+            "service_endpoint_ids": [
+                {
+                    "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+                    "endpoint_uuid": {"uuid": "1"}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+                    "endpoint_uuid": {"uuid": "2"}
+                }
+            ],
+            "service_config": {
+                "config_rules": [
+                    {
+                        "action": "CONFIGACTION_SET",
+                        "custom": {
+                            "resource_key": "/settings",
+                            "resource_value": {
+                                "switch_info": {
+                                    "p4-sw1": {
+                                        "arch": "v1model",
+                                        "dpid": 1,
+                                        "port_list": [
+                                            {
+                                                "port_id": 1,
+                                                "port_type": "host",
+                                                "vlan_id": 4094
+                                            },
+                                            {
+                                                "port_id": 2,
+                                                "port_type": "host",
+                                                "vlan_id": 4094
+                                            }
+                                        ],
+                                        "fwd_list": [
+                                            {
+                                                "port_id": 1,
+                                                "host_mac": "fa:16:3e:75:9c:e5"
+                                            },
+                                            {
+                                                "port_id": 2,
+                                                "host_mac": "fa:16:3e:e2:af:28"
+                                            }
+                                        ]
+                                    }
+                                }
+                            }
+                        }
+                    }
+                ]
+            },
+            "service_constraints": []
+        }
+    ]
+}
diff --git a/src/tests/p4-fabric-tna/run_test_03a_service_provision_l2.sh b/src/tests/p4-fabric-tna/run_test_03a_service_provision_l2.sh
new file mode 100755
index 000000000..6da590469
--- /dev/null
+++ b/src/tests/p4-fabric-tna/run_test_03a_service_provision_l2.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source tfs_runtime_env_vars.sh
+python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_l2.py
diff --git a/src/tests/p4-fabric-tna/run_test_03b_service_deprovision_l2.sh b/src/tests/p4-fabric-tna/run_test_03b_service_deprovision_l2.sh
new file mode 100755
index 000000000..fdb30c2fc
--- /dev/null
+++ b/src/tests/p4-fabric-tna/run_test_03b_service_deprovision_l2.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source tfs_runtime_env_vars.sh
+python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_l2.py
diff --git a/src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_l2.py b/src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_l2.py
new file mode 100644
index 000000000..87ef21285
--- /dev/null
+++ b/src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_l2.py
@@ -0,0 +1,78 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+from common.proto.context_pb2 import ServiceId, ServiceStatusEnum, ServiceTypeEnum
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from common.tools.object_factory.Service import json_service_id
+from context.client.ContextClient import ContextClient
+from service.client.ServiceClient import ServiceClient
+from tests.Fixtures import context_client, service_client # pylint: disable=unused-import
+from tests.tools.test_tools_p4 import *
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+def test_service_deletion_l2(
+    context_client : ContextClient, # pylint: disable=redefined-outer-name
+    service_client : ServiceClient  # pylint: disable=redefined-outer-name
+) -> None:
+    # Get the current number of devices
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    LOGGER.warning('Devices[{:d}] = {:s}'.format(len(response.devices), grpc_message_to_json_string(response)))
+
+    # Total devices
+    dev_nb = len(response.devices)
+    assert dev_nb == DEV_NB
+
+    # P4 devices
+    p4_dev_nb = identify_number_of_p4_devices(response.devices)
+    assert p4_dev_nb == P4_DEV_NB
+
+    # Get the current number of rules in the P4 devices
+    p4_rules_before_deletion = get_number_of_rules(response.devices)
+
+    # Get the current number of services
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    services_nb_before_deletion = len(response.services)
+    assert verify_active_service_type(response.services, ServiceTypeEnum.SERVICETYPE_L2NM)
+
+    for service in response.services:
+        # Ignore services of other types
+        if service.service_type != ServiceTypeEnum.SERVICETYPE_L2NM:
+            continue
+
+        service_id = service.service_id
+        assert service_id
+
+        service_uuid = service_id.service_uuid.uuid
+        context_uuid = service_id.context_id.context_uuid.uuid
+        assert service.service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE
+
+        # Delete L2 service
+        service_client.DeleteService(ServiceId(**json_service_id(service_uuid, json_context_id(context_uuid))))
+
+    # Get an updated view of the services
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    services_nb_after_deletion = len(response.services)
+    assert services_nb_after_deletion == services_nb_before_deletion - 1, "Exactly one new service must be deleted"
+
+    # Get an updated view of the devices
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    p4_rules_after_deletion = get_number_of_rules(response.devices)
+
+    rules_diff = p4_rules_before_deletion - p4_rules_after_deletion
+
+    assert p4_rules_after_deletion < p4_rules_before_deletion, "L2 service must contain some rules"
+    assert rules_diff == P4_DEV_NB * L2_RULES, "L2 service must contain {} rules per device".format(L2_RULES)
diff --git a/src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_l2.py b/src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_l2.py
new file mode 100644
index 000000000..a42c05546
--- /dev/null
+++ b/src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_l2.py
@@ -0,0 +1,73 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+from common.proto.context_pb2 import ServiceStatusEnum, ServiceTypeEnum
+from common.tools.descriptor.Loader import DescriptorLoader, check_descriptor_load_results
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from service.client.ServiceClient import ServiceClient
+from tests.Fixtures import context_client, device_client, service_client # pylint: disable=unused-import
+from tests.tools.test_tools_p4 import *
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+def test_service_creation_l2(
+    context_client : ContextClient, # pylint: disable=redefined-outer-name
+    device_client  : DeviceClient,  # pylint: disable=redefined-outer-name
+    service_client : ServiceClient  # pylint: disable=redefined-outer-name
+) -> None:
+    # Get the current number of services
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    services_nb_before = len(response.services)
+
+    # Get the current number of devices
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    LOGGER.warning('Devices[{:d}] = {:s}'.format(len(response.devices), grpc_message_to_json_string(response)))
+
+    # Total devices
+    dev_nb = len(response.devices)
+    assert dev_nb == DEV_NB
+
+    # P4 devices
+    p4_dev_nb = identify_number_of_p4_devices(response.devices)
+    assert p4_dev_nb == P4_DEV_NB
+
+    # Get the current number of rules in the P4 devices
+    p4_rules_before = get_number_of_rules(response.devices)
+
+    # Load service
+    descriptor_loader = DescriptorLoader(
+        descriptors_file=DESC_FILE_SERVICE_CREATE_L2_SIMPLE,
+        context_client=context_client, device_client=device_client, service_client=service_client
+    )
+    results = descriptor_loader.process()
+    check_descriptor_load_results(results, descriptor_loader)
+
+    # Get an updated view of the services
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    services_nb_after = len(response.services)
+    assert services_nb_after == services_nb_before + 1, "Exactly one new service must be in place"
+    assert verify_active_service_type(response.services, ServiceTypeEnum.SERVICETYPE_L2NM)
+
+    # Get an updated view of the devices
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    p4_rules_after = get_number_of_rules(response.devices)
+
+    rules_diff = p4_rules_after - p4_rules_before
+
+    assert p4_rules_after > p4_rules_before, "L2 service must install some rules"
+    assert rules_diff == P4_DEV_NB * L2_RULES, "L2 service must install {} rules per device".format(L2_RULES)
diff --git a/src/tests/tools/test_tools_p4.py b/src/tests/tools/test_tools_p4.py
index 65257aefc..aa37f9e2c 100644
--- a/src/tests/tools/test_tools_p4.py
+++ b/src/tests/tools/test_tools_p4.py
@@ -96,9 +96,9 @@ DESC_FILE_SERVICE_CREATE_INT = os.path.join(TEST_PATH, 'service-create-int.json'
 assert os.path.exists(DESC_FILE_SERVICE_CREATE_INT),\
     "Invalid path to the SD-Fabric INT service descriptor"
 
-DESC_FILE_SERVICE_CREATE_L2 = os.path.join(TEST_PATH, 'service-create-l2.json')
-assert os.path.exists(DESC_FILE_SERVICE_CREATE_L2),\
-    "Invalid path to the SD-Fabric L2 service descriptor"
+DESC_FILE_SERVICE_CREATE_L2_SIMPLE = os.path.join(TEST_PATH, 'service-create-l2-simple.json')
+assert os.path.exists(DESC_FILE_SERVICE_CREATE_L2_SIMPLE),\
+    "Invalid path to the SD-Fabric L2 simple service descriptor"
 
 DESC_FILE_SERVICE_CREATE_L3 = os.path.join(TEST_PATH, 'service-create-l3.json')
 assert os.path.exists(DESC_FILE_SERVICE_CREATE_L3),\
-- 
GitLab


From 918206dc6016b5a67aeae8ead548a51430ada6de Mon Sep 17 00:00:00 2001
From: "Georgios P. Katsikas" <gkatsikas@ubitech.eu>
Date: Mon, 31 Mar 2025 07:17:43 +0000
Subject: [PATCH 08/14] feat: P4 L3 service handler

---
 .../service/service_handlers/__init__.py      |   7 +
 .../p4_fabric_tna_l3/__init__.py              |  13 +
 .../p4_fabric_tna_l3_service_handler.py       | 505 ++++++++++++++++++
 src/tests/p4-fabric-tna/README.md             |  14 +
 .../descriptors/service-create-l3.json        |  67 +++
 .../run_test_04a_service_provision_l3.sh      |  17 +
 .../run_test_04b_service_deprovision_l3.sh    |  17 +
 .../test_functional_service_deprovision_l3.py |  78 +++
 .../test_functional_service_provision_l3.py   |  73 +++
 9 files changed, 791 insertions(+)
 create mode 100644 src/service/service/service_handlers/p4_fabric_tna_l3/__init__.py
 create mode 100644 src/service/service/service_handlers/p4_fabric_tna_l3/p4_fabric_tna_l3_service_handler.py
 create mode 100644 src/tests/p4-fabric-tna/descriptors/service-create-l3.json
 create mode 100755 src/tests/p4-fabric-tna/run_test_04a_service_provision_l3.sh
 create mode 100755 src/tests/p4-fabric-tna/run_test_04b_service_deprovision_l3.sh
 create mode 100644 src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_l3.py
 create mode 100644 src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_l3.py

diff --git a/src/service/service/service_handlers/__init__.py b/src/service/service/service_handlers/__init__.py
index 756d0fffb..0ecef7c22 100644
--- a/src/service/service/service_handlers/__init__.py
+++ b/src/service/service/service_handlers/__init__.py
@@ -28,6 +28,7 @@ from .microwave.MicrowaveServiceHandler import MicrowaveServiceHandler
 from .p4_dummy_l1.p4_dummy_l1_service_handler import P4DummyL1ServiceHandler
 from .p4_fabric_tna_int.p4_fabric_tna_int_service_handler import P4FabricINTServiceHandler
 from .p4_fabric_tna_l2_simple.p4_fabric_tna_l2_simple_service_handler import P4FabricL2SimpleServiceHandler
+from .p4_fabric_tna_l3.p4_fabric_tna_l3_service_handler import P4FabricL3ServiceHandler
 from .tapi_tapi.TapiServiceHandler import TapiServiceHandler
 from .tapi_xr.TapiXrServiceHandler import TapiXrServiceHandler
 from .optical_tfs.OpticalTfsServiceHandler import OpticalTfsServiceHandler
@@ -125,6 +126,12 @@ SERVICE_HANDLERS = [
             FilterFieldEnum.DEVICE_DRIVER: DeviceDriverEnum.DEVICEDRIVER_P4,
         }
     ]),
+    (P4FabricL3ServiceHandler, [
+        {
+            FilterFieldEnum.SERVICE_TYPE: ServiceTypeEnum.SERVICETYPE_L3NM,
+            FilterFieldEnum.DEVICE_DRIVER: DeviceDriverEnum.DEVICEDRIVER_P4,
+        }
+    ]),
     (L2NM_IETFL2VPN_ServiceHandler, [
         {
             FilterFieldEnum.SERVICE_TYPE  : ServiceTypeEnum.SERVICETYPE_L2NM,
diff --git a/src/service/service/service_handlers/p4_fabric_tna_l3/__init__.py b/src/service/service/service_handlers/p4_fabric_tna_l3/__init__.py
new file mode 100644
index 000000000..023830645
--- /dev/null
+++ b/src/service/service/service_handlers/p4_fabric_tna_l3/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/src/service/service/service_handlers/p4_fabric_tna_l3/p4_fabric_tna_l3_service_handler.py b/src/service/service/service_handlers/p4_fabric_tna_l3/p4_fabric_tna_l3_service_handler.py
new file mode 100644
index 000000000..849d1db92
--- /dev/null
+++ b/src/service/service/service_handlers/p4_fabric_tna_l3/p4_fabric_tna_l3_service_handler.py
@@ -0,0 +1,505 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Service handler for P4-based static L3 routing using the SD-Fabric P4 dataplane
+for BMv2 and Intel Tofino switches.
+"""
+
+import logging
+from typing import Any, List, Dict, Optional, Tuple, Union
+from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method
+from common.proto.context_pb2 import ConfigActionEnum, DeviceId, Service, Device
+from common.tools.object_factory.Device import json_device_id
+from common.type_checkers.Checkers import chk_type, chk_address_mac, chk_address_ipv4, chk_prefix_len_ipv4
+from service.service.service_handler_api._ServiceHandler import _ServiceHandler
+from service.service.service_handler_api.SettingsHandler import SettingsHandler
+from service.service.service_handlers.p4_fabric_tna_commons.p4_fabric_tna_commons import *
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
+
+LOGGER = logging.getLogger(__name__)
+
+METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'p4_fabric_tna_l3'})
+
+class P4FabricL3ServiceHandler(_ServiceHandler):
+    def __init__(   # pylint: disable=super-init-not-called
+        self, service : Service, task_executor : TaskExecutor, **settings # type: ignore
+    ) -> None:
+        """ Initialize Driver.
+            Parameters:
+                service
+                    The service instance (gRPC message) to be managed.
+                task_executor
+                    An instance of Task Executor providing access to the
+                    service handlers factory, the context and device clients,
+                    and an internal cache of already-loaded gRPC entities.
+                **settings
+                    Extra settings required by the service handler.
+
+        """
+        self.__service_label = "P4 static L3 connectivity service"
+        self.__service = service
+        self.__task_executor = task_executor
+        self.__settings_handler = SettingsHandler(self.__service.service_config, **settings)
+
+        self._init_settings()
+        self._parse_settings()
+        self._print_settings()
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetEndpoint(
+        self, endpoints : List[Tuple[str, str, Optional[str]]],
+        connection_uuid : Optional[str] = None
+    ) -> List[Union[bool, Exception]]:
+        """ Create/Update service endpoints from a list.
+            Parameters:
+                endpoints: List[Tuple[str, str, Optional[str]]]
+                    List of tuples, each containing a device_uuid,
+                    endpoint_uuid and, optionally, the topology_uuid
+                    of the endpoint to be added.
+                connection_uuid : Optional[str]
+                    If specified, is the UUID of the connection this endpoint is associated to.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for endpoint changes requested.
+                    Return values must be in the same order as the requested
+                    endpoints. If an endpoint is properly added, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        chk_type('endpoints', endpoints, list)
+        if len(endpoints) == 0: return []
+
+        LOGGER.info("{} - Provision service configuration".format(
+            self.__service_label))
+
+        visited = set()
+        results = []
+        for endpoint in endpoints:
+            device_uuid, endpoint_uuid = endpoint[0:2]
+            device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+            device_name = device.name
+
+            LOGGER.info("Device {}".format(device_name))
+            LOGGER.info("\t | Service endpoint UUID: {}".format(endpoint_uuid))
+
+            port_id = find_port_id_in_endpoint_list(device.device_endpoints, endpoint_uuid)
+            LOGGER.info("\t | Service port ID: {}".format(port_id))
+
+            dev_port_key = device_name + "-" + PORT_PREFIX + str(port_id)
+
+            # Skip already visited device ports
+            if dev_port_key in visited:
+                continue
+
+            rules = []
+            actual_rules = -1
+            applied_rules, failed_rules = 0, -1
+
+            # Create and apply rules
+            try:
+                rules = self._create_rules(
+                    device_obj=device, port_id=port_id, action=ConfigActionEnum.CONFIGACTION_SET)
+                actual_rules = len(rules)
+                applied_rules, failed_rules = apply_rules(
+                    task_executor=self.__task_executor,
+                    device_obj=device,
+                    json_config_rules=rules
+                )
+            except Exception as ex:
+                LOGGER.error("Failed to insert L3 rules on device {} due to {}".format(device.name, ex))
+            finally:
+                rules.clear()
+
+            # Ensure correct status
+            results.append(True) if (failed_rules == 0) and (applied_rules == actual_rules) \
+                else results.append(False)
+
+            # You should no longer visit this device port again
+            visited.add(dev_port_key)
+
+            LOGGER.info("Installed {}/{} L3 rules on device {} and port {}".format(
+                applied_rules, actual_rules, device_name, port_id))
+
+        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]]:
+        """ Delete service endpoints from a list.
+            Parameters:
+                endpoints: List[Tuple[str, str, Optional[str]]]
+                    List of tuples, each containing a device_uuid,
+                    endpoint_uuid, and the topology_uuid of the endpoint
+                    to be removed.
+                connection_uuid : Optional[str]
+                    If specified, is the UUID of the connection this endpoint is associated to.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for endpoint deletions requested.
+                    Return values must be in the same order as the requested
+                    endpoints. If an endpoint is properly deleted, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        chk_type('endpoints', endpoints, list)
+        if len(endpoints) == 0: return []
+
+        LOGGER.info("{} - Deprovision service configuration".format(
+            self.__service_label))
+
+        visited = set()
+        results = []
+        for endpoint in endpoints:
+            device_uuid, endpoint_uuid = endpoint[0:2]
+            device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+            device_name = device.name
+
+            LOGGER.info("Device {}".format(device_name))
+            LOGGER.info("\t | Service endpoint UUID: {}".format(endpoint_uuid))
+
+            port_id = find_port_id_in_endpoint_list(device.device_endpoints, endpoint_uuid)
+            LOGGER.info("\t | Service port ID: {}".format(port_id))
+
+            dev_port_key = device_name + "-" + PORT_PREFIX + str(port_id)
+
+            # Skip already visited device ports
+            if dev_port_key in visited:
+                continue
+
+            rules = []
+            actual_rules = -1
+            applied_rules, failed_rules = 0, -1
+
+            # Create and apply rules
+            try:
+                rules = self._create_rules(
+                    device_obj=device, port_id=port_id, action=ConfigActionEnum.CONFIGACTION_DELETE)
+                actual_rules = len(rules)
+                applied_rules, failed_rules = apply_rules(
+                    task_executor=self.__task_executor,
+                    device_obj=device,
+                    json_config_rules=rules
+                )
+            except Exception as ex:
+                LOGGER.error("Failed to insert L3 rules on device {} due to {}".format(device.name, ex))
+            finally:
+                rules.clear()
+
+            # Ensure correct status
+            results.append(True) if (failed_rules == 0) and (applied_rules == actual_rules) \
+                else results.append(False)
+
+            # You should no longer visit this device port again
+            visited.add(dev_port_key)
+
+            LOGGER.info("Deleted {}/{} L3 rules from device {} and port {}".format(
+                applied_rules, actual_rules, device_name, port_id))
+
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetConstraint(self, constraints: List[Tuple[str, Any]]) \
+            -> List[Union[bool, Exception]]:
+        """ Create/Update service constraints.
+            Parameters:
+                constraints: List[Tuple[str, Any]]
+                    List of tuples, each containing a constraint_type and the
+                    new constraint_value to be set.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for constraint changes requested.
+                    Return values must be in the same order as the requested
+                    constraints. If a constraint is properly set, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        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]]:
+        """ Delete service constraints.
+            Parameters:
+                constraints: List[Tuple[str, Any]]
+                    List of tuples, each containing a constraint_type pointing
+                    to the constraint to be deleted, and a constraint_value
+                    containing possible additionally required values to locate
+                    the constraint to be removed.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for constraint deletions requested.
+                    Return values must be in the same order as the requested
+                    constraints. If a constraint is properly deleted, True must
+                    be returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        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]]:
+        """ Create/Update configuration for a list of service resources.
+            Parameters:
+                resources: List[Tuple[str, Any]]
+                    List of tuples, each containing a resource_key pointing to
+                    the resource to be modified, and a resource_value
+                    containing the new value to be set.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for resource key changes requested.
+                    Return values must be in the same order as the requested
+                    resource keys. If a resource is properly set, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        chk_type('resources', resources, list)
+        if len(resources) == 0: return []
+
+        msg = '[SetConfig] Method not implemented. Resources({:s}) are being ignored.'
+        LOGGER.warning(msg.format(str(resources)))
+        return [True for _ in range(len(resources))]
+
+    @metered_subclass_method(METRICS_POOL)
+    def DeleteConfig(self, resources: List[Tuple[str, Any]]) \
+            -> List[Union[bool, Exception]]:
+        """ Delete configuration for a list of service resources.
+            Parameters:
+                resources: List[Tuple[str, Any]]
+                    List of tuples, each containing a resource_key pointing to
+                    the resource to be modified, and a resource_value containing
+                    possible additionally required values to locate the value
+                    to be removed.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for resource key deletions requested.
+                    Return values must be in the same order as the requested
+                    resource keys. If a resource is properly deleted, True must
+                    be returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        chk_type('resources', resources, list)
+        if len(resources) == 0: return []
+
+        msg = '[SetConfig] Method not implemented. Resources({:s}) are being ignored.'
+        LOGGER.warning(msg.format(str(resources)))
+        return [True for _ in range(len(resources))]
+
+    def _init_settings(self):
+        self.__switch_info = {}
+        self.__port_map = {}
+
+        try:
+            self.__settings = self.__settings_handler.get('/settings')
+            LOGGER.info("{} with settings: {}".format(self.__service_label, self.__settings))
+        except Exception as ex:
+            self.__settings = {}
+            LOGGER.error("Failed to parse service settings: {}".format(ex))
+
+    def _default_settings(self):
+        port_list = [
+            {
+                PORT_ID: 1,
+                PORT_TYPE: "host"
+            },
+            {
+                PORT_ID: 2,
+                PORT_TYPE: "host"
+            },
+        ]
+        routing_list = [
+            {
+                PORT_ID: 1,
+                IPV4_DST: "10.158.72.11",
+                IPV4_PREFIX_LEN: 32,
+                MAC_SRC: "fa:16:3e:e2:af:28",
+                MAC_DST: "fa:16:3e:75:9c:e5"
+            },
+            {
+                PORT_ID: 2,
+                IPV4_DST: "172.16.10.9",
+                IPV4_PREFIX_LEN: 32,
+                MAC_SRC: "fa:16:3e:75:9c:e5",
+                MAC_DST: "fa:16:3e:e2:af:28"
+            }
+        ]
+        switch_info = {
+            "p4-sw1": {
+                ARCH: TARGET_ARCH_V1MODEL,
+                DPID: 1,
+                PORT_LIST: port_list,
+                ROUTING_LIST: routing_list
+            }
+        }
+        self.__settings = {
+            SWITCH_INFO: switch_info
+        }
+
+        port_map = {
+            "p4-sw1": {
+                "port-1": {
+                    PORT_ID: 1,
+                    PORT_TYPE: PORT_TYPE_HOST,
+                    ROUTING_LIST: [
+                        {
+                            IPV4_DST: "10.158.72.11",
+                            IPV4_PREFIX_LEN: 32,
+                            MAC_SRC: "fa:16:3e:e2:af:28",
+                            MAC_DST: "fa:16:3e:75:9c:e5"
+                        }
+                    ]
+                },
+                "port-2": {
+                    PORT_ID: 2,
+                    PORT_TYPE: PORT_TYPE_HOST,
+                    ROUTING_LIST: [
+                        {
+                            IPV4_DST: "172.16.10.9",
+                            IPV4_PREFIX_LEN: 32,
+                            MAC_SRC: "fa:16:3e:75:9c:e5",
+                            MAC_DST: "fa:16:3e:e2:af:28"
+                        }
+                    ]
+                }
+            }
+        }
+
+    def _parse_settings(self):
+        #TODO: Pass settings in a correct way
+        try:
+            self.__switch_info = self.__settings[SWITCH_INFO]
+        except Exception as ex:
+            LOGGER.error("Failed to parse settings: {}".format(ex))
+            self._default_settings() #TODO: Remove when bug is fixed
+            self.__switch_info = self.__settings[SWITCH_INFO]
+        assert isinstance(self.__switch_info, dict), "Switch info object must be a map with switch names as keys"
+
+        for switch_name, switch_info in self.__switch_info.items():
+            assert switch_name, "Invalid P4 switch name"
+            assert isinstance(switch_info, dict), "Switch {} info must be a map with arch, dpid, and fwd_list items)"
+            assert switch_info[ARCH] in SUPPORTED_TARGET_ARCH_LIST, \
+                "Switch {} - Supported P4 architectures are: {}".format(switch_name, ','.join(SUPPORTED_TARGET_ARCH_LIST))
+            switch_dpid = switch_info[DPID]
+            assert switch_dpid > 0, "Switch {} - P4 switch dataplane ID must be a positive integer".format(switch_name, switch_info[DPID])
+
+            # Port list
+            port_list = switch_info[PORT_LIST]
+            assert isinstance(port_list, list), "Switch {} port list must be a list with port_id and port_type items)"
+            for port in port_list:
+                port_id = port[PORT_ID]
+                assert port_id >= 0, "Switch {} - Invalid P4 switch port ID".format(switch_name)
+                port_type = port[PORT_TYPE]
+                assert port_type in PORT_TYPES_STR_VALID, "Switch {} - Valid P4 switch port types are: {}".format(
+                    switch_name, ','.join(PORT_TYPES_STR_VALID))
+                
+                if switch_name not in self.__port_map:
+                    self.__port_map[switch_name] = {}
+                port_key = PORT_PREFIX + str(port_id)
+                if port_key not in self.__port_map[switch_name]:
+                    self.__port_map[switch_name][port_key] = {}
+                self.__port_map[switch_name][port_key][PORT_ID] = port_id
+                self.__port_map[switch_name][port_key][PORT_TYPE] = port_type
+                self.__port_map[switch_name][port_key][ROUTING_LIST] = []
+
+            # Routing list
+            routing_list = switch_info[ROUTING_LIST]
+            assert isinstance(routing_list, list), "Switch {} routing list be a list)"
+            for rt_entry in routing_list:
+                port_id = rt_entry[PORT_ID]
+                assert port_id >= 0, "Invalid port ID: {}".format(port_id)
+                ipv4_dst = rt_entry[IPV4_DST]
+                assert chk_address_ipv4(ipv4_dst), "Invalid destination IPv4 address {}".format(ipv4_dst)
+                ipv4_prefix_len = rt_entry[IPV4_PREFIX_LEN]
+                assert chk_prefix_len_ipv4(ipv4_prefix_len), "Invalid IPv4 address prefix length {}".format(ipv4_prefix_len)
+                mac_src = rt_entry[MAC_SRC]
+                assert chk_address_mac(mac_src), "Invalid source MAC address {}".format(mac_src)
+                mac_dst = rt_entry[MAC_DST]
+                assert chk_address_mac(mac_dst), "Invalid destination MAC address {}".format(mac_dst)
+
+                # Retrieve entry from the port map
+                switch_port_entry = self._get_switch_port_in_port_map(switch_name, port_id)
+
+                # Add routing entry
+                switch_port_entry[ROUTING_LIST].append(
+                    {
+                        PORT_ID: port_id,
+                        IPV4_DST: ipv4_dst,
+                        IPV4_PREFIX_LEN: ipv4_prefix_len,
+                        MAC_SRC: mac_src,
+                        MAC_DST: mac_dst
+                    }
+                )
+
+    def _print_settings(self):
+        LOGGER.info("--------------- {} settings ---------------".format(self.__service.name))
+        LOGGER.info("--- Topology info")
+        for switch_name, switch_info in self.__switch_info.items():
+            LOGGER.info("\t Device {}".format(switch_name))
+            LOGGER.info("\t\t| Target P4 architecture: {}".format(switch_info[ARCH]))
+            LOGGER.info("\t\t|          Data plane ID: {}".format(switch_info[DPID]))
+            LOGGER.info("\t\t|               Port map: {}".format(self.__port_map[switch_name]))
+        LOGGER.info("-------------------------------------------------------")
+
+    def _get_switch_port_in_port_map(self, switch_name : str, port_id : int) -> Dict:
+        assert switch_name, "A valid switch name must be used as a key to the port map"
+        assert port_id > 0, "A valid switch port ID must be used as a key to a switch's port map"
+        switch_entry = self.__port_map[switch_name]
+        assert switch_entry, "Switch {} does not exist in the port map".format(switch_name)
+        port_key = PORT_PREFIX + str(port_id)
+        assert switch_entry[port_key], "Port with ID {} does not exist in the switch map".format(port_id)
+
+        return switch_entry[port_key]
+
+    def _get_routing_list_of_switch_port(self, switch_name : str, port_id : int) -> List [Tuple]:
+        switch_port_entry = self._get_switch_port_in_port_map(switch_name, port_id)
+        return switch_port_entry[ROUTING_LIST]
+
+    def _create_rules(self, device_obj : Device, port_id : int, action : ConfigActionEnum): # type: ignore
+        dev_name = device_obj.name
+
+        rules  = []
+
+        ### Static routing rules
+        routing_list = self._get_routing_list_of_switch_port(switch_name=dev_name, port_id=port_id)
+        for rt_entry in routing_list:
+            try:
+                rules += rules_set_up_next_routing_simple(
+                    egress_port=port_id,
+                    eth_src=rt_entry[MAC_SRC],
+                    eth_dst=rt_entry[MAC_DST],
+                    action=action
+                )
+                rules += rules_set_up_routing(
+                    ipv4_dst=rt_entry[IPV4_DST],
+                    ipv4_prefix_len=rt_entry[IPV4_PREFIX_LEN],
+                    egress_port=port_id,
+                    action=action
+                )
+            except Exception as ex:
+                LOGGER.error("Error while creating static L3 routing rules")
+                raise Exception(ex)
+
+        return rules
diff --git a/src/tests/p4-fabric-tna/README.md b/src/tests/p4-fabric-tna/README.md
index b96bb02e9..f6bc2dd0c 100644
--- a/src/tests/p4-fabric-tna/README.md
+++ b/src/tests/p4-fabric-tna/README.md
@@ -139,6 +139,20 @@ cd ~/tfs-ctrl/
 bash src/tests/p4-fabric-tna/run_test_03b_service_deprovision_l2.sh
 ```
 
+#### Provision L3 network service via the Service API
+
+```shell
+cd ~/tfs-ctrl/
+bash src/tests/p4-fabric-tna/run_test_04a_service_provision_l3.sh
+```
+
+#### Deprovision L3 network service via the Service API
+
+```shell
+cd ~/tfs-ctrl/
+bash src/tests/p4-fabric-tna/run_test_04b_service_deprovision_l3.sh
+```
+
 #### Provision INT service via the Service API
 
 ```shell
diff --git a/src/tests/p4-fabric-tna/descriptors/service-create-l3.json b/src/tests/p4-fabric-tna/descriptors/service-create-l3.json
new file mode 100644
index 000000000..7d8153e7a
--- /dev/null
+++ b/src/tests/p4-fabric-tna/descriptors/service-create-l3.json
@@ -0,0 +1,67 @@
+{
+    "services": [
+        {
+            "service_id": {
+                "context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "p4-service-l3"}
+            },
+            "name": "p4-service-l3",
+            "service_type": "SERVICETYPE_L3NM",
+            "service_status": {"service_status": "SERVICESTATUS_PLANNED"},
+            "service_endpoint_ids": [
+                {
+                    "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+                    "endpoint_uuid": {"uuid": "1"}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+                    "endpoint_uuid": {"uuid": "2"}
+                }
+            ],
+            "service_config": {
+                "config_rules": [
+                    {
+                        "action": "CONFIGACTION_SET",
+                        "custom": {
+                            "resource_key": "/settings",
+                            "resource_value": {
+                                "switch_info": {
+                                    "p4-sw1": {
+                                        "arch": "v1model",
+                                        "dpid": 1,
+                                        "port_list": [
+                                            {
+                                                "port_id": 1,
+                                                "port_type": "host"
+                                            },
+                                            {
+                                                "port_id": 2,
+                                                "port_type": "host"
+                                            }
+                                        ],
+                                        "routing_list": [
+                                            {
+                                                "port_id": 1,
+                                                "ipv4_dst": "10.158.72.11",
+                                                "ipv4_prefix_len": 32,
+                                                "mac_src": "fa:16:3e:e2:af:28",
+                                                "mac_dst": "fa:16:3e:75:9c:e5"
+                                            },
+                                            {
+                                                "port_id": 2,
+                                                "ipv4_dst": "172.16.10.9",
+                                                "ipv4_prefix_len": 32,
+                                                "mac_src": "fa:16:3e:75:9c:e5",
+                                                "mac_dst": "fa:16:3e:e2:af:28"
+                                            }
+                                        ]
+                                    }
+                                }
+                            }
+                        }
+                    }
+                ]
+            },
+            "service_constraints": []
+        }
+    ]
+}
diff --git a/src/tests/p4-fabric-tna/run_test_04a_service_provision_l3.sh b/src/tests/p4-fabric-tna/run_test_04a_service_provision_l3.sh
new file mode 100755
index 000000000..96c629370
--- /dev/null
+++ b/src/tests/p4-fabric-tna/run_test_04a_service_provision_l3.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source tfs_runtime_env_vars.sh
+python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_l3.py
diff --git a/src/tests/p4-fabric-tna/run_test_04b_service_deprovision_l3.sh b/src/tests/p4-fabric-tna/run_test_04b_service_deprovision_l3.sh
new file mode 100755
index 000000000..fdc1d72ac
--- /dev/null
+++ b/src/tests/p4-fabric-tna/run_test_04b_service_deprovision_l3.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source tfs_runtime_env_vars.sh
+python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_l3.py
diff --git a/src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_l3.py b/src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_l3.py
new file mode 100644
index 000000000..d349a0874
--- /dev/null
+++ b/src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_l3.py
@@ -0,0 +1,78 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+from common.proto.context_pb2 import ServiceId, ServiceStatusEnum, ServiceTypeEnum
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from common.tools.object_factory.Service import json_service_id
+from context.client.ContextClient import ContextClient
+from service.client.ServiceClient import ServiceClient
+from tests.Fixtures import context_client, service_client # pylint: disable=unused-import
+from tests.tools.test_tools_p4 import *
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+def test_service_deletion_l3(
+    context_client : ContextClient, # pylint: disable=redefined-outer-name
+    service_client : ServiceClient  # pylint: disable=redefined-outer-name
+) -> None:
+    # Get the current number of devices
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    LOGGER.warning('Devices[{:d}] = {:s}'.format(len(response.devices), grpc_message_to_json_string(response)))
+
+    # Total devices
+    dev_nb = len(response.devices)
+    assert dev_nb == DEV_NB
+
+    # P4 devices
+    p4_dev_nb = identify_number_of_p4_devices(response.devices)
+    assert p4_dev_nb == P4_DEV_NB
+
+    # Get the current number of rules in the P4 devices
+    p4_rules_before_deletion = get_number_of_rules(response.devices)
+
+    # Get the current number of services
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    services_nb_before_deletion = len(response.services)
+    assert verify_active_service_type(response.services, ServiceTypeEnum.SERVICETYPE_L3NM)
+
+    for service in response.services:
+        # Ignore services of other types
+        if service.service_type != ServiceTypeEnum.SERVICETYPE_L3NM:
+            continue
+
+        service_id = service.service_id
+        assert service_id
+
+        service_uuid = service_id.service_uuid.uuid
+        context_uuid = service_id.context_id.context_uuid.uuid
+        assert service.service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE
+
+        # Delete L3 service
+        service_client.DeleteService(ServiceId(**json_service_id(service_uuid, json_context_id(context_uuid))))
+
+    # Get an updated view of the services
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    services_nb_after_deletion = len(response.services)
+    assert services_nb_after_deletion == services_nb_before_deletion - 1, "Exactly one new service must be deleted"
+
+    # Get an updated view of the devices
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    p4_rules_after_deletion = get_number_of_rules(response.devices)
+
+    rules_diff = p4_rules_before_deletion - p4_rules_after_deletion
+
+    assert p4_rules_after_deletion < p4_rules_before_deletion, "L3 service must contain some rules"
+    assert rules_diff == P4_DEV_NB * L3_RULES, "L3 service must contain {} rules per device".format(L3_RULES)
diff --git a/src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_l3.py b/src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_l3.py
new file mode 100644
index 000000000..9c0009b14
--- /dev/null
+++ b/src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_l3.py
@@ -0,0 +1,73 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+from common.proto.context_pb2 import ServiceStatusEnum, ServiceTypeEnum
+from common.tools.descriptor.Loader import DescriptorLoader, check_descriptor_load_results
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from service.client.ServiceClient import ServiceClient
+from tests.Fixtures import context_client, device_client, service_client # pylint: disable=unused-import
+from tests.tools.test_tools_p4 import *
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+def test_service_creation_l3(
+    context_client : ContextClient, # pylint: disable=redefined-outer-name
+    device_client  : DeviceClient,  # pylint: disable=redefined-outer-name
+    service_client : ServiceClient  # pylint: disable=redefined-outer-name
+) -> None:
+    # Get the current number of services
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    services_nb_before = len(response.services)
+
+    # Get the current number of devices
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    LOGGER.warning('Devices[{:d}] = {:s}'.format(len(response.devices), grpc_message_to_json_string(response)))
+
+    # Total devices
+    dev_nb = len(response.devices)
+    assert dev_nb == DEV_NB
+
+    # P4 devices
+    p4_dev_nb = identify_number_of_p4_devices(response.devices)
+    assert p4_dev_nb == P4_DEV_NB
+
+    # Get the current number of rules in the P4 devices
+    p4_rules_before = get_number_of_rules(response.devices)
+
+    # Load service
+    descriptor_loader = DescriptorLoader(
+        descriptors_file=DESC_FILE_SERVICE_CREATE_L3,
+        context_client=context_client, device_client=device_client, service_client=service_client
+    )
+    results = descriptor_loader.process()
+    check_descriptor_load_results(results, descriptor_loader)
+
+    # Get an updated view of the services
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    services_nb_after = len(response.services)
+    assert services_nb_after == services_nb_before + 1, "Exactly one new service must be in place"
+    assert verify_active_service_type(response.services, ServiceTypeEnum.SERVICETYPE_L3NM)
+
+    # Get an updated view of the devices
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    p4_rules_after = get_number_of_rules(response.devices)
+
+    rules_diff = p4_rules_after - p4_rules_before
+
+    assert p4_rules_after > p4_rules_before, "L3 service must install some rules"
+    assert rules_diff == P4_DEV_NB * L3_RULES, "L3 service must install {} rules per device".format(L3_RULES)
-- 
GitLab


From 5c553a4f03d55be0fd2730d8f776661c1b8deee2 Mon Sep 17 00:00:00 2001
From: "Georgios P. Katsikas" <gkatsikas@ubitech.eu>
Date: Mon, 31 Mar 2025 08:53:13 +0000
Subject: [PATCH 09/14] feat: P4 ACL service handler

---
 .../service/service_handlers/__init__.py      |   7 +
 .../p4_fabric_tna_acl/__init__.py             |  13 +
 .../p4_fabric_tna_acl_config.py               |  39 ++
 .../p4_fabric_tna_acl_service_handler.py      | 526 ++++++++++++++++++
 src/tests/p4-fabric-tna/README.md             |  14 +
 .../descriptors/service-create-acl.json       |  65 +++
 .../run_test_05a_service_provision_acl.sh     |  17 +
 .../run_test_05b_service_deprovision_acl.sh   |  17 +
 ...test_functional_service_deprovision_acl.py |  78 +++
 .../test_functional_service_provision_acl.py  |  73 +++
 10 files changed, 849 insertions(+)
 create mode 100644 src/service/service/service_handlers/p4_fabric_tna_acl/__init__.py
 create mode 100644 src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_config.py
 create mode 100644 src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_service_handler.py
 create mode 100644 src/tests/p4-fabric-tna/descriptors/service-create-acl.json
 create mode 100755 src/tests/p4-fabric-tna/run_test_05a_service_provision_acl.sh
 create mode 100755 src/tests/p4-fabric-tna/run_test_05b_service_deprovision_acl.sh
 create mode 100644 src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_acl.py
 create mode 100644 src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_acl.py

diff --git a/src/service/service/service_handlers/__init__.py b/src/service/service/service_handlers/__init__.py
index 0ecef7c22..7c00d5a85 100644
--- a/src/service/service/service_handlers/__init__.py
+++ b/src/service/service/service_handlers/__init__.py
@@ -29,6 +29,7 @@ from .p4_dummy_l1.p4_dummy_l1_service_handler import P4DummyL1ServiceHandler
 from .p4_fabric_tna_int.p4_fabric_tna_int_service_handler import P4FabricINTServiceHandler
 from .p4_fabric_tna_l2_simple.p4_fabric_tna_l2_simple_service_handler import P4FabricL2SimpleServiceHandler
 from .p4_fabric_tna_l3.p4_fabric_tna_l3_service_handler import P4FabricL3ServiceHandler
+from .p4_fabric_tna_acl.p4_fabric_tna_acl_service_handler import P4FabricACLServiceHandler
 from .tapi_tapi.TapiServiceHandler import TapiServiceHandler
 from .tapi_xr.TapiXrServiceHandler import TapiXrServiceHandler
 from .optical_tfs.OpticalTfsServiceHandler import OpticalTfsServiceHandler
@@ -132,6 +133,12 @@ SERVICE_HANDLERS = [
             FilterFieldEnum.DEVICE_DRIVER: DeviceDriverEnum.DEVICEDRIVER_P4,
         }
     ]),
+    (P4FabricACLServiceHandler, [
+        {
+            FilterFieldEnum.SERVICE_TYPE: ServiceTypeEnum.SERVICETYPE_ACL,
+            FilterFieldEnum.DEVICE_DRIVER: DeviceDriverEnum.DEVICEDRIVER_P4,
+        }
+    ]),
     (L2NM_IETFL2VPN_ServiceHandler, [
         {
             FilterFieldEnum.SERVICE_TYPE  : ServiceTypeEnum.SERVICETYPE_L2NM,
diff --git a/src/service/service/service_handlers/p4_fabric_tna_acl/__init__.py b/src/service/service/service_handlers/p4_fabric_tna_acl/__init__.py
new file mode 100644
index 000000000..023830645
--- /dev/null
+++ b/src/service/service/service_handlers/p4_fabric_tna_acl/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_config.py b/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_config.py
new file mode 100644
index 000000000..09dbcc5aa
--- /dev/null
+++ b/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_config.py
@@ -0,0 +1,39 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Common objects and methods for In-band Network Telemetry (INT) dataplane
+based on the SD-Fabric dataplane model.
+This dataplane covers both software based and hardware-based Stratum-enabled P4 switches,
+such as the BMv2 software switch and Intel's Tofino/Tofino-2 switches.
+
+SD-Fabric repo: https://github.com/stratum/fabric-tna
+SD-Fabric docs: https://docs.sd-fabric.org/master/index.html
+"""
+
+import logging
+
+from service.service.service_handlers.p4_fabric_tna_commons.p4_fabric_tna_commons import *
+
+LOGGER = logging.getLogger(__name__)
+
+# ACL service handler settings
+ACL = "acl"
+ACTION = "action"
+ACTION_DROP = "drop"
+ACTION_ALLOW = "allow"
+ACTION_LIST = [ACTION_ALLOW, ACTION_DROP]
+
+def is_valid_acl_action(action : str) -> bool:
+    return action in ACTION_LIST
diff --git a/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_service_handler.py b/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_service_handler.py
new file mode 100644
index 000000000..0b44a1ce8
--- /dev/null
+++ b/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_service_handler.py
@@ -0,0 +1,526 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Service handler for P4-based access control using the SD-Fabric P4 dataplane
+for BMv2 and Intel Tofino switches.
+"""
+
+import logging
+from typing import Any, List, Dict, Optional, Tuple, Union
+from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method
+from common.proto.context_pb2 import ConfigActionEnum, DeviceId, Service, Device
+from common.tools.object_factory.Device import json_device_id
+from common.type_checkers.Checkers import chk_type, chk_address_ipv4, chk_prefix_len_ipv4,\
+    chk_transport_port
+from service.service.service_handler_api._ServiceHandler import _ServiceHandler
+from service.service.service_handler_api.SettingsHandler import SettingsHandler
+from service.service.service_handlers.p4_fabric_tna_commons.p4_fabric_tna_commons import *
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
+
+from .p4_fabric_tna_acl_config import *
+
+LOGGER = logging.getLogger(__name__)
+
+METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'p4_fabric_tna_acl'})
+
+class P4FabricACLServiceHandler(_ServiceHandler):
+    def __init__(   # pylint: disable=super-init-not-called
+        self, service : Service, task_executor : TaskExecutor, **settings # type: ignore
+    ) -> None:
+        """ Initialize Driver.
+            Parameters:
+                service
+                    The service instance (gRPC message) to be managed.
+                task_executor
+                    An instance of Task Executor providing access to the
+                    service handlers factory, the context and device clients,
+                    and an internal cache of already-loaded gRPC entities.
+                **settings
+                    Extra settings required by the service handler.
+
+        """
+        self.__service_label = "P4 Access Control connectivity service"
+        self.__service = service
+        self.__task_executor = task_executor
+        self.__settings_handler = SettingsHandler(self.__service.service_config, **settings)
+
+        self._init_settings()
+        self._parse_settings()
+        self._print_settings()
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetEndpoint(
+        self, endpoints : List[Tuple[str, str, Optional[str]]],
+        connection_uuid : Optional[str] = None
+    ) -> List[Union[bool, Exception]]:
+        """ Create/Update service endpoints from a list.
+            Parameters:
+                endpoints: List[Tuple[str, str, Optional[str]]]
+                    List of tuples, each containing a device_uuid,
+                    endpoint_uuid and, optionally, the topology_uuid
+                    of the endpoint to be added.
+                connection_uuid : Optional[str]
+                    If specified, is the UUID of the connection this endpoint is associated to.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for endpoint changes requested.
+                    Return values must be in the same order as the requested
+                    endpoints. If an endpoint is properly added, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        chk_type('endpoints', endpoints, list)
+        if len(endpoints) == 0: return []
+
+        LOGGER.info("{} - Provision service configuration".format(
+            self.__service_label))
+
+        visited = set()
+        results = []
+        for endpoint in endpoints:
+            device_uuid, endpoint_uuid = endpoint[0:2]
+            device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+            device_name = device.name
+
+            LOGGER.info("Device {}".format(device_name))
+            LOGGER.info("\t | Service endpoint UUID: {}".format(endpoint_uuid))
+
+            port_id = find_port_id_in_endpoint_list(device.device_endpoints, endpoint_uuid)
+            LOGGER.info("\t | Service port ID: {}".format(port_id))
+
+            try:
+                # Check if this port is part of the ACL configuration
+                _ = self._get_switch_port_in_port_map(device_name, port_id)
+            except Exception:
+                LOGGER.warning("Switch {} endpoint {} is not part of the ACL configuration".format(device_name, port_id))
+                results.append(False)
+                continue
+
+            dev_port_key = device_name + "-" + PORT_PREFIX + str(port_id)
+
+            # Skip already visited device ports
+            if dev_port_key in visited:
+                continue
+
+            rules = []
+            actual_rules = -1
+            applied_rules, failed_rules = 0, -1
+
+            # Create and apply rules
+            try:
+                rules = self._create_rules(
+                    device_obj=device, port_id=port_id, action=ConfigActionEnum.CONFIGACTION_SET)
+                actual_rules = len(rules)
+                applied_rules, failed_rules = apply_rules(
+                    task_executor=self.__task_executor,
+                    device_obj=device,
+                    json_config_rules=rules
+                )
+            except Exception as ex:
+                LOGGER.error("Failed to insert ACL rules on device {} due to {}".format(device.name, ex))
+            finally:
+                rules.clear()
+
+            # Ensure correct status
+            results.append(True) if (failed_rules == 0) and (applied_rules == actual_rules) \
+                else results.append(False)
+
+            # You should no longer visit this device port again
+            visited.add(dev_port_key)
+
+            LOGGER.info("Installed {}/{} ACL rules on device {} and port {}".format(
+                applied_rules, actual_rules, device_name, port_id))
+
+        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]]:
+        """ Delete service endpoints from a list.
+            Parameters:
+                endpoints: List[Tuple[str, str, Optional[str]]]
+                    List of tuples, each containing a device_uuid,
+                    endpoint_uuid, and the topology_uuid of the endpoint
+                    to be removed.
+                connection_uuid : Optional[str]
+                    If specified, is the UUID of the connection this endpoint is associated to.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for endpoint deletions requested.
+                    Return values must be in the same order as the requested
+                    endpoints. If an endpoint is properly deleted, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        chk_type('endpoints', endpoints, list)
+        if len(endpoints) == 0: return []
+
+        LOGGER.info("{} - Deprovision service configuration".format(
+            self.__service_label))
+
+        visited = set()
+        results = []
+        for endpoint in endpoints:
+            device_uuid, endpoint_uuid = endpoint[0:2]
+            device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+            device_name = device.name
+
+            LOGGER.info("Device {}".format(device_name))
+            LOGGER.info("\t | Service endpoint UUID: {}".format(endpoint_uuid))
+
+            port_id = find_port_id_in_endpoint_list(device.device_endpoints, endpoint_uuid)
+            LOGGER.info("\t | Service port ID: {}".format(port_id))
+
+            try:
+                # Check if this port is part of the ACL configuration
+                _ = self._get_switch_port_in_port_map(device_name, port_id)
+            except Exception:
+                LOGGER.warning("Switch {} endpoint {} is not part of the ACL configuration".format(device_name, port_id))
+                results.append(False)
+                continue
+
+            dev_port_key = device_name + "-" + PORT_PREFIX + str(port_id)
+
+            # Skip already visited device ports
+            if dev_port_key in visited:
+                continue
+
+            rules = []
+            actual_rules = -1
+            applied_rules, failed_rules = 0, -1
+
+            # Create and apply rules
+            try:
+                rules = self._create_rules(
+                    device_obj=device, port_id=port_id, action=ConfigActionEnum.CONFIGACTION_DELETE)
+                actual_rules = len(rules)
+                applied_rules, failed_rules = apply_rules(
+                    task_executor=self.__task_executor,
+                    device_obj=device,
+                    json_config_rules=rules
+                )
+            except Exception as ex:
+                LOGGER.error("Failed to insert ACL rules on device {} due to {}".format(device.name, ex))
+            finally:
+                rules.clear()
+
+            # Ensure correct status
+            results.append(True) if (failed_rules == 0) and (applied_rules == actual_rules) \
+                else results.append(False)
+
+            # You should no longer visit this device port again
+            visited.add(dev_port_key)
+
+            LOGGER.info("Deleted {}/{} ACL rules from device {} and port {}".format(
+                applied_rules, actual_rules, device_name, port_id))
+
+        return results
+
+    @metered_subclass_method(METRICS_POOL)
+    def SetConstraint(self, constraints: List[Tuple[str, Any]]) \
+            -> List[Union[bool, Exception]]:
+        """ Create/Update service constraints.
+            Parameters:
+                constraints: List[Tuple[str, Any]]
+                    List of tuples, each containing a constraint_type and the
+                    new constraint_value to be set.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for constraint changes requested.
+                    Return values must be in the same order as the requested
+                    constraints. If a constraint is properly set, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        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]]:
+        """ Delete service constraints.
+            Parameters:
+                constraints: List[Tuple[str, Any]]
+                    List of tuples, each containing a constraint_type pointing
+                    to the constraint to be deleted, and a constraint_value
+                    containing possible additionally required values to locate
+                    the constraint to be removed.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for constraint deletions requested.
+                    Return values must be in the same order as the requested
+                    constraints. If a constraint is properly deleted, True must
+                    be returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        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]]:
+        """ Create/Update configuration for a list of service resources.
+            Parameters:
+                resources: List[Tuple[str, Any]]
+                    List of tuples, each containing a resource_key pointing to
+                    the resource to be modified, and a resource_value
+                    containing the new value to be set.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for resource key changes requested.
+                    Return values must be in the same order as the requested
+                    resource keys. If a resource is properly set, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        chk_type('resources', resources, list)
+        if len(resources) == 0: return []
+
+        msg = '[SetConfig] Method not implemented. Resources({:s}) are being ignored.'
+        LOGGER.warning(msg.format(str(resources)))
+        return [True for _ in range(len(resources))]
+
+    @metered_subclass_method(METRICS_POOL)
+    def DeleteConfig(self, resources: List[Tuple[str, Any]]) \
+            -> List[Union[bool, Exception]]:
+        """ Delete configuration for a list of service resources.
+            Parameters:
+                resources: List[Tuple[str, Any]]
+                    List of tuples, each containing a resource_key pointing to
+                    the resource to be modified, and a resource_value containing
+                    possible additionally required values to locate the value
+                    to be removed.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for resource key deletions requested.
+                    Return values must be in the same order as the requested
+                    resource keys. If a resource is properly deleted, True must
+                    be returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
+        """
+        chk_type('resources', resources, list)
+        if len(resources) == 0: return []
+
+        msg = '[SetConfig] Method not implemented. Resources({:s}) are being ignored.'
+        LOGGER.warning(msg.format(str(resources)))
+        return [True for _ in range(len(resources))]
+
+    def _init_settings(self):
+        self.__switch_info = {}
+        self.__port_map = {}
+
+        try:
+            self.__settings = self.__settings_handler.get('/settings')
+            LOGGER.info("{} with settings: {}".format(self.__service_label, self.__settings))
+        except Exception as ex:
+            self.__settings = {}
+            LOGGER.error("Failed to parse service settings: {}".format(ex))
+
+    def _default_settings(self):
+        acl = [
+            {
+                PORT_ID: 1,
+                IPV4_SRC: "10.158.72.11",
+                IPV4_PREFIX_LEN: 32,
+                ACTION: ACTION_DROP
+            },
+            {
+                PORT_ID: 1,
+                TRN_PORT_DST: 8080,
+                ACTION: ACTION_DROP
+            }
+        ]
+
+        switch_info = {
+            "p4-sw1": {
+                ARCH: TARGET_ARCH_V1MODEL,
+                DPID: 1,
+                ACL: acl
+            }
+        }
+        self.__settings = {
+            SWITCH_INFO: switch_info
+        }
+
+        port_map = {
+            "p4-sw1": {
+                "port-1": {
+                    PORT_ID: 1,
+                    ACL: [
+                        {
+                            IPV4_SRC: "10.158.72.11",
+                            IPV4_PREFIX_LEN: 32,
+                            ACTION: ACTION_DROP
+                        },
+                        {
+                            TRN_PORT_DST: 8080,
+                            ACTION: ACTION_DROP
+                        }
+                    ]
+                }
+            }
+        }
+
+    def _parse_settings(self):
+        #TODO: Pass settings in a correct way
+        try:
+            self.__switch_info = self.__settings[SWITCH_INFO]
+        except Exception as ex:
+            LOGGER.error("Failed to parse settings: {}".format(ex))
+            self._default_settings() #TODO: Remove when bug is fixed
+            self.__switch_info = self.__settings[SWITCH_INFO]
+        assert isinstance(self.__switch_info, dict), "Switch info object must be a map with switch names as keys"
+
+        for switch_name, switch_info in self.__switch_info.items():
+            assert switch_name, "Invalid P4 switch name"
+            assert isinstance(switch_info, dict), "Switch {} info must be a map with arch, dpid, and fwd_list items)"
+            assert switch_info[ARCH] in SUPPORTED_TARGET_ARCH_LIST, \
+                "Switch {} - Supported P4 architectures are: {}".format(switch_name, ','.join(SUPPORTED_TARGET_ARCH_LIST))
+            switch_dpid = switch_info[DPID]
+            assert switch_dpid > 0, "Switch {} - P4 switch dataplane ID must be a positive integer".format(switch_name, switch_info[DPID])
+
+            # Access Control list
+            acl = switch_info[ACL]
+            assert isinstance(acl, list), "Switch {} access control list must be a list with port_id, [ipv4_dst/src, trn_post_dst/src], and action items)"
+            for acl_entry in acl:
+                LOGGER.info("ACL entry: {}".format(acl_entry))
+                port_id = acl_entry[PORT_ID]
+                assert port_id >= 0, "Switch {} - Invalid P4 switch port ID".format(switch_name)
+
+                # Prepare the port map
+                if switch_name not in self.__port_map:
+                    self.__port_map[switch_name] = {}
+                port_key = PORT_PREFIX + str(port_id)
+                if port_key not in self.__port_map[switch_name]:
+                    self.__port_map[switch_name][port_key] = {}
+                self.__port_map[switch_name][port_key][PORT_ID] = port_id
+                if ACL not in self.__port_map[switch_name][port_key]:
+                    self.__port_map[switch_name][port_key][ACL] = []
+
+                map_entry = {}
+
+                ipv4_src = ""
+                if IPV4_SRC in acl_entry:
+                    ipv4_src = acl_entry[IPV4_SRC]
+                    assert chk_address_ipv4(ipv4_src), "Invalid source IPv4 address {}".format(ipv4_dst)
+                    map_entry[IPV4_SRC] = ipv4_src
+
+                ipv4_dst = ""
+                if IPV4_DST in acl_entry:
+                    ipv4_dst = acl_entry[IPV4_DST]
+                    assert chk_address_ipv4(ipv4_dst), "Invalid destination IPv4 address {}".format(ipv4_dst)
+                    map_entry[IPV4_DST] = ipv4_dst
+
+                ipv4_prefix_len = -1
+                if ipv4_src or ipv4_dst:
+                    ipv4_prefix_len = acl_entry[IPV4_PREFIX_LEN]
+                    assert chk_prefix_len_ipv4(ipv4_prefix_len), "Invalid IPv4 address prefix length {}".format(ipv4_prefix_len)
+                    map_entry[IPV4_PREFIX_LEN] = ipv4_prefix_len
+                
+                trn_port_src = -1
+                if TRN_PORT_SRC in acl_entry:
+                    trn_port_src = acl_entry[TRN_PORT_SRC]
+                    assert chk_transport_port(trn_port_src), "Invalid source transport port"
+                    map_entry[TRN_PORT_SRC] = trn_port_src
+                
+                trn_port_dst = -1
+                if TRN_PORT_DST in acl_entry:
+                    trn_port_dst = acl_entry[TRN_PORT_DST]
+                    assert chk_transport_port(trn_port_dst), "Invalid destination transport port"
+                    map_entry[TRN_PORT_DST] = trn_port_dst
+                
+                action = acl_entry[ACTION]
+                assert is_valid_acl_action(action), "Valid actions are: {}".format(','.join(ACTION_LIST))
+
+                # Retrieve entry from the port map
+                switch_port_entry = self._get_switch_port_in_port_map(switch_name, port_id)
+
+                # Add routing entry
+                switch_port_entry[ACL].append(map_entry)
+
+    def _print_settings(self):
+        LOGGER.info("--------------- {} settings ---------------".format(self.__service.name))
+        LOGGER.info("--- Topology info")
+        for switch_name, switch_info in self.__switch_info.items():
+            LOGGER.info("\t Device {}".format(switch_name))
+            LOGGER.info("\t\t| Target P4 architecture: {}".format(switch_info[ARCH]))
+            LOGGER.info("\t\t|          Data plane ID: {}".format(switch_info[DPID]))
+            LOGGER.info("\t\t|               Port map: {}".format(self.__port_map[switch_name]))
+        LOGGER.info("-------------------------------------------------------")
+
+    def _get_switch_port_in_port_map(self, switch_name : str, port_id : int) -> Dict:
+        assert switch_name, "A valid switch name must be used as a key to the port map"
+        assert port_id > 0, "A valid switch port ID must be used as a key to a switch's port map"
+        switch_entry = self.__port_map[switch_name]
+        assert switch_entry, "Switch {} does not exist in the port map".format(switch_name)
+        port_key = PORT_PREFIX + str(port_id)
+        assert switch_entry[port_key], "Port with ID {} does not exist in the switch map".format(port_id)
+
+        return switch_entry[port_key]
+    
+    def _get_acl_of_switch_port(self, switch_name : str, port_id : int) -> List [Tuple]:
+        switch_port_entry = self._get_switch_port_in_port_map(switch_name, port_id)
+        return switch_port_entry[ACL]
+
+    def _create_rules(self, device_obj : Device, port_id : int, action : ConfigActionEnum): # type: ignore
+        dev_name = device_obj.name
+
+        rules  = []
+
+        ### ACL rules
+        acl = self._get_acl_of_switch_port(switch_name=dev_name, port_id=port_id)
+        for acl_entry in acl:
+            if IPV4_SRC in acl_entry:
+                rules += rules_set_up_acl_filter_host(
+                    ingress_port=port_id,
+                    ip_address=acl_entry[IPV4_SRC],
+                    prefix_len=acl_entry[IPV4_PREFIX_LEN],
+                    ip_direction="src",
+                    action=action
+                )
+            if IPV4_DST in acl_entry:
+                rules += rules_set_up_acl_filter_host(
+                    ingress_port=port_id,
+                    ip_address=acl_entry[IPV4_DST],
+                    prefix_len=acl_entry[IPV4_PREFIX_LEN],
+                    ip_direction="dst",
+                    action=action
+                )
+            if TRN_PORT_SRC in acl_entry:
+                rules += rules_set_up_acl_filter_port(
+                    ingress_port=port_id,
+                    transport_port=acl_entry[TRN_PORT_SRC],
+                    transport_direction="src",
+                    action=action
+                )
+            if TRN_PORT_DST in acl_entry:
+                rules += rules_set_up_acl_filter_port(
+                    ingress_port=port_id,
+                    transport_port=acl_entry[TRN_PORT_DST],
+                    transport_direction="dst",
+                    action=action
+                )
+
+        return rules
diff --git a/src/tests/p4-fabric-tna/README.md b/src/tests/p4-fabric-tna/README.md
index f6bc2dd0c..115932bb4 100644
--- a/src/tests/p4-fabric-tna/README.md
+++ b/src/tests/p4-fabric-tna/README.md
@@ -153,6 +153,20 @@ cd ~/tfs-ctrl/
 bash src/tests/p4-fabric-tna/run_test_04b_service_deprovision_l3.sh
 ```
 
+#### Provision ACL network service via the Service API
+
+```shell
+cd ~/tfs-ctrl/
+bash src/tests/p4-fabric-tna/run_test_05a_service_provision_acl.sh
+```
+
+#### Deprovision ACL network service via the Service API
+
+```shell
+cd ~/tfs-ctrl/
+bash src/tests/p4-fabric-tna/run_test_05b_service_deprovision_acl.sh
+```
+
 #### Provision INT service via the Service API
 
 ```shell
diff --git a/src/tests/p4-fabric-tna/descriptors/service-create-acl.json b/src/tests/p4-fabric-tna/descriptors/service-create-acl.json
new file mode 100644
index 000000000..d0beef010
--- /dev/null
+++ b/src/tests/p4-fabric-tna/descriptors/service-create-acl.json
@@ -0,0 +1,65 @@
+{
+    "services": [
+        {
+            "service_id": {
+                "context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "p4-service-acl"}
+            },
+            "name": "p4-service-acl",
+            "service_type": "SERVICETYPE_ACL",
+            "service_status": {"service_status": "SERVICESTATUS_PLANNED"},
+            "service_endpoint_ids": [
+                {
+                    "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+                    "endpoint_uuid": {"uuid": "1"}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+                    "endpoint_uuid": {"uuid": "2"}
+                }
+            ],
+            "service_config": {
+                "config_rules": [
+                    {
+                        "action": "CONFIGACTION_SET",
+                        "custom": {
+                            "resource_key": "/settings",
+                            "resource_value": {
+                                "switch_info": {
+                                    "p4-sw1": {
+                                        "arch": "v1model",
+                                        "dpid": 1,
+                                        "acl": [
+                                            {
+                                                "port_id": 1,
+                                                "trn_port_dst": 8080,
+                                                "action": "drop"
+                                            },
+                                            {
+                                                "port_id": 1,
+                                                "trn_port_src": 12345,
+                                                "action": "drop"
+                                            },
+                                            {
+                                                "port_id": 1,
+                                                "ipv4_dst": "172.16.10.10",
+                                                "ipv4_prefix_len": 32,
+                                                "action": "drop"
+                                            },
+                                            {
+                                                "port_id": 2,
+                                                "ipv4_src": "172.16.10.10",
+                                                "ipv4_prefix_len": 32,
+                                                "action": "drop"
+                                            }
+                                        ]
+                                    }
+                                }
+                            }
+                        }
+                    }
+                ]
+            },
+            "service_constraints": []
+        }
+    ]
+}
diff --git a/src/tests/p4-fabric-tna/run_test_05a_service_provision_acl.sh b/src/tests/p4-fabric-tna/run_test_05a_service_provision_acl.sh
new file mode 100755
index 000000000..2cf94b1bd
--- /dev/null
+++ b/src/tests/p4-fabric-tna/run_test_05a_service_provision_acl.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source tfs_runtime_env_vars.sh
+python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_acl.py
diff --git a/src/tests/p4-fabric-tna/run_test_05b_service_deprovision_acl.sh b/src/tests/p4-fabric-tna/run_test_05b_service_deprovision_acl.sh
new file mode 100755
index 000000000..681490896
--- /dev/null
+++ b/src/tests/p4-fabric-tna/run_test_05b_service_deprovision_acl.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source tfs_runtime_env_vars.sh
+python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_acl.py
diff --git a/src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_acl.py b/src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_acl.py
new file mode 100644
index 000000000..fcecbd2c7
--- /dev/null
+++ b/src/tests/p4-fabric-tna/tests-service/test_functional_service_deprovision_acl.py
@@ -0,0 +1,78 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+from common.proto.context_pb2 import ServiceId, ServiceStatusEnum, ServiceTypeEnum
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from common.tools.object_factory.Service import json_service_id
+from context.client.ContextClient import ContextClient
+from service.client.ServiceClient import ServiceClient
+from tests.Fixtures import context_client, service_client # pylint: disable=unused-import
+from tests.tools.test_tools_p4 import *
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+def test_service_deletion_acl(
+    context_client : ContextClient, # pylint: disable=redefined-outer-name
+    service_client : ServiceClient  # pylint: disable=redefined-outer-name
+) -> None:
+    # Get the current number of devices
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    LOGGER.warning('Devices[{:d}] = {:s}'.format(len(response.devices), grpc_message_to_json_string(response)))
+
+    # Total devices
+    dev_nb = len(response.devices)
+    assert dev_nb == DEV_NB
+
+    # P4 devices
+    p4_dev_nb = identify_number_of_p4_devices(response.devices)
+    assert p4_dev_nb == P4_DEV_NB
+
+    # Get the current number of rules in the P4 devices
+    p4_rules_before_deletion = get_number_of_rules(response.devices)
+
+    # Get the current number of services
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    services_nb_before_deletion = len(response.services)
+    assert verify_active_service_type(response.services, ServiceTypeEnum.SERVICETYPE_ACL)
+
+    for service in response.services:
+        # Ignore services of other types
+        if service.service_type != ServiceTypeEnum.SERVICETYPE_ACL:
+            continue
+
+        service_id = service.service_id
+        assert service_id
+
+        service_uuid = service_id.service_uuid.uuid
+        context_uuid = service_id.context_id.context_uuid.uuid
+        assert service.service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE
+
+        # Delete ACL service
+        service_client.DeleteService(ServiceId(**json_service_id(service_uuid, json_context_id(context_uuid))))
+
+    # Get an updated view of the services
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    services_nb_after_deletion = len(response.services)
+    assert services_nb_after_deletion == services_nb_before_deletion - 1, "Exactly one new service must be deleted"
+
+    # Get an updated view of the devices
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    p4_rules_after_deletion = get_number_of_rules(response.devices)
+
+    rules_diff = p4_rules_before_deletion - p4_rules_after_deletion
+
+    assert p4_rules_after_deletion < p4_rules_before_deletion, "ACL service must contain some rules"
+    assert rules_diff == P4_DEV_NB * ACL_RULES, "ACL service must contain {} rules per device".format(ACL_RULES)
diff --git a/src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_acl.py b/src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_acl.py
new file mode 100644
index 000000000..58de046b4
--- /dev/null
+++ b/src/tests/p4-fabric-tna/tests-service/test_functional_service_provision_acl.py
@@ -0,0 +1,73 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+from common.proto.context_pb2 import ServiceStatusEnum, ServiceTypeEnum
+from common.tools.descriptor.Loader import DescriptorLoader, check_descriptor_load_results
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from service.client.ServiceClient import ServiceClient
+from tests.Fixtures import context_client, device_client, service_client # pylint: disable=unused-import
+from tests.tools.test_tools_p4 import *
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+def test_service_creation_acl(
+    context_client : ContextClient, # pylint: disable=redefined-outer-name
+    device_client  : DeviceClient,  # pylint: disable=redefined-outer-name
+    service_client : ServiceClient  # pylint: disable=redefined-outer-name
+) -> None:
+    # Get the current number of services
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    services_nb_before = len(response.services)
+
+    # Get the current number of devices
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    LOGGER.warning('Devices[{:d}] = {:s}'.format(len(response.devices), grpc_message_to_json_string(response)))
+
+    # Total devices
+    dev_nb = len(response.devices)
+    assert dev_nb == DEV_NB
+
+    # P4 devices
+    p4_dev_nb = identify_number_of_p4_devices(response.devices)
+    assert p4_dev_nb == P4_DEV_NB
+
+    # Get the current number of rules in the P4 devices
+    p4_rules_before = get_number_of_rules(response.devices)
+
+    # Load service
+    descriptor_loader = DescriptorLoader(
+        descriptors_file=DESC_FILE_SERVICE_CREATE_ACL,
+        context_client=context_client, device_client=device_client, service_client=service_client
+    )
+    results = descriptor_loader.process()
+    check_descriptor_load_results(results, descriptor_loader)
+
+    # Get an updated view of the services
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    services_nb_after = len(response.services)
+    assert services_nb_after == services_nb_before + 1, "Exactly one new service must be in place"
+    assert verify_active_service_type(response.services, ServiceTypeEnum.SERVICETYPE_ACL)
+
+    # Get an updated view of the devices
+    response = context_client.ListDevices(ADMIN_CONTEXT_ID)
+    p4_rules_after = get_number_of_rules(response.devices)
+
+    rules_diff = p4_rules_after - p4_rules_before
+
+    assert p4_rules_after > p4_rules_before, "ACL service must install some rules"
+    assert rules_diff == P4_DEV_NB * ACL_RULES, "ACL service must install {} rules per device".format(ACL_RULES)
-- 
GitLab


From 22bb98ab7a75738d8d7417d282182cc99d3b9a1d Mon Sep 17 00:00:00 2001
From: "Georgios P. Katsikas" <gkatsikas@ubitech.eu>
Date: Mon, 31 Mar 2025 10:30:36 +0000
Subject: [PATCH 10/14] fix: service handlers' temporal configuration

---
 .../p4_fabric_tna_acl_service_handler.py      | 53 +++++++++++-------
 .../p4_fabric_tna_l3_service_handler.py       | 56 +++++++++----------
 .../descriptors/service-create-acl.json       |  8 +--
 src/tests/tools/test_tools_p4.py              |  2 +-
 4 files changed, 65 insertions(+), 54 deletions(-)

diff --git a/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_service_handler.py b/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_service_handler.py
index 0b44a1ce8..dc86dc535 100644
--- a/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_service_handler.py
+++ b/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_service_handler.py
@@ -342,13 +342,24 @@ class P4FabricACLServiceHandler(_ServiceHandler):
         acl = [
             {
                 PORT_ID: 1,
-                IPV4_SRC: "10.158.72.11",
+                TRN_PORT_DST: 8080,
+                ACTION: ACTION_DROP
+            },
+            {
+                PORT_ID: 2,
+                TRN_PORT_SRC: 12345,
+                ACTION: ACTION_DROP
+            },
+            {
+                PORT_ID: 2,
+                IPV4_DST: "10.158.72.11",
                 IPV4_PREFIX_LEN: 32,
                 ACTION: ACTION_DROP
             },
             {
-                PORT_ID: 1,
-                TRN_PORT_DST: 8080,
+                PORT_ID: 2,
+                IPV4_SRC: "10.158.72.12",
+                IPV4_PREFIX_LEN: 32,
                 ACTION: ACTION_DROP
             }
         ]
@@ -364,24 +375,24 @@ class P4FabricACLServiceHandler(_ServiceHandler):
             SWITCH_INFO: switch_info
         }
 
-        port_map = {
-            "p4-sw1": {
-                "port-1": {
-                    PORT_ID: 1,
-                    ACL: [
-                        {
-                            IPV4_SRC: "10.158.72.11",
-                            IPV4_PREFIX_LEN: 32,
-                            ACTION: ACTION_DROP
-                        },
-                        {
-                            TRN_PORT_DST: 8080,
-                            ACTION: ACTION_DROP
-                        }
-                    ]
-                }
-            }
-        }
+        # port_map = {
+        #     "p4-sw1": {
+        #         "port-1": {
+        #             PORT_ID: 1,
+        #             ACL: [
+        #                 {
+        #                     IPV4_SRC: "10.158.72.11",
+        #                     IPV4_PREFIX_LEN: 32,
+        #                     ACTION: ACTION_DROP
+        #                 },
+        #                 {
+        #                     TRN_PORT_DST: 8080,
+        #                     ACTION: ACTION_DROP
+        #                 }
+        #             ]
+        #         }
+        #     }
+        # }
 
     def _parse_settings(self):
         #TODO: Pass settings in a correct way
diff --git a/src/service/service/service_handlers/p4_fabric_tna_l3/p4_fabric_tna_l3_service_handler.py b/src/service/service/service_handlers/p4_fabric_tna_l3/p4_fabric_tna_l3_service_handler.py
index 849d1db92..ed5dd25bd 100644
--- a/src/service/service/service_handlers/p4_fabric_tna_l3/p4_fabric_tna_l3_service_handler.py
+++ b/src/service/service/service_handlers/p4_fabric_tna_l3/p4_fabric_tna_l3_service_handler.py
@@ -358,34 +358,34 @@ class P4FabricL3ServiceHandler(_ServiceHandler):
             SWITCH_INFO: switch_info
         }
 
-        port_map = {
-            "p4-sw1": {
-                "port-1": {
-                    PORT_ID: 1,
-                    PORT_TYPE: PORT_TYPE_HOST,
-                    ROUTING_LIST: [
-                        {
-                            IPV4_DST: "10.158.72.11",
-                            IPV4_PREFIX_LEN: 32,
-                            MAC_SRC: "fa:16:3e:e2:af:28",
-                            MAC_DST: "fa:16:3e:75:9c:e5"
-                        }
-                    ]
-                },
-                "port-2": {
-                    PORT_ID: 2,
-                    PORT_TYPE: PORT_TYPE_HOST,
-                    ROUTING_LIST: [
-                        {
-                            IPV4_DST: "172.16.10.9",
-                            IPV4_PREFIX_LEN: 32,
-                            MAC_SRC: "fa:16:3e:75:9c:e5",
-                            MAC_DST: "fa:16:3e:e2:af:28"
-                        }
-                    ]
-                }
-            }
-        }
+        # port_map = {
+        #     "p4-sw1": {
+        #         "port-1": {
+        #             PORT_ID: 1,
+        #             PORT_TYPE: PORT_TYPE_HOST,
+        #             ROUTING_LIST: [
+        #                 {
+        #                     IPV4_DST: "10.158.72.11",
+        #                     IPV4_PREFIX_LEN: 32,
+        #                     MAC_SRC: "fa:16:3e:e2:af:28",
+        #                     MAC_DST: "fa:16:3e:75:9c:e5"
+        #                 }
+        #             ]
+        #         },
+        #         "port-2": {
+        #             PORT_ID: 2,
+        #             PORT_TYPE: PORT_TYPE_HOST,
+        #             ROUTING_LIST: [
+        #                 {
+        #                     IPV4_DST: "172.16.10.9",
+        #                     IPV4_PREFIX_LEN: 32,
+        #                     MAC_SRC: "fa:16:3e:75:9c:e5",
+        #                     MAC_DST: "fa:16:3e:e2:af:28"
+        #                 }
+        #             ]
+        #         }
+        #     }
+        # }
 
     def _parse_settings(self):
         #TODO: Pass settings in a correct way
diff --git a/src/tests/p4-fabric-tna/descriptors/service-create-acl.json b/src/tests/p4-fabric-tna/descriptors/service-create-acl.json
index d0beef010..225e8e85e 100644
--- a/src/tests/p4-fabric-tna/descriptors/service-create-acl.json
+++ b/src/tests/p4-fabric-tna/descriptors/service-create-acl.json
@@ -35,19 +35,19 @@
                                                 "action": "drop"
                                             },
                                             {
-                                                "port_id": 1,
+                                                "port_id": 2,
                                                 "trn_port_src": 12345,
                                                 "action": "drop"
                                             },
                                             {
-                                                "port_id": 1,
-                                                "ipv4_dst": "172.16.10.10",
+                                                "port_id": 2,
+                                                "ipv4_dst": "10.158.72.11",
                                                 "ipv4_prefix_len": 32,
                                                 "action": "drop"
                                             },
                                             {
                                                 "port_id": 2,
-                                                "ipv4_src": "172.16.10.10",
+                                                "ipv4_src": "10.158.72.12",
                                                 "ipv4_prefix_len": 32,
                                                 "action": "drop"
                                             }
diff --git a/src/tests/tools/test_tools_p4.py b/src/tests/tools/test_tools_p4.py
index aa37f9e2c..c68f35183 100644
--- a/src/tests/tools/test_tools_p4.py
+++ b/src/tests/tools/test_tools_p4.py
@@ -30,7 +30,7 @@ ENDPOINT_RULES = 3
 INT_RULES = 19
 L2_RULES = 10
 L3_RULES = 4
-ACL_RULES = 2
+ACL_RULES = 1
 
 DATAPLANE_RULES_NB_INT_B1 = 5
 DATAPLANE_RULES_NB_INT_B2 = 6
-- 
GitLab


From b042d3f7ad6cc35926aa2117b8c31fda101eb90e Mon Sep 17 00:00:00 2001
From: "Georgios P. Katsikas" <gkatsikas@ubitech.eu>
Date: Mon, 31 Mar 2025 10:54:15 +0000
Subject: [PATCH 11/14] fix: P4 ACL temporary configuration

---
 .../p4_fabric_tna_acl_service_handler.py        | 17 -----------------
 .../descriptors/service-create-acl.json         | 17 -----------------
 2 files changed, 34 deletions(-)

diff --git a/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_service_handler.py b/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_service_handler.py
index dc86dc535..53c4e7c86 100644
--- a/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_service_handler.py
+++ b/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_service_handler.py
@@ -344,23 +344,6 @@ class P4FabricACLServiceHandler(_ServiceHandler):
                 PORT_ID: 1,
                 TRN_PORT_DST: 8080,
                 ACTION: ACTION_DROP
-            },
-            {
-                PORT_ID: 2,
-                TRN_PORT_SRC: 12345,
-                ACTION: ACTION_DROP
-            },
-            {
-                PORT_ID: 2,
-                IPV4_DST: "10.158.72.11",
-                IPV4_PREFIX_LEN: 32,
-                ACTION: ACTION_DROP
-            },
-            {
-                PORT_ID: 2,
-                IPV4_SRC: "10.158.72.12",
-                IPV4_PREFIX_LEN: 32,
-                ACTION: ACTION_DROP
             }
         ]
 
diff --git a/src/tests/p4-fabric-tna/descriptors/service-create-acl.json b/src/tests/p4-fabric-tna/descriptors/service-create-acl.json
index 225e8e85e..a0383f472 100644
--- a/src/tests/p4-fabric-tna/descriptors/service-create-acl.json
+++ b/src/tests/p4-fabric-tna/descriptors/service-create-acl.json
@@ -33,23 +33,6 @@
                                                 "port_id": 1,
                                                 "trn_port_dst": 8080,
                                                 "action": "drop"
-                                            },
-                                            {
-                                                "port_id": 2,
-                                                "trn_port_src": 12345,
-                                                "action": "drop"
-                                            },
-                                            {
-                                                "port_id": 2,
-                                                "ipv4_dst": "10.158.72.11",
-                                                "ipv4_prefix_len": 32,
-                                                "action": "drop"
-                                            },
-                                            {
-                                                "port_id": 2,
-                                                "ipv4_src": "10.158.72.12",
-                                                "ipv4_prefix_len": 32,
-                                                "action": "drop"
                                             }
                                         ]
                                     }
-- 
GitLab


From 9dfe1e7fb80cd9704b8bd7de0684f396e90c28b6 Mon Sep 17 00:00:00 2001
From: "Georgios P. Katsikas" <gkatsikas@ubitech.eu>
Date: Mon, 31 Mar 2025 16:32:07 +0000
Subject: [PATCH 12/14] doc: update README

---
 src/tests/p4-fabric-tna/README.md | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/src/tests/p4-fabric-tna/README.md b/src/tests/p4-fabric-tna/README.md
index 115932bb4..e8ae8fde9 100644
--- a/src/tests/p4-fabric-tna/README.md
+++ b/src/tests/p4-fabric-tna/README.md
@@ -72,13 +72,21 @@ The `./setup.sh` script copies from this directory. If you need to change the P4
 A set of tests is implemented, each focusing on different aspects of TFS.
 For each of these tests, an auxiliary bash script allows to run it with less typing.
 
-|                 Test                 |              Bash Runner           |                Purpose             |
-| ------------------------------------ | ---------------------------------- | ---------------------------------- |
-| -                                    | setup.sh                           | Copy P4 artifacts into the SBI pod |
-| test_functional_bootstrap.py         | run_test_01_bootstrap.sh           | Connect TFS to the P4 switch       |
-| test_functional_rules_provision.py   | run_test_02_rules_provision.sh     | Install rules on the P4 switch     |
-| test_functional_rules_deprovision.py | run_test_03_rules_deprovision.sh   | Uninstall rules from the P4 switch |
-| test_functional_cleanup.py           | run_test_04_cleanup.sh             | Disconnect TFS from the P4 switch  |
+|              Bash Runner                      |                Purpose                                                      |
+| --------------------------------------------- | --------------------------------------------------------------------------- |
+| setup.sh                                      | Copy P4 artifacts into the SBI pod                                          |
+| run_test_01_bootstrap.sh                      | Connect TFS to the P4 switch                                                |
+| run_test_02a_sbi_provision_int_l2_l3_acl.sh   | Install L2, L3, INT, and ACL rules on the P4 switch via the SBI service     |
+| run_test_02b_sbi_deprovision_int_l2_l3_acl.sh | Uninstall L2, L3, INT, and ACL rules from the P4 switch via the SBI service |
+| run_test_03a_service_provision_l2.sh          | Install L2 forwarding rules via a dedicated P4 L2 service handler           |
+| run_test_03b_service_deprovision_l2.sh        | Uninstall L2 forwarding rules via a dedicated P4 L2 service handler         |
+| run_test_04a_service_provision_l3.sh          | Install L3 routing rules via a dedicated P4 L3 service handler              |
+| run_test_04b_service_deprovision_l3.sh        | Uninstall L3 routing rules via a dedicated P4 L3 service handler            |
+| run_test_05a_service_provision_acl.sh         | Install ACL rules via a dedicated P4 ACL service handler                    |
+| run_test_05b_service_deprovision_acl.sh       | Uninstall ACL rules via a dedicated P4 ACL service handler                  |
+| run_test_06a_service_provision_int.sh         | Install INT rules via a dedicated P4 INT service handler                    |
+| run_test_06b_service_deprovision_int.sh       | Uninstall INT rules via a dedicated P4 INT service handler                  |
+| run_test_07_cleanup.sh                        | Clean-up context and topology and disconnect TFS from the P4 switch         |
 
 Each of the tests above is described in detail below.
 
-- 
GitLab


From 1296e935c1863d0f5ad7f284b5d3fa060a5de597 Mon Sep 17 00:00:00 2001
From: "Georgios P. Katsikas" <gkatsikas@ubitech.eu>
Date: Mon, 5 May 2025 20:07:40 +0300
Subject: [PATCH 13/14] fix: remove hardcoded service settings after pathcomp
 bug fix

---
 .../p4_fabric_tna_acl_service_handler.py      | 51 ++----------
 .../p4_fabric_tna_int_service_handler.py      | 40 ++--------
 ...p4_fabric_tna_l2_simple_service_handler.py | 64 ++-------------
 .../p4_fabric_tna_l3_service_handler.py       | 80 ++-----------------
 .../descriptors/service-create-acl.json       |  6 +-
 .../descriptors/service-create-int.json       | 14 ++--
 .../descriptors/service-create-l2-simple.json | 10 +--
 .../descriptors/service-create-l3.json        | 18 ++---
 .../p4-fabric-tna/descriptors/topology.json   | 34 ++++----
 ...witch-three-port-chassis-config-phy.pb.txt |  3 +-
 10 files changed, 64 insertions(+), 256 deletions(-)

diff --git a/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_service_handler.py b/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_service_handler.py
index 53c4e7c86..b57086a29 100644
--- a/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_service_handler.py
+++ b/src/service/service/service_handlers/p4_fabric_tna_acl/p4_fabric_tna_acl_service_handler.py
@@ -335,56 +335,15 @@ class P4FabricACLServiceHandler(_ServiceHandler):
             self.__settings = self.__settings_handler.get('/settings')
             LOGGER.info("{} with settings: {}".format(self.__service_label, self.__settings))
         except Exception as ex:
-            self.__settings = {}
-            LOGGER.error("Failed to parse service settings: {}".format(ex))
-
-    def _default_settings(self):
-        acl = [
-            {
-                PORT_ID: 1,
-                TRN_PORT_DST: 8080,
-                ACTION: ACTION_DROP
-            }
-        ]
-
-        switch_info = {
-            "p4-sw1": {
-                ARCH: TARGET_ARCH_V1MODEL,
-                DPID: 1,
-                ACL: acl
-            }
-        }
-        self.__settings = {
-            SWITCH_INFO: switch_info
-        }
-
-        # port_map = {
-        #     "p4-sw1": {
-        #         "port-1": {
-        #             PORT_ID: 1,
-        #             ACL: [
-        #                 {
-        #                     IPV4_SRC: "10.158.72.11",
-        #                     IPV4_PREFIX_LEN: 32,
-        #                     ACTION: ACTION_DROP
-        #                 },
-        #                 {
-        #                     TRN_PORT_DST: 8080,
-        #                     ACTION: ACTION_DROP
-        #                 }
-        #             ]
-        #         }
-        #     }
-        # }
+            LOGGER.error("Failed to retrieve service settings: {}".format(ex))
+            raise Exception(ex)
 
     def _parse_settings(self):
-        #TODO: Pass settings in a correct way
         try:
-            self.__switch_info = self.__settings[SWITCH_INFO]
+            self.__switch_info = self.__settings.value[SWITCH_INFO]
         except Exception as ex:
-            LOGGER.error("Failed to parse settings: {}".format(ex))
-            self._default_settings() #TODO: Remove when bug is fixed
-            self.__switch_info = self.__settings[SWITCH_INFO]
+            LOGGER.error("Failed to parse service settings: {}".format(ex))
+            raise Exception(ex)
         assert isinstance(self.__switch_info, dict), "Switch info object must be a map with switch names as keys"
 
         for switch_name, switch_info in self.__switch_info.items():
diff --git a/src/service/service/service_handlers/p4_fabric_tna_int/p4_fabric_tna_int_service_handler.py b/src/service/service/service_handlers/p4_fabric_tna_int/p4_fabric_tna_int_service_handler.py
index efdac5fea..dd19c4f89 100644
--- a/src/service/service/service_handlers/p4_fabric_tna_int/p4_fabric_tna_int_service_handler.py
+++ b/src/service/service/service_handlers/p4_fabric_tna_int/p4_fabric_tna_int_service_handler.py
@@ -305,43 +305,15 @@ class P4FabricINTServiceHandler(_ServiceHandler):
             self.__settings = self.__settings_handler.get('/settings')
             LOGGER.info("{} with settings: {}".format(self.__service_label, self.__settings))
         except Exception as ex:
-            self.__settings = {}
-            LOGGER.error("Failed to parse service settings: {}".format(ex))
-
-    def _default_settings(self):
-        switch_info = {
-            "p4-sw1": {
-                ARCH: TARGET_ARCH_V1MODEL,
-                DPID: 1,
-                MAC: "fa:16:3e:93:8c:c0",
-                IP: "10.10.10.120",
-                PORT_INT: {
-                    PORT_ID: 3,
-                    PORT_TYPE: "host"
-                },
-                RECIRCULATION_PORT_LIST: RECIRCULATION_PORTS_V1MODEL,
-                INT_REPORT_MIRROR_ID_LIST: INT_REPORT_MIRROR_ID_LIST_V1MODEL
-            }
-        }
-        int_collector_info = {
-            MAC: "fa:16:3e:fb:cf:96",
-            IP: "10.10.10.41",
-            PORT: 32766,
-            VLAN_ID: 4094
-        }
-        self.__settings = {
-            SWITCH_INFO: switch_info,
-            INT_COLLECTOR_INFO: int_collector_info
-        }
+            LOGGER.error("Failed to retrieve service settings: {}".format(ex))
+            raise Exception(ex)
 
     def _parse_settings(self):
-        #TODO: Pass settings in a correct way
         try:
-            self.__switch_info = self.__settings[SWITCH_INFO]
+            self.__switch_info = self.__settings.value[SWITCH_INFO]
         except Exception as ex:
-            LOGGER.error("Failed to parse settings: {}".format(ex))
-            self._default_settings() #TODO: Remove when bug is fixed
-            self.__switch_info = self.__settings[SWITCH_INFO]
+            LOGGER.error("Failed to parse service settings: {}".format(ex))
+            raise Exception(ex)
         assert isinstance(self.__switch_info, dict), "Switch info object must be a map with switch names as keys"
 
         for switch_name, switch_info in self.__switch_info.items():
@@ -364,7 +336,7 @@ class P4FabricINTServiceHandler(_ServiceHandler):
                 switch_info[INT_REPORT_MIRROR_ID_LIST] = INT_REPORT_MIRROR_ID_LIST_V1MODEL
             assert isinstance(switch_info[RECIRCULATION_PORT_LIST], list), "Switch {} - Recirculation ports must be described as a list".format(switch_name)
 
-        self.__int_collector_info = self.__settings[INT_COLLECTOR_INFO]
+        self.__int_collector_info = self.__settings.value[INT_COLLECTOR_INFO]
         assert isinstance(self.__int_collector_info, dict), "INT collector info object must be a map with mac, ip, port, and vlan_id keys)"
 
         self.__int_collector_mac = self.__int_collector_info[MAC]
diff --git a/src/service/service/service_handlers/p4_fabric_tna_l2_simple/p4_fabric_tna_l2_simple_service_handler.py b/src/service/service/service_handlers/p4_fabric_tna_l2_simple/p4_fabric_tna_l2_simple_service_handler.py
index c25fb087c..8d4aaf081 100644
--- a/src/service/service/service_handlers/p4_fabric_tna_l2_simple/p4_fabric_tna_l2_simple_service_handler.py
+++ b/src/service/service/service_handlers/p4_fabric_tna_l2_simple/p4_fabric_tna_l2_simple_service_handler.py
@@ -318,69 +318,15 @@ class P4FabricL2SimpleServiceHandler(_ServiceHandler):
             self.__settings = self.__settings_handler.get('/settings')
             LOGGER.info("{} with settings: {}".format(self.__service_label, self.__settings))
         except Exception as ex:
-            self.__settings = {}
-            LOGGER.error("Failed to parse service settings: {}".format(ex))
-
-    def _default_settings(self):
-        port_list = [
-            {
-                PORT_ID: 1,
-                PORT_TYPE: "host",
-                VLAN_ID: 4094
-            },
-            {
-                PORT_ID: 2,
-                PORT_TYPE: "host",
-                VLAN_ID: 4094
-            },
-        ]
-        fwd_list = [
-            {
-                PORT_ID: 1,
-                HOST_MAC: "fa:16:3e:75:9c:e5"
-            },
-            {
-                PORT_ID: 2,
-                HOST_MAC: "fa:16:3e:e2:af:28"
-            }
-        ]
-        switch_info = {
-            "p4-sw1": {
-                ARCH: TARGET_ARCH_V1MODEL,
-                DPID: 1,
-                PORT_LIST: port_list,
-                FORWARDING_LIST: fwd_list
-            }
-        }
-        self.__settings = {
-            SWITCH_INFO: switch_info
-        }
-
-        # port_map = {
-        #     "p4-sw1": {
-        #         "port-1": {
-        #             PORT_ID: 1,
-        #             PORT_TYPE: PORT_TYPE_HOST,
-        #             VLAN_ID: 4094,
-        #             FORWARDING_LIST: ["fa:16:3e:75:9c:e5"]
-        #         },
-        #         "port-2": {
-        #             PORT_ID: 2,
-        #             PORT_TYPE: PORT_TYPE_HOST,
-        #             VLAN_ID: 4094,
-        #             FORWARDING_LIST: ["fa:16:3e:e2:af:28"]
-        #         }
-        #     }
-        # }
+            LOGGER.error("Failed to retrieve service settings: {}".format(ex))
+            raise Exception(ex)
 
     def _parse_settings(self):
-        #TODO: Pass settings in a correct way
         try:
-            self.__switch_info = self.__settings[SWITCH_INFO]
+            self.__switch_info = self.__settings.value[SWITCH_INFO]
         except Exception as ex:
-            LOGGER.error("Failed to parse settings: {}".format(ex))
-            self._default_settings() #TODO: Remove when bug is fixed
-            self.__switch_info = self.__settings[SWITCH_INFO]
+            LOGGER.error("Failed to parse service settings: {}".format(ex))
+            raise Exception(ex)
         assert isinstance(self.__switch_info, dict), "Switch info object must be a map with switch names as keys"
 
         for switch_name, switch_info in self.__switch_info.items():
diff --git a/src/service/service/service_handlers/p4_fabric_tna_l3/p4_fabric_tna_l3_service_handler.py b/src/service/service/service_handlers/p4_fabric_tna_l3/p4_fabric_tna_l3_service_handler.py
index ed5dd25bd..4b013328e 100644
--- a/src/service/service/service_handlers/p4_fabric_tna_l3/p4_fabric_tna_l3_service_handler.py
+++ b/src/service/service/service_handlers/p4_fabric_tna_l3/p4_fabric_tna_l3_service_handler.py
@@ -316,85 +316,15 @@ class P4FabricL3ServiceHandler(_ServiceHandler):
             self.__settings = self.__settings_handler.get('/settings')
             LOGGER.info("{} with settings: {}".format(self.__service_label, self.__settings))
         except Exception as ex:
-            self.__settings = {}
-            LOGGER.error("Failed to parse service settings: {}".format(ex))
-
-    def _default_settings(self):
-        port_list = [
-            {
-                PORT_ID: 1,
-                PORT_TYPE: "host"
-            },
-            {
-                PORT_ID: 2,
-                PORT_TYPE: "host"
-            },
-        ]
-        routing_list = [
-            {
-                PORT_ID: 1,
-                IPV4_DST: "10.158.72.11",
-                IPV4_PREFIX_LEN: 32,
-                MAC_SRC: "fa:16:3e:e2:af:28",
-                MAC_DST: "fa:16:3e:75:9c:e5"
-            },
-            {
-                PORT_ID: 2,
-                IPV4_DST: "172.16.10.9",
-                IPV4_PREFIX_LEN: 32,
-                MAC_SRC: "fa:16:3e:75:9c:e5",
-                MAC_DST: "fa:16:3e:e2:af:28"
-            }
-        ]
-        switch_info = {
-            "p4-sw1": {
-                ARCH: TARGET_ARCH_V1MODEL,
-                DPID: 1,
-                PORT_LIST: port_list,
-                ROUTING_LIST: routing_list
-            }
-        }
-        self.__settings = {
-            SWITCH_INFO: switch_info
-        }
-
-        # port_map = {
-        #     "p4-sw1": {
-        #         "port-1": {
-        #             PORT_ID: 1,
-        #             PORT_TYPE: PORT_TYPE_HOST,
-        #             ROUTING_LIST: [
-        #                 {
-        #                     IPV4_DST: "10.158.72.11",
-        #                     IPV4_PREFIX_LEN: 32,
-        #                     MAC_SRC: "fa:16:3e:e2:af:28",
-        #                     MAC_DST: "fa:16:3e:75:9c:e5"
-        #                 }
-        #             ]
-        #         },
-        #         "port-2": {
-        #             PORT_ID: 2,
-        #             PORT_TYPE: PORT_TYPE_HOST,
-        #             ROUTING_LIST: [
-        #                 {
-        #                     IPV4_DST: "172.16.10.9",
-        #                     IPV4_PREFIX_LEN: 32,
-        #                     MAC_SRC: "fa:16:3e:75:9c:e5",
-        #                     MAC_DST: "fa:16:3e:e2:af:28"
-        #                 }
-        #             ]
-        #         }
-        #     }
-        # }
+            LOGGER.error("Failed to retrieve service settings: {}".format(ex))
+            raise Exception(ex)
 
     def _parse_settings(self):
-        #TODO: Pass settings in a correct way
         try:
-            self.__switch_info = self.__settings[SWITCH_INFO]
+            self.__switch_info = self.__settings.value[SWITCH_INFO]
         except Exception as ex:
-            LOGGER.error("Failed to parse settings: {}".format(ex))
-            self._default_settings() #TODO: Remove when bug is fixed
-            self.__switch_info = self.__settings[SWITCH_INFO]
+            LOGGER.error("Failed to parse service settings: {}".format(ex))
+            raise Exception(ex)
         assert isinstance(self.__switch_info, dict), "Switch info object must be a map with switch names as keys"
 
         for switch_name, switch_info in self.__switch_info.items():
diff --git a/src/tests/p4-fabric-tna/descriptors/service-create-acl.json b/src/tests/p4-fabric-tna/descriptors/service-create-acl.json
index a0383f472..2ec9c6674 100644
--- a/src/tests/p4-fabric-tna/descriptors/service-create-acl.json
+++ b/src/tests/p4-fabric-tna/descriptors/service-create-acl.json
@@ -9,11 +9,11 @@
             "service_status": {"service_status": "SERVICESTATUS_PLANNED"},
             "service_endpoint_ids": [
                 {
-                    "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+                    "device_id": {"device_uuid": {"uuid": "sw1"}},
                     "endpoint_uuid": {"uuid": "1"}
                 },
                 {
-                    "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+                    "device_id": {"device_uuid": {"uuid": "sw1"}},
                     "endpoint_uuid": {"uuid": "2"}
                 }
             ],
@@ -25,7 +25,7 @@
                             "resource_key": "/settings",
                             "resource_value": {
                                 "switch_info": {
-                                    "p4-sw1": {
+                                    "sw1": {
                                         "arch": "v1model",
                                         "dpid": 1,
                                         "acl": [
diff --git a/src/tests/p4-fabric-tna/descriptors/service-create-int.json b/src/tests/p4-fabric-tna/descriptors/service-create-int.json
index 98956b959..785468f68 100644
--- a/src/tests/p4-fabric-tna/descriptors/service-create-int.json
+++ b/src/tests/p4-fabric-tna/descriptors/service-create-int.json
@@ -9,11 +9,11 @@
             "service_status": {"service_status": "SERVICESTATUS_PLANNED"},
             "service_endpoint_ids": [
                 {
-                    "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+                    "device_id": {"device_uuid": {"uuid": "sw1"}},
                     "endpoint_uuid": {"uuid": "1"}
                 },
                 {
-                    "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+                    "device_id": {"device_uuid": {"uuid": "sw1"}},
                     "endpoint_uuid": {"uuid": "2"}
                 }
             ],
@@ -25,11 +25,11 @@
                             "resource_key": "/settings",
                             "resource_value": {
                                 "switch_info": {
-                                    "p4-sw1": {
+                                    "sw1": {
                                         "arch": "v1model",
                                         "dpid": 1,
-                                        "mac": "fa:16:3e:93:8c:c0",
-                                        "ip": "10.10.10.120",
+                                        "mac": "ee:ee:8c:6c:f3:2c",
+                                        "ip": "192.168.5.139",
                                         "int_port": {
                                             "port_id": 3,
                                             "port_type": "host"
@@ -37,8 +37,8 @@
                                     }
                                 },
                                 "int_collector_info": {
-                                    "mac": "fa:16:3e:fb:cf:96",
-                                    "ip": "10.10.10.41",
+                                    "mac": "46:e4:58:c6:74:53",
+                                    "ip": "192.168.5.137",
                                     "port": 32766,
                                     "vlan_id": 4094
                                 }
diff --git a/src/tests/p4-fabric-tna/descriptors/service-create-l2-simple.json b/src/tests/p4-fabric-tna/descriptors/service-create-l2-simple.json
index 5a659f3d9..05f53d7a6 100644
--- a/src/tests/p4-fabric-tna/descriptors/service-create-l2-simple.json
+++ b/src/tests/p4-fabric-tna/descriptors/service-create-l2-simple.json
@@ -9,11 +9,11 @@
             "service_status": {"service_status": "SERVICESTATUS_PLANNED"},
             "service_endpoint_ids": [
                 {
-                    "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+                    "device_id": {"device_uuid": {"uuid": "sw1"}},
                     "endpoint_uuid": {"uuid": "1"}
                 },
                 {
-                    "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+                    "device_id": {"device_uuid": {"uuid": "sw1"}},
                     "endpoint_uuid": {"uuid": "2"}
                 }
             ],
@@ -25,7 +25,7 @@
                             "resource_key": "/settings",
                             "resource_value": {
                                 "switch_info": {
-                                    "p4-sw1": {
+                                    "sw1": {
                                         "arch": "v1model",
                                         "dpid": 1,
                                         "port_list": [
@@ -43,11 +43,11 @@
                                         "fwd_list": [
                                             {
                                                 "port_id": 1,
-                                                "host_mac": "fa:16:3e:75:9c:e5"
+                                                "host_mac": "00:00:00:00:00:01"
                                             },
                                             {
                                                 "port_id": 2,
-                                                "host_mac": "fa:16:3e:e2:af:28"
+                                                "host_mac": "00:00:00:00:00:02"
                                             }
                                         ]
                                     }
diff --git a/src/tests/p4-fabric-tna/descriptors/service-create-l3.json b/src/tests/p4-fabric-tna/descriptors/service-create-l3.json
index 7d8153e7a..4a016f255 100644
--- a/src/tests/p4-fabric-tna/descriptors/service-create-l3.json
+++ b/src/tests/p4-fabric-tna/descriptors/service-create-l3.json
@@ -9,11 +9,11 @@
             "service_status": {"service_status": "SERVICESTATUS_PLANNED"},
             "service_endpoint_ids": [
                 {
-                    "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+                    "device_id": {"device_uuid": {"uuid": "sw1"}},
                     "endpoint_uuid": {"uuid": "1"}
                 },
                 {
-                    "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+                    "device_id": {"device_uuid": {"uuid": "sw1"}},
                     "endpoint_uuid": {"uuid": "2"}
                 }
             ],
@@ -25,7 +25,7 @@
                             "resource_key": "/settings",
                             "resource_value": {
                                 "switch_info": {
-                                    "p4-sw1": {
+                                    "sw1": {
                                         "arch": "v1model",
                                         "dpid": 1,
                                         "port_list": [
@@ -41,17 +41,17 @@
                                         "routing_list": [
                                             {
                                                 "port_id": 1,
-                                                "ipv4_dst": "10.158.72.11",
+                                                "ipv4_dst": "10.0.0.1",
                                                 "ipv4_prefix_len": 32,
-                                                "mac_src": "fa:16:3e:e2:af:28",
-                                                "mac_dst": "fa:16:3e:75:9c:e5"
+                                                "mac_src": "00:00:00:00:00:02",
+                                                "mac_dst": "00:00:00:00:00:01"
                                             },
                                             {
                                                 "port_id": 2,
-                                                "ipv4_dst": "172.16.10.9",
+                                                "ipv4_dst": "10.0.0.2",
                                                 "ipv4_prefix_len": 32,
-                                                "mac_src": "fa:16:3e:75:9c:e5",
-                                                "mac_dst": "fa:16:3e:e2:af:28"
+                                                "mac_src": "00:00:00:00:00:01",
+                                                "mac_dst": "00:00:00:00:00:02"
                                             }
                                         ]
                                     }
diff --git a/src/tests/p4-fabric-tna/descriptors/topology.json b/src/tests/p4-fabric-tna/descriptors/topology.json
index 30e1f5e9a..908faaa7d 100644
--- a/src/tests/p4-fabric-tna/descriptors/topology.json
+++ b/src/tests/p4-fabric-tna/descriptors/topology.json
@@ -11,11 +11,11 @@
             "device_id": {"device_uuid": {"uuid": "tfs-sdn-controller"}},
             "name": "tfs-sdn-controller",
             "device_type": "teraflowsdn",
-            "device_drivers": ["DEVICEDRIVER_IETF_L3VPN"],
+            "device_drivers": ["DEVICEDRIVER_IETF_L2VPN"],
             "device_operational_status": "DEVICEOPERATIONALSTATUS_UNDEFINED",
             "device_config": {"config_rules": [
-                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.10.10.41"}},
-                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8002"}},
+                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "192.168.5.137"}},
+                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8003"}},
                 {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
                     "endpoints": [{"uuid": "mgmt", "name": "mgmt", "type": "mgmt-int"}],
                     "scheme": "http", "username": "admin", "password": "admin", "import_topology": "topology"
@@ -51,18 +51,18 @@
             }
         },
         {
-            "device_id": {"device_uuid": {"uuid": "p4-sw1"}},
+            "device_id": {"device_uuid": {"uuid": "sw1"}},
             "device_type": "p4-switch",
             "device_drivers": ["DEVICEDRIVER_P4"],
             "device_operational_status": "DEVICEOPERATIONALSTATUS_DISABLED",
-            "name": "p4-sw1",
+            "name": "sw1",
             "device_config": {
                 "config_rules": [
-                    {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/address", "resource_value": "10.10.10.120"}},
+                    {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/address", "resource_value": "192.168.5.139"}},
                     {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/port", "resource_value": "50001"}},
                     {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/settings", "resource_value": {
                         "id": 1,
-                        "name": "p4-sw1",
+                        "name": "sw1",
                         "vendor": "Open Networking Foundation",
                         "hw_ver": "BMv2 simple_switch",
                         "sw_ver": "Stratum",
@@ -81,32 +81,32 @@
     ],
     "links": [
         {
-            "link_id": {"link_uuid": {"uuid": "p4-sw1/1==edge-net/eth1"}}, "link_type": "LINKTYPE_VIRTUAL", "link_endpoint_ids": [
-                {"device_id": {"device_uuid": {"uuid": "p4-sw1"}},   "endpoint_uuid": {"uuid": "1"}},
+            "link_id": {"link_uuid": {"uuid": "sw1/1==edge-net/eth1"}}, "link_type": "LINKTYPE_VIRTUAL", "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "sw1"}},      "endpoint_uuid": {"uuid": "1"}},
                 {"device_id": {"device_uuid": {"uuid": "edge-net"}}, "endpoint_uuid": {"uuid": "eth1"}}
             ]
         },
         {
-            "link_id": {"link_uuid": {"uuid": "edge-net/eth1==p4-sw1/1"}}, "link_type": "LINKTYPE_VIRTUAL", "link_endpoint_ids": [
+            "link_id": {"link_uuid": {"uuid": "edge-net/eth1==sw1/1"}}, "link_type": "LINKTYPE_VIRTUAL", "link_endpoint_ids": [
                 {"device_id": {"device_uuid": {"uuid": "edge-net"}}, "endpoint_uuid": {"uuid": "eth1"}},
-                {"device_id": {"device_uuid": {"uuid": "p4-sw1"}},   "endpoint_uuid": {"uuid": "1"}}
+                {"device_id": {"device_uuid": {"uuid": "sw1"}},      "endpoint_uuid": {"uuid": "1"}}
             ]
         },
         {
-            "link_id": {"link_uuid": {"uuid": "p4-sw1/2==corporate-net/eth1"}}, "link_type": "LINKTYPE_VIRTUAL", "link_endpoint_ids": [
-                {"device_id": {"device_uuid": {"uuid": "p4-sw1"}},        "endpoint_uuid": {"uuid": "2"}},
+            "link_id": {"link_uuid": {"uuid": "sw1/2==corporate-net/eth1"}}, "link_type": "LINKTYPE_VIRTUAL", "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "sw1"}},           "endpoint_uuid": {"uuid": "2"}},
                 {"device_id": {"device_uuid": {"uuid": "corporate-net"}}, "endpoint_uuid": {"uuid": "eth1"}}
             ]
         },
         {
-            "link_id": {"link_uuid": {"uuid": "corporate-net/eth1==p4-sw1/2"}}, "link_type": "LINKTYPE_VIRTUAL", "link_endpoint_ids": [
+            "link_id": {"link_uuid": {"uuid": "corporate-net/eth1==sw1/2"}}, "link_type": "LINKTYPE_VIRTUAL", "link_endpoint_ids": [
                 {"device_id": {"device_uuid": {"uuid": "corporate-net"}}, "endpoint_uuid": {"uuid": "eth1"}},
-                {"device_id": {"device_uuid": {"uuid": "p4-sw1"}},        "endpoint_uuid": {"uuid": "2"}}
+                {"device_id": {"device_uuid": {"uuid": "sw1"}},           "endpoint_uuid": {"uuid": "2"}}
             ]
         },
         {
-            "link_id": {"link_uuid": {"uuid": "p4-sw1/3==tfs-sdn-controller/mgmt"}}, "link_type": "LINKTYPE_MANAGEMENT", "link_endpoint_ids": [
-                {"device_id": {"device_uuid": {"uuid": "p4-sw1"}},             "endpoint_uuid": {"uuid": "3"}},
+            "link_id": {"link_uuid": {"uuid": "sw1/3==tfs-sdn-controller/mgmt"}}, "link_type": "LINKTYPE_MANAGEMENT", "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "sw1"}},                "endpoint_uuid": {"uuid": "3"}},
                 {"device_id": {"device_uuid": {"uuid": "tfs-sdn-controller"}}, "endpoint_uuid": {"uuid": "mgmt"}}
             ]
         }
diff --git a/src/tests/p4-fabric-tna/topology/p4-switch-three-port-chassis-config-phy.pb.txt b/src/tests/p4-fabric-tna/topology/p4-switch-three-port-chassis-config-phy.pb.txt
index 038d36269..bc13f29d9 100644
--- a/src/tests/p4-fabric-tna/topology/p4-switch-three-port-chassis-config-phy.pb.txt
+++ b/src/tests/p4-fabric-tna/topology/p4-switch-three-port-chassis-config-phy.pb.txt
@@ -18,10 +18,11 @@
 description: "Chassis configuration for a single Stratum bmv2 switch with 3 ports"
 chassis {
   platform: PLT_P4_SOFT_SWITCH
-  name: "bmv2-switch"
+  name: "sw1"
 }
 nodes {
   id: 1
+  name: "sw1 node 1"
   slot: 1
   index: 1
 }
-- 
GitLab


From 08533d97d5d59cc97765777fce9d85dc3b59b5cd Mon Sep 17 00:00:00 2001
From: "Georgios P. Katsikas" <gkatsikas@ubitech.eu>
Date: Thu, 8 May 2025 12:25:17 +0300
Subject: [PATCH 14/14] fix: service types order in proto

---
 proto/context.proto                                | 12 ++++++------
 src/common/tools/object_factory/Service.py         |  2 +-
 .../p4-fwd-l1/tests/topologies/6switchObjects.py   | 14 ++------------
 3 files changed, 9 insertions(+), 19 deletions(-)

diff --git a/proto/context.proto b/proto/context.proto
index 0f2c8011f..525997847 100644
--- a/proto/context.proto
+++ b/proto/context.proto
@@ -321,12 +321,12 @@ enum ServiceTypeEnum {
   SERVICETYPE_UNKNOWN = 0;
   SERVICETYPE_L3NM = 1;
   SERVICETYPE_L2NM = 2;
-  SERVICETYPE_L1NM = 3;
-  SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 4;
-  SERVICETYPE_TE = 5;
-  SERVICETYPE_E2E = 6;
-  SERVICETYPE_OPTICAL_CONNECTIVITY = 7;
-  SERVICETYPE_QKD = 8;
+  SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3;
+  SERVICETYPE_TE = 4;
+  SERVICETYPE_E2E = 5;
+  SERVICETYPE_OPTICAL_CONNECTIVITY = 6;
+  SERVICETYPE_QKD = 7;
+  SERVICETYPE_L1NM = 8;
   SERVICETYPE_INT = 9;
   SERVICETYPE_ACL = 10;
 }
diff --git a/src/common/tools/object_factory/Service.py b/src/common/tools/object_factory/Service.py
index 74c183230..0d039ac35 100644
--- a/src/common/tools/object_factory/Service.py
+++ b/src/common/tools/object_factory/Service.py
@@ -90,6 +90,6 @@ def json_service_p4_planned(
     ):
 
     return json_service(
-        service_uuid, ServiceTypeEnum.SERVICETYPE_L2NM, context_id=json_context_id(context_uuid),
+        service_uuid, ServiceTypeEnum.SERVICETYPE_L1NM, context_id=json_context_id(context_uuid),
         status=ServiceStatusEnum.SERVICESTATUS_PLANNED, endpoint_ids=endpoint_ids, constraints=constraints,
         config_rules=config_rules)
\ No newline at end of file
diff --git a/src/tests/p4-fwd-l1/tests/topologies/6switchObjects.py b/src/tests/p4-fwd-l1/tests/topologies/6switchObjects.py
index 522066bb0..69a68a569 100644
--- a/src/tests/p4-fwd-l1/tests/topologies/6switchObjects.py
+++ b/src/tests/p4-fwd-l1/tests/topologies/6switchObjects.py
@@ -312,12 +312,6 @@ LINK_SW5_SW6                = json_link(LINK_SW5_SW6_UUID, [ENDPOINT_ID_SW5_2, E
 
 # ----- Service ----------------------------------------------------------------------------------------------------------
 
-#SERVICE_SW1_UUID        = get_service_uuid(ENDPOINT_ID_SW1_1, ENDPOINT_ID_SW1_2)
-#SERVICE_SW1             = json_service_p4_planned(SERVICE_SW1_UUID)
-
-#SERVICE_SW2_UUID        = get_service_uuid(ENDPOINT_ID_SW2_1, ENDPOINT_ID_SW2_2)
-#SERVICE_SW2             = json_service_p4_planned(SERVICE_SW2_UUID)
-
 SERVICE_SW1_SW6_UUID            = get_service_uuid(ENDPOINT_ID_SW1_3, ENDPOINT_ID_SW6_3)
 SERVICE_SW1_SW6                 = json_service_p4_planned(SERVICE_SW1_SW6_UUID)
 SERVICE_SW1_SW6_ENDPOINT_IDS    = [DEVICE_SW1_ENDPOINT_IDS[2], DEVICE_SW6_ENDPOINT_IDS[2]]
@@ -345,10 +339,6 @@ LINKS = [
 
     LINK_SW4_SW6,
     LINK_SW5_SW6
-    ] 
-
-#SERVICES = [(SERVICE_SW1, DEVICE_SW1_ENDPOINT_IDS), (SERVICE_SW2, DEVICE_SW2_ENDPOINT_IDS)]
-
-#SERVICE_SW1_SW2_ENDPOINT_IDS = DEVICE_SW1_ENDPOINT_IDS + DEVICE_SW2_ENDPOINT_IDS
+    ]
 
-SERVICES = [(SERVICE_SW1_SW6, SERVICE_SW1_SW6_ENDPOINT_IDS)]
\ No newline at end of file
+SERVICES = [(SERVICE_SW1_SW6, SERVICE_SW1_SW6_ENDPOINT_IDS)]
-- 
GitLab