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 510b59ebb84f0af4460ba8f766e8b8be51ce5816..00eccfb4a02375dab48b112a41680a2a384ac2f1 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 @@ -346,83 +346,85 @@ class P4FabricACLServiceHandler(_ServiceHandler): except Exception as ex: 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(): - 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) + assert isinstance(self.__switch_info, list), "Switch info object must be a list" + + for switch in self.__switch_info: + for switch_name, switch_info in switch.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])) + for switch in self.__switch_info: + for switch_name, switch_info in switch.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: @@ -434,7 +436,7 @@ class P4FabricACLServiceHandler(_ServiceHandler): 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] 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 c5ecdd6823665c8a11d2cc7833f9214e8e0ec71e..73d555a0bdd12d0bebb1517431da84a3470595a4 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 @@ -316,27 +316,29 @@ class P4FabricINTServiceHandler(_ServiceHandler): except Exception as ex: 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(): - 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) + assert isinstance(self.__switch_info, list), "Switch info object must be a list" + + # for switch_name, switch_info in self.__switch_info.items(): + for switch in self.__switch_info: + for switch_name, switch_info in switch.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.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)" @@ -356,16 +358,17 @@ class P4FabricINTServiceHandler(_ServiceHandler): 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])) + for switch in self.__switch_info: + for switch_name, switch_info in switch.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)) 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 c24bdc880a0f3da485568aaaaf94dcfe183e47e6..d58a183ef8966aa6c9ea886207c9e1831839e4ac 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 @@ -329,62 +329,64 @@ class P4FabricL2SimpleServiceHandler(_ServiceHandler): except Exception as ex: 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(): - 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) + assert isinstance(self.__switch_info, list), "Switch info object must be a list" + + for switch in self.__switch_info: + for switch_name, switch_info in switch.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])) + for switch in self.__switch_info: + for switch_name, switch_info in switch.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: @@ -452,7 +454,7 @@ class P4FabricL2SimpleServiceHandler(_ServiceHandler): 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( 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 c97d388291505183fc43fcc948cb1bc9129646ed..cc7a8dbd5441c9adf501956463c875a9758eca34 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 @@ -327,72 +327,74 @@ class P4FabricL3ServiceHandler(_ServiceHandler): except Exception as ex: 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(): - 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 - } - ) + assert isinstance(self.__switch_info, list), "Switch info object must be a list" + + for switch in self.__switch_info: + for switch_name, switch_info in switch.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])) + for switch in self.__switch_info: + for switch_name, switch_info in switch.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: