Loading src/common/type_checkers/Checkers.py +9 −0 Original line number Diff line number Diff line Loading @@ -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. Loading src/service/service/service_handlers/p4_fabric_tna_commons/p4_fabric_tna_commons.py +74 −22 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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)) Loading @@ -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 ################################################################################################################ Loading @@ -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()] Loading @@ -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', Loading Loading @@ -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 } ], Loading @@ -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 } ) ) Loading @@ -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( Loading Loading @@ -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) Loading Loading @@ -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) Loading @@ -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', Loading Loading @@ -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) Loading @@ -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) } ], Loading @@ -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 = [] Loading @@ -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) } ], Loading @@ -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) Loading Loading @@ -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 Loading src/tests/tools/test_tools_p4.py +3 −3 Original line number Diff line number Diff line Loading @@ -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 Loading src/service/service/task_scheduler/TaskExecutor.py +1 −1 File changed.Contains only whitespace changes. Show changes Loading
src/common/type_checkers/Checkers.py +9 −0 Original line number Diff line number Diff line Loading @@ -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. Loading
src/service/service/service_handlers/p4_fabric_tna_commons/p4_fabric_tna_commons.py +74 −22 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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)) Loading @@ -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 ################################################################################################################ Loading @@ -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()] Loading @@ -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', Loading Loading @@ -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 } ], Loading @@ -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 } ) ) Loading @@ -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( Loading Loading @@ -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) Loading Loading @@ -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) Loading @@ -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', Loading Loading @@ -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) Loading @@ -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) } ], Loading @@ -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 = [] Loading @@ -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) } ], Loading @@ -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) Loading Loading @@ -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 Loading
src/tests/tools/test_tools_p4.py +3 −3 Original line number Diff line number Diff line Loading @@ -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 Loading
src/service/service/task_scheduler/TaskExecutor.py +1 −1 File changed.Contains only whitespace changes. Show changes