- sw_idx_vxlan = Topology.get_interface_sw_index(node, node_vxlan_if)
-
- dst_ip_start_int = IPUtil.ip_to_int(dst_ip_start)
-
- tmp_fn = '/tmp/configure_routes_and_bridge_domains.config'
- commands = list()
- for i in range(0, vxlan_count):
- dst_ip = IPUtil.int_to_ip(dst_ip_start_int + i * ip_step)
- commands.append(
- 'ip_neighbor_add_del sw_if_index {sw_idx} dst {ip} mac {mac}\n'
- .format(sw_idx=sw_idx_vxlan, ip=dst_ip,
- mac=Topology.get_interface_mac(op_node, op_node_if)))
- commands.append(
- 'ip_add_del_route {ip}/32 via {ip} sw_if_index {sw_idx}'
- ' resolve-attempts 10 count 1\n'.format(
- ip=dst_ip, sw_idx=sw_idx_vxlan))
- bd_id = bd_id_start + i
- subif_id = i + 1
- commands.append(
- 'sw_interface_set_l2_bridge sw_if_index {sw_idx} bd_id {bd_id} '
- 'shg 0 enable\n'.format(sw_idx=Topology.get_interface_sw_index(
- node, 'vxlan_tunnel{nr}'.format(nr=subif_id)), bd_id=bd_id))
- commands.append(
- 'sw_interface_set_l2_bridge sw_if_index {sw_idx} bd_id {bd_id} '
- 'shg 0 enable\n'.format(sw_idx=Topology.get_interface_sw_index(
- node, 'vlan_subif{nr}'.format(nr=subif_id)), bd_id=bd_id))
-
- VatExecutor().write_and_execute_script(node, tmp_fn, commands)
+ try:
+ dst_address_start = IPv6Address(unicode(dst_ip_start))
+ af_inet = AF_INET6
+ is_ipv6 = 1
+ except (AddressValueError, NetmaskValueError):
+ dst_address_start = IPv4Address(unicode(dst_ip_start))
+ af_inet = AF_INET
+ is_ipv6 = 0
+
+ with PapiExecutor(node) as papi_exec:
+ for i in xrange(0, vxlan_count):
+ dst_ip = dst_address_start + i * ip_step
+ neighbor = dict(
+ sw_if_index=Topology.get_interface_sw_index(
+ node, node_vxlan_if),
+ flags=0,
+ mac_address=str(
+ Topology.get_interface_mac(op_node, op_node_if)),
+ ip_address=str(dst_ip))
+ cmd = 'ip_neighbor_add_del'
+ args = dict(
+ is_add=1,
+ neighbor=neighbor)
+ papi_exec.add(cmd, **args)
+ cmd = 'ip_add_del_route'
+ args = dict(
+ next_hop_sw_if_index=Topology.get_interface_sw_index(
+ node, node_vxlan_if),
+ table_id=0,
+ is_add=1,
+ is_ipv6=is_ipv6,
+ next_hop_weight=1,
+ next_hop_proto=1 if is_ipv6 else 0,
+ dst_address_length=128 if is_ipv6 else 32,
+ dst_address=inet_pton(af_inet, str(dst_ip)),
+ next_hop_address=inet_pton(af_inet, str(dst_ip)))
+ papi_exec.add(cmd, **args)
+ cmd = 'sw_interface_set_l2_bridge'
+ args = dict(
+ rx_sw_if_index=Topology.get_interface_sw_index(
+ node, 'vxlan_tunnel{nr}'.format(nr=i+1)),
+ bd_id=int(bd_id_start+i),
+ shg=0,
+ port_type=0,
+ enable=1)
+ papi_exec.add(cmd, **args)
+ args = dict(
+ rx_sw_if_index=Topology.get_interface_sw_index(
+ node, 'vlan_subif{nr}'.format(nr=i+1)),
+ bd_id=int(bd_id_start+i),
+ shg=0,
+ port_type=0,
+ enable=1)
+ papi_exec.add(cmd, **args)
+ papi_exec.get_replies().verify_replies()
+
+ @staticmethod
+ def vpp_sw_interface_rx_placement_dump(node):
+ """Dump VPP interface RX placement on node.
+
+ :param node: Node to run command on.
+ :type node: dict
+ :returns: Thread mapping information as a list of dictionaries.
+ :rtype: list
+ """
+ cmd = 'sw_interface_rx_placement_dump'
+ cmd_reply = 'sw_interface_rx_placement_details'
+ err_msg = "Failed to run '{cmd}' PAPI command on host {host}!".format(
+ cmd=cmd, host=node['host'])
+ with PapiExecutor(node) as papi_exec:
+ for ifc in node['interfaces'].values():
+ if ifc['vpp_sw_index'] is not None:
+ papi_exec.add(cmd, sw_if_index=ifc['vpp_sw_index'])
+ papi_resp = papi_exec.get_dump(err_msg)
+ thr_mapping = [s[cmd_reply] for r in papi_resp.reply
+ for s in r['api_reply']]
+ return sorted(thr_mapping, key=lambda k: k['sw_if_index'])
+
+ @staticmethod
+ def vpp_sw_interface_set_rx_placement(node, sw_if_index, queue_id,
+ worker_id):
+ """Set interface RX placement to worker on node.
+
+ :param node: Node to run command on.
+ :param sw_if_index: VPP SW interface index.
+ :param queue_id: VPP interface queue ID.
+ :param worker_id: VPP worker ID (indexing from 0).
+ :type node: dict
+ :type sw_if_index: int
+ :type queue_id: int
+ :type worker_id: int
+ :raises RuntimeError: If failed to run command on host or if no API
+ reply received.
+ """
+ cmd = 'sw_interface_set_rx_placement'
+ err_msg = "Failed to set interface RX placement to worker on host " \
+ "{host}!".format(host=node['host'])
+ args = dict(sw_if_index=sw_if_index, queue_id=queue_id,
+ worker_id=worker_id)
+ with PapiExecutor(node) as papi_exec:
+ papi_exec.add(cmd, **args).get_replies(err_msg).\
+ verify_reply(err_msg=err_msg)
+
+ @staticmethod
+ def vpp_round_robin_rx_placement(node, prefix):
+ """Set Round Robin interface RX placement on all worker threads
+ on node.
+
+ :param node: Topology nodes.
+ :param prefix: Interface name prefix.
+ :type node: dict
+ :type prefix: str
+ """
+ worker_id = 0
+ worker_cnt = len(VPPUtil.vpp_show_threads(node)) - 1
+ for placement in InterfaceUtil.vpp_sw_interface_rx_placement_dump(node):
+ for interface in node['interfaces'].values():
+ if placement['sw_if_index'] == interface['vpp_sw_index'] \
+ and prefix in interface['name']:
+ InterfaceUtil.vpp_sw_interface_set_rx_placement(
+ node, placement['sw_if_index'], placement['queue_id'],
+ worker_id % worker_cnt)
+ worker_id += 1
+
+ @staticmethod
+ def vpp_round_robin_rx_placement_on_all_duts(nodes, prefix):
+ """Set Round Robin interface RX placement on all worker threads
+ on all DUTs.
+
+ :param nodes: Topology nodes.
+ :param prefix: Interface name prefix.
+ :type nodes: dict
+ :type prefix: str
+ """
+ for node in nodes.values():
+ if node['type'] == NodeType.DUT:
+ InterfaceUtil.vpp_round_robin_rx_placement(node, prefix)