@@ -24,18 +24,18 @@ def _nicctl_path(self) -> str:
2424 return str (self .connection .path (self .mtl_path , "script" , self .tool_name ))
2525 return str (self .connection .path (nicctl_path , self .tool_name ))
2626
27- def _parse_vf_list (self , output : str , all : bool = True ) -> list :
27+ def _parse_vf_list (self , output : str ) -> list :
2828 if "No VFs found" in output :
2929 return []
30- vf_info_regex = r"\d{1,3}\s+(. +)\s+vfio" if all else r"(\d{4}:\S+) "
30+ vf_info_regex = r"( \d{4}[0-9a-fA-F:.] +)\(?\S*\)?\s+\S*\s*vfio "
3131 return re .findall (vf_info_regex , output )
3232
3333 def vfio_list (self , pci_addr : str = "all" ) -> list :
3434 """Returns list of VFs created on host."""
3535 resp = self .connection .execute_command (
3636 f"{ self .nicctl } list { pci_addr } " , shell = True
3737 )
38- return self ._parse_vf_list (resp .stdout , "all" in pci_addr )
38+ return self ._parse_vf_list (resp .stdout )
3939
4040 def create_vfs (self , pci_id : str , num_of_vfs : int = 6 ) -> list :
4141 """Create VFs on NIC.
@@ -68,3 +68,73 @@ def prepare_vfs_for_test(self, nic: NetworkInterface) -> list:
6868 self .create_vfs (nic_pci )
6969 self .host .vfs = self .vfio_list (nic_pci )
7070 return self .host .vfs
71+
72+ def bind_pmd (self , pci_id : str ) -> None :
73+ """Bind VF to DPDK PMD driver."""
74+ self .connection .execute_command (
75+ self .nicctl + " bind_pmd " + pci_id , shell = True
76+ )
77+
78+ def bind_kernel (self , pci_id : str ) -> None :
79+ """Bind VF to kernel driver."""
80+ self .connection .execute_command (
81+ self .nicctl + " bind_kernel " + pci_id , shell = True
82+ )
83+
84+
85+ class InterfaceSetup :
86+ def __init__ (self , hosts , mtl_path ):
87+ self .hosts = hosts
88+ self .mtl_path = mtl_path
89+ self .nicctl_objs = {host .name : Nicctl (mtl_path , host ) for host in hosts .values ()}
90+ self .customs = []
91+ self .cleanups = []
92+
93+ def get_test_interfaces (self , hosts , interface_type = "VF" , count = 2 ):
94+ selected_interfaces = {k : [] for k in hosts .keys ()}
95+ for host in hosts .values ():
96+ if getattr (host .topology .extra_info , "custom_interface" , None ):
97+ selected_interfaces [host .name ] = [
98+ host .topology .extra_info ["custom_interface" ]]
99+ self .customs .append (host .name )
100+ if len (selected_interfaces [host .name ]) < count :
101+ raise Exception (f"Not enough interfaces for test on host { host .name } in extra_info.custom_interface" )
102+ else :
103+ if interface_type == "VF" :
104+ vfs = self .nicctl_objs [host .name ].create_vfs (host .network_interfaces [0 ].pci_address .lspci , count )
105+ selected_interfaces [host .name ] = vfs
106+ self .register_cleanup (self .nicctl_objs [host .name ], host .network_interfaces [0 ].pci_address .lspci , interface_type )
107+ elif interface_type == "PF" :
108+ try :
109+ selected_interfaces [host .name ] = []
110+ for i in range (count ):
111+ self .nicctl_objs [host .name ].bind_pmd (host .network_interfaces [i ].pci_address .lspci )
112+ selected_interfaces [host .name ].append (str (host .network_interfaces [i ]))
113+ self .register_cleanup (self .nicctl_objs [host .name ], host .network_interfaces [i ].pci_address .lspci , interface_type )
114+ except IndexError :
115+ raise Exception (f"Not enough interfaces for test on host { host .name } in topology config." )
116+ elif interface_type == "VFxPF" :
117+ for i in range (count ):
118+ vfs = self .nicctl_objs [host .name ].create_vfs (host .network_interfaces [i ].pci_address .lspci , 1 )
119+ selected_interfaces [host .name ].extend (vfs )
120+ self .register_cleanup (self .nicctl_objs [host .name ], host .network_interfaces [i ].pci_address .lspci , "VF" )
121+ else :
122+ raise Exception (f"Unknown interface type { interface_type } " )
123+ return selected_interfaces
124+
125+ def get_test_interfaces_list (self , hosts , interface_type = "VF" , count = 2 ):
126+ selected_interfaces = self .get_test_interfaces (hosts , interface_type , count )
127+ interface_list = []
128+ for host in hosts .values ():
129+ interface_list .extend (selected_interfaces [host .name ])
130+ return interface_list
131+
132+ def register_cleanup (self , nicctl , interface , if_type ):
133+ self .cleanups .append ((nicctl , interface , if_type ))
134+
135+ def cleanup (self ):
136+ for nicctl , interface , if_type in self .cleanups :
137+ if if_type == "VF" :
138+ nicctl .disable_vf (interface )
139+ elif if_type == "PF" :
140+ nicctl .bind_kernel (interface )
0 commit comments