def apply_route_config_for_port(request, duthost, ptfhost, define_sub_ports_configuration, apply_config_on_the_dut, apply_config_on_the_ptf): """ Apply route configuration on the PTF and remove after tests Args: request: pytest request object duthost: DUT host object ptfhost: PTF host object define_sub_ports_configuration: Dictonary of parameters for configuration DUT apply_config_on_the_dut: fixture for applying sub-ports configuration on the DUT apply_config_on_the_ptf: fixture for applying sub-ports configuration on the PTF Yields: Dictonary of parameters for configuration DUT and PTF host """ port_map = {} vlan_id = 999 sub_ports = define_sub_ports_configuration['sub_ports'] dut_ports = define_sub_ports_configuration['dut_ports'] port_type = define_sub_ports_configuration['port_type'] subnet = define_sub_ports_configuration['subnet'] # Get additional port for configuration of SVI port or L3 RIF if 'svi' in request.param: interface_num = 1 else: interface_num = 2 dut_ports, ptf_ports = get_port(duthost, ptfhost, interface_num, port_type, dut_ports.values(), exclude_sub_interface_ports=True) # Get additional IP addresses for configuration of RIF on the DUT and PTF subnet = ipaddress.ip_network(str(subnet.broadcast_address + 1) + u'/24') subnets = [i for i, _ in zip(subnet.subnets(new_prefix=30), dut_ports)] sub_ports_keys = sub_ports.copy() for dut_port, ptf_port, subnet in zip(dut_ports.values(), ptf_ports, subnets): dut_port_ip, ptf_port_ip = ('{}/{}'.format(host, 30) for host in subnet.hosts()) remove_ip_from_port(duthost, dut_port) if 'svi' in request.param: # Configure SVI port on the DUT ptf_port = '{}.{}'.format(ptf_port, vlan_id) remove_member_from_vlan(duthost, vlan_id, dut_port) setup_vlan(duthost, vlan_id) add_member_to_vlan(duthost, vlan_id, dut_port) add_ip_to_dut_port(duthost, 'Vlan{}'.format(vlan_id), dut_port_ip) # Configure additional sub-port for connection between SVI port of the DUT and PTF create_sub_port_on_ptf(ptfhost, ptf_port, ptf_port_ip) else: # should remove port from Vlan1000 first to configure L3 RIF remove_member_from_vlan(duthost, '1000', dut_port) # Configure L3 RIF on the DUT add_ip_to_dut_port(duthost, dut_port, dut_port_ip) # Configure L3 RIF on the PTF add_ip_to_ptf_port(ptfhost, ptf_port, ptf_port_ip) # Get two random sub-ports which are not part of the selected DUT interface sub_ports_on_port = random.sample([ sub_port for sub_port in sub_ports_keys if dut_port + '.' not in sub_port ], 2) for sub_port in sub_ports_on_port: sub_ports_keys.pop(sub_port) port_map[ptf_port] = { 'dut_port': dut_port, 'ip': ptf_port_ip, 'neighbor_ip': dut_port_ip, 'dst_ports': [] } # Configure static route between selected sub-ports and selected interfaces on the PTF for next_hop_sub_port in sub_ports_on_port: name_of_namespace = 'vnet_for_{}'.format(next_hop_sub_port) dst_port_network = ipaddress.ip_network(unicode( sub_ports[next_hop_sub_port]['neighbor_ip']), strict=False) # Add selected sub-port to namespace on the PTF add_port_to_namespace( ptfhost, name_of_namespace, sub_ports[next_hop_sub_port]['neighbor_port'], sub_ports[next_hop_sub_port]['neighbor_ip']) # Add static route from sub-port to selected interface on the PTF add_static_route_to_ptf(ptfhost, subnet, sub_ports[next_hop_sub_port]['ip'], name_of_namespace) # Add static route from selected interface to sub-port on the PTF add_static_route_to_ptf(ptfhost, dst_port_network, dut_port_ip) port_map[ptf_port]['dst_ports'].append( (next_hop_sub_port, name_of_namespace)) yield {'port_map': port_map, 'sub_ports': sub_ports} # Teardown for src_port, next_hop_sub_ports in port_map.items(): src_port_network = ipaddress.ip_network(unicode( next_hop_sub_ports['ip']), strict=False) # Remove static route between selected sub-ports and selected interfaces from the PTF for sub_port, name_of_namespace in next_hop_sub_ports['dst_ports']: dst_port_network = ipaddress.ip_network(unicode( sub_ports[sub_port]['ip']), strict=False) remove_static_route_from_ptf(ptfhost, src_port_network, sub_ports[sub_port]['ip'], name_of_namespace) remove_static_route_from_ptf(ptfhost, dst_port_network, next_hop_sub_ports['neighbor_ip']) remove_namespace(ptfhost, name_of_namespace) if 'svi' in request.param: # Remove SVI port from the DUT remove_member_from_vlan(duthost, vlan_id, next_hop_sub_ports['dut_port']) remove_ip_from_port(duthost, 'Vlan{}'.format(vlan_id), ip=next_hop_sub_ports['neighbor_ip']) # Remove additional sub-port from the PTF remove_sub_port_from_ptf(ptfhost, src_port, next_hop_sub_ports['ip']) if 'port_in_lag' in port_type: bond_port = src_port.split('.')[0] cfg_facts = duthost.config_facts( host=duthost.hostname, source="running")['ansible_facts'] remove_lag_port(duthost, cfg_facts, next_hop_sub_ports['dut_port']) remove_bond_port(ptfhost, bond_port, ptf_ports[bond_port]) else: # Remove L3 RIF from the DUT remove_ip_from_port(duthost, next_hop_sub_ports['dut_port'], ip=next_hop_sub_ports['neighbor_ip']) # Remove L3 RIF from the PTF remove_ip_from_ptf_port(ptfhost, src_port, next_hop_sub_ports['ip']) if 'port_in_lag' in port_type: bond_port = src_port cfg_facts = duthost.config_facts( host=duthost.hostname, source="running")['ansible_facts'] remove_lag_port(duthost, cfg_facts, next_hop_sub_ports['dut_port']) remove_bond_port(ptfhost, bond_port, ptf_ports[bond_port]) if 'svi' in request.param: remove_vlan(duthost, vlan_id)
def define_sub_ports_configuration(request, duthost, ptfhost, ptfadapter, port_type, tbinfo): """ Define configuration of sub-ports for TC run Args: request: pytest request object duthost: DUT host object ptfhost: PTF host object port_type: Port type to test Yields: Dictonary of sub-port parameters for configuration DUT and PTF host For example: { 'Ethernet4.10': { 'ip': '172.16.0.1/30', 'neighbor_port': 'eth1.10', 'neighbor_ip': '172.16.0.2/30' }, 'Ethernet4.20': { 'ip': '172.16.0.5/30', 'neighbor_port': 'eth1.20', 'neighbor_ip': '172.16.0.6/30' } } """ sub_ports_config = {} max_numbers_of_sub_ports = request.config.getoption( "--max_numbers_of_sub_ports") vlan_ranges_dut = range(20, 60, 10) vlan_ranges_ptf = range(20, 60, 10) if 'invalid' in request.node.name: vlan_ranges_ptf = range(21, 41, 10) if 'max_numbers' in request.node.name: vlan_ranges_dut = range(11, max_numbers_of_sub_ports + 11) vlan_ranges_ptf = range(11, max_numbers_of_sub_ports + 11) # Linux has the limitation of 15 characters on an interface name, # but name of LAG port should have prefix 'PortChannel' and suffix # '<0-9999>' on SONiC. So max length of LAG port suffix have be 3 characters # For example: 'PortChannel1.99' if 'port_in_lag' in port_type: vlan_range_end = min(100, max_numbers_of_sub_ports + 11) vlan_ranges_dut = range(11, vlan_range_end) vlan_ranges_ptf = range(11, vlan_range_end) interface_num = 2 ip_subnet = u'172.16.0.0/16' prefix = 30 network = ipaddress.ip_network(ip_subnet) # for normal t0, get_port tries to retrieve test ports from vlan members # let's enforce same behavior for t0-backend if "t0-backend" in tbinfo["topo"]["name"]: config_port_indices, ptf_ports = get_port( duthost, ptfhost, interface_num, port_type, exclude_sub_interface_ports=True) else: config_port_indices, ptf_ports = get_port(duthost, ptfhost, interface_num, port_type) subnets = [ i for i, _ in zip(network.subnets(new_prefix=22), config_port_indices) ] for port, ptf_port, subnet in zip(config_port_indices.values(), ptf_ports, subnets): for vlan_id_dut, vlan_id_ptf, net in zip( vlan_ranges_dut, vlan_ranges_ptf, subnet.subnets(new_prefix=30)): hosts_list = [i for i in net.hosts()] sub_ports_config['{}.{}'.format(port, vlan_id_dut)] = { 'ip': '{}/{}'.format(hosts_list[0], prefix), 'neighbor_port': '{}.{}'.format(ptf_port, vlan_id_ptf), 'neighbor_ip': '{}/{}'.format(hosts_list[1], prefix) } yield { 'sub_ports': sub_ports_config, 'dut_ports': config_port_indices, 'ptf_ports': ptf_ports, 'subnet': network, 'interface_ranges': config_port_indices.keys(), 'port_type': port_type }
def define_sub_ports_configuration(request, duthost, ptfhost, ptfadapter): """ Define configuration of sub-ports for TC run Args: request: pytest request object duthost: DUT host object ptfhost: PTF host object Yields: Dictonary of sub-port parameters for configuration DUT and PTF host For example: { 'Ethernet4.10': { 'ip': '172.16.0.1/30', 'neighbor_port': 'eth1.10', 'neighbor_ip': '172.16.0.2/30' }, 'Ethernet4.20': { 'ip': '172.16.0.5/30', 'neighbor_port': 'eth1.20', 'neighbor_ip': '172.16.0.6/30' } } """ sub_ports_config = {} max_numbers_of_sub_ports = request.config.getoption( "--max_numbers_of_sub_ports") vlan_ranges_dut = range(10, 50, 10) vlan_ranges_ptf = range(10, 50, 10) if 'invalid' in request.node.name: vlan_ranges_ptf = range(11, 31, 10) if 'max_numbers' in request.node.name: vlan_ranges_dut = range(1, max_numbers_of_sub_ports + 1) vlan_ranges_ptf = range(1, max_numbers_of_sub_ports + 1) # Linux has the limitation of 15 characters on an interface name, # but name of LAG port should have prefix 'PortChannel' and suffix # '<0-9999>' on SONiC. So max length of LAG port suffix have be 3 characters # For example: 'PortChannel1.99' if 'port_in_lag' in request.param: max_numbers_of_sub_ports = max_numbers_of_sub_ports if max_numbers_of_sub_ports <= 99 else 99 vlan_ranges_dut = range(1, max_numbers_of_sub_ports + 1) vlan_ranges_ptf = range(1, max_numbers_of_sub_ports + 1) interface_num = 2 ip_subnet = u'172.16.0.0/16' prefix = 30 network = ipaddress.ip_network(ip_subnet) config_port_indices, ptf_ports = get_port(duthost, ptfhost, interface_num, request.param) subnets = [ i for i, _ in zip(network.subnets(new_prefix=22), config_port_indices) ] for port, ptf_port, subnet in zip(config_port_indices.values(), ptf_ports, subnets): for vlan_id_dut, vlan_id_ptf, net in zip( vlan_ranges_dut, vlan_ranges_ptf, subnet.subnets(new_prefix=30)): hosts_list = [i for i in net.hosts()] sub_ports_config['{}.{}'.format(port, vlan_id_dut)] = { 'ip': '{}/{}'.format(hosts_list[0], prefix), 'neighbor_port': '{}.{}'.format(ptf_port, vlan_id_ptf), 'neighbor_ip': '{}/{}'.format(hosts_list[1], prefix) } yield { 'sub_ports': sub_ports_config, 'dut_ports': config_port_indices, 'ptf_ports': ptf_ports, 'subnet': network, 'interface_ranges': config_port_indices.keys(), 'port_type': request.param }