def add_bond_eth_interface(node, ifc_name=None, sw_if_idx=None): """Add BondEthernet interface to current topology. :param node: DUT node from topology. :param ifc_name: Name of the BondEthernet interface. :param sw_if_idx: SW interface index. :type node: dict :type ifc_name: str :type sw_if_idx: int """ if_key = Topology.add_new_port(node, 'eth_bond') vat_executor = VatExecutor() vat_executor.execute_script_json_out("dump_interfaces.vat", node) interface_dump_json = vat_executor.get_script_stdout() if ifc_name and sw_if_idx is None: sw_if_idx = VatJsonUtil.get_interface_sw_index_from_json( interface_dump_json, ifc_name) Topology.update_interface_sw_if_index(node, if_key, sw_if_idx) if sw_if_idx and ifc_name is None: ifc_name = InterfaceUtil.vpp_get_interface_name(node, sw_if_idx) Topology.update_interface_name(node, if_key, ifc_name) ifc_mac = VatJsonUtil.get_interface_mac_from_json( interface_dump_json, sw_if_idx) Topology.update_interface_mac_address(node, if_key, ifc_mac)
def modify_tap_interface(node, if_index, tap_name, mac=None): """Modify tap interface like linux interface name or VPP MAC. :param node: Node to modify tap on. :param if_index: Index of tap interface to be modified. :param tap_name: Tap interface name for linux tap. :param mac: Optional MAC address for VPP tap. :type node: dict :type if_index: int :type tap_name: str :type mac: str :returns: Returns a interface index. :rtype: int """ command = 'modify' if mac is not None: args = 'sw_if_index {} tapname {} mac {}'.format( if_index, tap_name, mac) else: args = 'sw_if_index {} tapname {}'.format(if_index, tap_name) with VatTerminal(node) as vat: resp = vat.vat_terminal_exec_cmd_from_template('tap.vat', tap_command=command, tap_arguments=args) if_key = Topology.get_interface_by_sw_index(node, if_index) Topology.update_interface_tap_dev_name(node, if_key, tap_name) if mac: Topology.update_interface_mac_address(node, if_key, mac) return resp[0]['sw_if_index']
def vpp_create_vhost_user_interface(node, socket): """Create Vhost-user interface on VPP node. :param node: Node to create Vhost-user interface on. :param socket: Vhost-user interface socket path. :type node: dict :type socket: str :returns: SW interface index. :rtype: int :raises RuntimeError: If Vhost-user interface creation failed. """ out = VatExecutor.cmd_from_template(node, 'create_vhost_user_if.vat', sock=socket) if out[0].get('retval') == 0: sw_if_idx = int(out[0].get('sw_if_index')) if_key = Topology.add_new_port(node, 'vhost') Topology.update_interface_sw_if_index(node, if_key, sw_if_idx) ifc_name = InterfaceUtil.vpp_get_interface_name(node, sw_if_idx) Topology.update_interface_name(node, if_key, ifc_name) ifc_mac = InterfaceUtil.vpp_get_interface_mac(node, sw_if_idx) Topology.update_interface_mac_address(node, if_key, ifc_mac) Topology.update_interface_vhost_socket(node, if_key, socket) return sw_if_idx else: raise RuntimeError('Create Vhost-user interface failed on node ' '"{}"'.format(node['host']))
def add_tap_interface(node, tap_name, mac=None): """Add tap interface with name and optionally with MAC. :param node: Node to add tap on. :param tap_name: Tap interface name for linux tap. :param mac: Optional MAC address for VPP tap. :type node: dict :type tap_name: str :type mac: str :returns: Returns a interface index. :rtype: int """ command = 'connect' if mac is not None: args = 'tapname {} mac {}'.format(tap_name, mac) else: args = 'tapname {}'.format(tap_name) with VatTerminal(node) as vat: resp = vat.vat_terminal_exec_cmd_from_template('tap.vat', tap_command=command, tap_arguments=args) sw_if_idx = resp[0]['sw_if_index'] if_key = Topology.add_new_port(node, 'tap') Topology.update_interface_sw_if_index(node, if_key, sw_if_idx) ifc_name = Tap.vpp_get_tap_interface_name(node, sw_if_idx) Topology.update_interface_name(node, if_key, ifc_name) if mac is None: mac = Tap.vpp_get_tap_interface_mac(node, sw_if_idx) Topology.update_interface_mac_address(node, if_key, mac) Topology.update_interface_tap_dev_name(node, if_key, tap_name) return sw_if_idx
def vpp_create_vhost_user_interface(node, socket): """Create Vhost-user interface on VPP node. :param node: Node to create Vhost-user interface on. :param socket: Vhost-user interface socket path. :type node: dict :type socket: str :returns: SW interface index. :rtype: int """ cmd = 'create_vhost_user_if' err_msg = 'Failed to create Vhost-user interface on host {host}'.format( host=node['host']) args = dict(sock_filename=str(socket)) with PapiExecutor(node) as papi_exec: sw_if_index = papi_exec.add(cmd, **args).get_sw_if_index(err_msg) # Update the Topology: if_key = Topology.add_new_port(node, 'vhost') Topology.update_interface_sw_if_index(node, if_key, sw_if_index) ifc_name = InterfaceUtil.vpp_get_interface_name(node, sw_if_index) Topology.update_interface_name(node, if_key, ifc_name) ifc_mac = InterfaceUtil.vpp_get_interface_mac(node, sw_if_index) Topology.update_interface_mac_address(node, if_key, ifc_mac) Topology.update_interface_vhost_socket(node, if_key, socket) return sw_if_index
def add_geneve_tunnel(node, local_address, remote_address, vni, multicast_if=None, encap_vrf=0, l3_mode=False, next_index=None): """Add GENEVE tunnel on the specified VPP node. :param node: Topology node. :param local_address: Local IP address. :param remote_address: Remote IP address. :param vni: Virtual network ID. :param multicast_if: Interface key of multicast interface; used only if remote is multicast. (Default value = None) :param encap_vrf: The FIB ID for sending unicast GENEVE encap packets or receiving multicast packets. (Default value = 0) :param l3_mode: Use geneve tunnel in L3 mode (ip routing) if Tue else in L2 mode (L2 switching). (Default value = False) :param next_index: The index of the next node. :type node: dict :type local_address: str :type remote_address: str :type vni: int :type multicast_if: str :type encap_vrf: int :type l3_mode: bool :type next_index: int :returns: SW interface index of created geneve tunnel. :rtype: int """ cmd = u"geneve_add_del_tunnel2" args = dict(is_add=True, local_address=IPAddress.create_ip_address_object( ip_address(local_address)), remote_address=IPAddress.create_ip_address_object( ip_address(remote_address)), mcast_sw_if_index=Topology.get_interface_sw_index( node, multicast_if) if multicast_if else Constants.BITWISE_NON_ZERO, encap_vrf_id=int(encap_vrf), decap_next_index=next_index if l3_mode else Constants.BITWISE_NON_ZERO, vni=int(vni), l3_mode=l3_mode) err_msg = f"Failed to configure GENEVE tunnel on host {node[u'host']}!" with PapiSocketExecutor(node) as papi_exec: sw_if_index = papi_exec.add(cmd, **args).get_sw_if_index(err_msg) if_key = Topology.add_new_port(node, u"geneve_tunnel") Topology.update_interface_sw_if_index(node, if_key, sw_if_index) ifc_name = InterfaceUtil.vpp_get_interface_name(node, sw_if_index) Topology.update_interface_name(node, if_key, ifc_name) ifc_mac = InterfaceUtil.vpp_get_interface_mac(node, sw_if_index) Topology.update_interface_mac_address(node, if_key, ifc_mac) return sw_if_index
def create_memif_interface(node, filename, mid, sid, rxq=1, txq=1, role="SLAVE"): """Create Memif interface on the given node. :param node: Given node to create Memif interface on. :param filename: Memif interface socket filename. :param mid: Memif interface ID. :param sid: Socket ID. :param rxq: Number of RX queues; 0 means do not set. :param txq: Number of TX queues; 0 means do not set. :param role: Memif interface role [master=0|slave=1]. Default is master. :type node: dict :type filename: str :type mid: str :type sid: str :type rxq: int :type txq: int :type role: str :returns: SW interface index. :rtype: int :raises ValueError: If command 'create memif' fails. """ role = getattr(MemifRole, role.upper()).value # Create socket Memif._memif_socket_filename_add_del(node, True, filename, sid) # Create memif sw_if_index = Memif._memif_create(node, mid, sid, rxq=rxq, txq=txq, role=role) # Update Topology if_key = Topology.add_new_port(node, 'memif') Topology.update_interface_sw_if_index(node, if_key, sw_if_index) ifc_name = Memif.vpp_get_memif_interface_name(node, sw_if_index) Topology.update_interface_name(node, if_key, ifc_name) ifc_mac = Memif.vpp_get_memif_interface_mac(node, sw_if_index) Topology.update_interface_mac_address(node, if_key, ifc_mac) Topology.update_interface_memif_socket(node, if_key, '/tmp/' + filename) Topology.update_interface_memif_id(node, if_key, mid) Topology.update_interface_memif_role(node, if_key, str(role)) return sw_if_index
def add_tap_interface(node, tap_name, mac=None, num_rx_queues=1): """Add tap interface with name and optionally with MAC. :param node: Node to add tap on. :param tap_name: Tap interface name for linux tap. :param mac: Optional MAC address for VPP tap. :param num_rx_queues: Number of RX queues. :type node: dict :type tap_name: str :type mac: str :type num_rx_queues: int :returns: Returns a interface index. :rtype: int """ cmd = u"tap_create_v2" args = dict(id=Constants.BITWISE_NON_ZERO, use_random_mac=bool(mac is None), mac_address=L2Util.mac_to_bin(mac) if mac else None, num_rx_queues=int(num_rx_queues), host_mtu_set=False, host_mac_addr_set=False, host_ip4_prefix_set=False, host_ip6_prefix_set=False, host_ip4_gw_set=False, host_ip6_gw_set=False, host_namespace_set=False, host_if_name_set=True, host_if_name=tap_name, host_bridge_set=False) err_msg = f"Failed to create tap interface {tap_name} " \ f"on host {node[u'host']}" with PapiSocketExecutor(node) as papi_exec: sw_if_index = papi_exec.add(cmd, **args).get_sw_if_index(err_msg) if_key = Topology.add_new_port(node, u"tap") Topology.update_interface_sw_if_index(node, if_key, sw_if_index) Topology.update_interface_name(node, if_key, tap_name) if mac is None: mac = Tap.vpp_get_tap_interface_mac(node, tap_name) Topology.update_interface_mac_address(node, if_key, mac) tap_dev_name = Tap.vpp_get_tap_dev_name(node, tap_name) Topology.update_interface_tap_dev_name(node, if_key, tap_dev_name) return sw_if_index
def vpp_create_vhost_user_interface(node, socket, is_server=False, virtio_feature_mask=None): """Create Vhost-user interface on VPP node. :param node: Node to create Vhost-user interface on. :param socket: Vhost-user interface socket path. :param is_server: Server side of connection. Default: False :param virtio_feature_mask: Mask of virtio features to be enabled. :type node: dict :type socket: str :type is_server: bool :type virtio_feature_mask: int :returns: SW interface index. :rtype: int """ cmd = u"create_vhost_user_if" err_msg = f"Failed to create Vhost-user interface " \ f"on host {node[u'host']}" if virtio_feature_mask is None: enable_gso = False else: enable_gso = VirtioFeatureMask.is_feature_enabled( virtio_feature_mask, VirtioFeaturesFlags.VIRTIO_NET_F_API_GSO) args = dict(is_server=bool(is_server), sock_filename=str(socket), enable_gso=bool(enable_gso)) with PapiSocketExecutor(node) as papi_exec: sw_if_index = papi_exec.add(cmd, **args).get_sw_if_index(err_msg) # Update the Topology: if_key = Topology.add_new_port(node, u"vhost") Topology.update_interface_sw_if_index(node, if_key, sw_if_index) ifc_name = InterfaceUtil.vpp_get_interface_name(node, sw_if_index) Topology.update_interface_name(node, if_key, ifc_name) ifc_mac = InterfaceUtil.vpp_get_interface_mac(node, sw_if_index) Topology.update_interface_mac_address(node, if_key, ifc_mac) Topology.update_interface_vhost_socket(node, if_key, socket) return sw_if_index
def create_memif_interface(node, socket, mid, role='master'): """Create Memif interface on the given node. :param node: Given node to create Memif interface on. :param socket: Memif interface socket path. :param mid: Memif interface ID. :param role: Memif interface role [master|slave]. Default is master. :type node: dict :type socket: str :type mid: str :type role: str :returns: SW interface index. :rtype: int :raises ValueError: If command 'create memif' fails. """ with VatTerminal(node, json_param=False) as vat: vat.vat_terminal_exec_cmd_from_template( 'memif_create.vat', socket=socket, id=mid, role=role) if 'sw_if_index' in vat.vat_stdout: try: sw_if_idx = int(vat.vat_stdout.split()[4]) if_key = Topology.add_new_port(node, 'memif') Topology.update_interface_sw_if_index( node, if_key, sw_if_idx) ifc_name = Memif.vpp_get_memif_interface_name( node, sw_if_idx) Topology.update_interface_name(node, if_key, ifc_name) ifc_mac = Memif.vpp_get_memif_interface_mac(node, sw_if_idx) Topology.update_interface_mac_address(node, if_key, ifc_mac) Topology.update_interface_memif_socket(node, if_key, socket) Topology.update_interface_memif_id(node, if_key, mid) Topology.update_interface_memif_role(node, if_key, role) return sw_if_idx except KeyError: raise ValueError('Create Memif interface failed on node ' '{}'.format(node['host'])) else: raise ValueError('Create Memif interface failed on node ' '{}'.format(node['host']))
def vpp_create_vhost_user_interface( node, socket, is_server=False, enable_gso=False): """Create Vhost-user interface on VPP node. :param node: Node to create Vhost-user interface on. :param socket: Vhost-user interface socket path. :param is_server: Server side of connection. Default: False :param enable_gso: Generic segmentation offloading. Default: False :type node: dict :type socket: str :type is_server: bool :type enable_gso: bool :returns: SW interface index. :rtype: int """ cmd = u"create_vhost_user_if" err_msg = f"Failed to create Vhost-user interface " \ f"on host {node[u'host']}" args = dict( is_server=bool(is_server), sock_filename=str(socket), enable_gso=bool(enable_gso) ) with PapiSocketExecutor(node) as papi_exec: sw_if_index = papi_exec.add(cmd, **args).get_sw_if_index(err_msg) # Update the Topology: if_key = Topology.add_new_port(node, u"vhost") Topology.update_interface_sw_if_index(node, if_key, sw_if_index) ifc_name = InterfaceUtil.vpp_get_interface_name(node, sw_if_index) Topology.update_interface_name(node, if_key, ifc_name) ifc_mac = InterfaceUtil.vpp_get_interface_mac(node, sw_if_index) Topology.update_interface_mac_address(node, if_key, ifc_mac) Topology.update_interface_vhost_socket(node, if_key, socket) return sw_if_index
def create_memif_interface(node, filename, mid, sid, rxq=1, txq=1, role='slave'): """Create Memif interface on the given node. :param node: Given node to create Memif interface on. :param filename: Memif interface socket filename. :param mid: Memif interface ID. :param sid: Socket ID. :param rxq: Number of RX queues. :param txq: Number of TX queues. :param role: Memif interface role [master|slave]. Default is master. :type node: dict :type filename: str :type mid: str :type sid: str :type rxq: int :type txq: int :type role: str :returns: SW interface index. :rtype: int :raises ValueError: If command 'create memif' fails. """ with VatTerminal(node, json_param=False) as vat: vat.vat_terminal_exec_cmd_from_template( 'memif_socket_filename_add_del.vat', add_del='add', id=sid, filename='/tmp/' + filename) vat.vat_terminal_exec_cmd_from_template('memif_create.vat', id=mid, socket=sid, rxq=rxq, txq=txq, role=role) if 'sw_if_index' in vat.vat_stdout: try: sw_if_idx = int(vat.vat_stdout.split()[4]) if_key = Topology.add_new_port(node, 'memif') Topology.update_interface_sw_if_index( node, if_key, sw_if_idx) ifc_name = Memif.vpp_get_memif_interface_name( node, sw_if_idx) Topology.update_interface_name(node, if_key, ifc_name) ifc_mac = Memif.vpp_get_memif_interface_mac( node, sw_if_idx) Topology.update_interface_mac_address( node, if_key, ifc_mac) Topology.update_interface_memif_socket( node, if_key, '/tmp/' + filename) Topology.update_interface_memif_id(node, if_key, mid) Topology.update_interface_memif_role(node, if_key, role) return sw_if_idx except KeyError: raise ValueError('Create Memif interface failed on node ' '{}'.format(node['host'])) else: raise ValueError('Create Memif interface failed on node ' '{}'.format(node['host']))