Commit 7b9e3010 authored by Georgios P. Katsikas's avatar Georgios P. Katsikas
Browse files

feat: support for more NFs and fixes

parent afbe8b59
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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.
+74 −22
Original line number Diff line number Diff line
@@ -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

+3 −3
Original line number Diff line number Diff line
@@ -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
+1 −1

File changed.

Contains only whitespace changes.