Skip to content

Commit 0662faa

Browse files
committed
Add vdpa_utils.py
This patch introduces an OVSHandler class and supporting functions: - check ovs status and retrieve bridge/port information - handle vdpa device integration with ovs - add flow rules to ovs bridge - provide flexible bridge and port info for vm - add vdpa_dpdk case usage: add flows rules to ovs - add netperf case usage: add flows rules to ovs and get vdpa ovs port info Signed-off-by: Wenli Quan <[email protected]>
1 parent 5705527 commit 0662faa

File tree

5 files changed

+146
-48
lines changed

5 files changed

+146
-48
lines changed

generic/tests/cfg/netperf.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#numa configration
3535
numa_node = -1
3636
netperf_with_numa = yes
37+
add_flows = yes
3738
# configure netperf test parameters, some seconds will be took to
3839
# wait all the clients work, this wait time should be less than
3940
# 0.5 * l, the wait time will augments if you have move

generic/tests/netperf.py

Lines changed: 8 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from avocado.utils import process
88
from virttest import error_context, remote, utils_misc, utils_net, utils_test, virt_vm
99

10-
from provider import netperf_base, win_driver_utils
10+
from provider import netperf_base, vdpa_utils, win_driver_utils
1111

1212
LOG_JOB = logging.getLogger("avocado.test")
1313

@@ -76,52 +76,13 @@ def mtu_set(mtu):
7676
if netdst in br_in_use:
7777
ifaces_in_use = host_bridges.list_iface()
7878
target_ifaces = list(ifaces_in_use + br_in_use)
79-
if (
80-
process.system(
81-
"which ovs-vsctl && systemctl status openvswitch.service",
82-
ignore_status=True,
83-
shell=True,
84-
)
85-
== 0
86-
):
87-
ovs_br_all = netperf_base.ssh_cmd(host, "ovs-vsctl list-br")
88-
ovs_br = []
89-
if ovs_br_all:
90-
for nic in vm.virtnet:
91-
if nic.netdst in ovs_br_all:
92-
ovs_br.append(nic.netdst)
93-
elif nic.nettype == "vdpa":
94-
vf_pci = netperf_base.ssh_cmd(
95-
host,
96-
"vdpa dev show |grep %s | grep -o 'pci/[^[:space:]]*' | "
97-
"awk -F/ '{print $2}'" % nic.netdst,
98-
)
99-
pf_pci = netperf_base.ssh_cmd(
100-
host,
101-
"grep PCI_SLOT_NAME /sys/bus/pci/devices/%s/physfn/uevent |"
102-
" cut -d'=' -f2" % vf_pci,
103-
)
104-
port = netperf_base.ssh_cmd(
105-
host, "ls /sys/bus/pci/devices/%s/net/ | head -n 1" % pf_pci
106-
)
107-
ovs_br_vdpa = netperf_base.ssh_cmd(
108-
host, "ovs-vsctl port-to-br %s" % port
109-
)
110-
cmd = (
111-
f"ovs-ofctl add-flow {ovs_br_vdpa} '"
112-
"in_port=1,idle_timeout=0 actions=output:2'"
113-
)
114-
cmd += (
115-
f"&& ovs-ofctl add-flow {ovs_br_vdpa} '"
116-
"in_port=2,idle_timeout=0 actions=output:1'"
117-
)
118-
cmd += "&& ovs-ofctl dump-flows {}".format(ovs_br_vdpa)
119-
netperf_base.ssh_cmd(host, cmd)
120-
ovs_br.append(ovs_br_vdpa)
121-
for br in ovs_br:
122-
ovs_list = "ovs-vsctl list-ports %s" % br
123-
ovs_port = netperf_base.ssh_cmd(host, ovs_list)
124-
target_ifaces.extend(ovs_port.split() + [br])
79+
80+
add_flows = params.get("add_flows", "yes") == "yes"
81+
ovs_handler = vdpa_utils.OVSHandler(vm)
82+
target_ifaces.extend(
83+
ovs_handler.get_vdpa_ovs_info(add_flows=add_flows, return_ports=True)
84+
)
85+
12586
if vm.virtnet[0].nettype == "macvtap":
12687
target_ifaces.extend([vm.virtnet[0].netdst, vm.get_ifname(0)])
12788
error_context.context("Change all Bridge NICs MTU to %s" % mtu, test.log.info)

provider/vdpa_utils.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
from avocado.utils import process
2+
3+
4+
def check_ovs_status():
5+
"""
6+
Check if ovs-vsctl and openvswitch service are installed and running.
7+
Returns True if both are available and running, otherwise False.
8+
"""
9+
cmd = "which ovs-vsctl && systemctl status openvswitch.service"
10+
return process.system(cmd, ignore_status=True, shell=True) == 0
11+
12+
13+
def get_ovs_bridges():
14+
"""
15+
Get all ovs bridges.
16+
Returns a list of ovs bridge names.
17+
"""
18+
cmd = "ovs-vsctl list-br"
19+
return process.system_output(cmd, shell=True).decode().split()
20+
21+
22+
def get_vf_pci_address(nic_netdst):
23+
"""
24+
Get vf pci address from a given network destination.
25+
Returns the vf pci address as a string.
26+
"""
27+
cmd = (
28+
"vdpa dev show | grep {0} | grep -o 'pci/[^[:space:]]*' | "
29+
"awk -F/ '{{print $2}}'"
30+
).format(nic_netdst)
31+
return process.system_output(cmd, shell=True).decode().strip()
32+
33+
34+
def get_pf_pci_address(vf_pci):
35+
"""
36+
Get pf pci address using vf pci address.
37+
Returns the pf pci address as a string.
38+
"""
39+
cmd = (
40+
"grep PCI_SLOT_NAME /sys/bus/pci/devices/{0}/physfn/uevent | cut -d'=' -f2"
41+
).format(vf_pci)
42+
return process.system_output(cmd, shell=True).decode().strip()
43+
44+
45+
def get_pf_port(pf_pci):
46+
"""
47+
Get the port for the pf pci address.
48+
Returns the port name.
49+
"""
50+
cmd = "ls /sys/bus/pci/devices/{0}/net/ | head -n 1".format(pf_pci)
51+
return process.system_output(cmd, shell=True).decode().strip()
52+
53+
54+
def get_ovs_bridge_for_port(port):
55+
"""
56+
Get the ovs bridge name for the given network port.
57+
Returns the bridge name.
58+
"""
59+
cmd = "ovs-vsctl port-to-br {0}".format(port)
60+
return process.system_output(cmd, shell=True).decode().strip()
61+
62+
63+
def get_ovs_port_for_bridge(bridge):
64+
"""
65+
Get the ovs port name for the given bridge port.
66+
Returns the bridge name.
67+
"""
68+
cmd = "ovs-vsctl list-ports {0}".format(bridge)
69+
return process.system_output(cmd, shell=True).decode().strip()
70+
71+
72+
def get_vdpa_ovs_bridges(vm):
73+
"""
74+
Get OVS bridge for VDPA devices in the VM.
75+
Returns the OVS bridge name, or None if not found.
76+
"""
77+
for nic in vm.virtnet:
78+
if nic.nettype == "vdpa":
79+
vf_pci = get_vf_pci_address(nic.netdst)
80+
pf_pci = get_pf_pci_address(vf_pci)
81+
port = get_pf_port(pf_pci)
82+
return get_ovs_bridge_for_port(port)
83+
return None
84+
85+
86+
def add_flows_to_ovs_bridge(br):
87+
"""
88+
Add flow rules to the given ovs bridge.
89+
"""
90+
cmd = "ovs-ofctl add-flow {0} 'in_port=1,idle_timeout=0 actions=output:2'".format(
91+
br
92+
)
93+
cmd += (
94+
" && ovs-ofctl add-flow {0} 'in_port=2,idle_timeout=0 actions=output:1'".format(
95+
br
96+
)
97+
)
98+
cmd += " && ovs-ofctl dump-flows {0}".format(br)
99+
process.run(cmd, shell=True)
100+
101+
102+
class OVSHandler:
103+
def __init__(self, vm):
104+
self.vm = vm
105+
106+
def get_vdpa_ovs_info(self, add_flows=True, return_ports=True):
107+
"""
108+
Get OVS bridge and port information
109+
"""
110+
if check_ovs_status():
111+
ovs_br_all = get_ovs_bridges()
112+
ovs_br = []
113+
target_ifaces = []
114+
115+
vdpa_br = get_vdpa_ovs_bridges(self.vm)
116+
if vdpa_br:
117+
if add_flows:
118+
add_flows_to_ovs_bridge(vdpa_br)
119+
ovs_br.append(vdpa_br)
120+
121+
for nic in self.vm.virtnet:
122+
if nic.netdst in ovs_br_all:
123+
ovs_br.append(nic.netdst)
124+
125+
for br in ovs_br:
126+
ovs_port = get_ovs_port_for_bridge(br)
127+
if return_ports:
128+
target_ifaces.extend(ovs_port.split() + [br])
129+
130+
if return_ports:
131+
return target_ifaces

qemu/tests/cfg/vdpa_dpdk.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
enable_guest_iommu = yes
3131
guest_iommu_option = pt
3232
kernel_extra_params_ad = "default_hugepagesz=1G hugepagesz=1G hugepages=10"
33+
add_flows = yes
3334
# Packet Sending Host Configuration
3435
#dsthost = The IP address of the packet sending host
3536
#username_dsthost = Username for the host

qemu/tests/vdpa_dpdk.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from avocado.utils import process
77
from virttest import remote, utils_misc, utils_net, utils_sriov
88

9-
from provider import dpdk_utils
9+
from provider import dpdk_utils, vdpa_utils
1010

1111
LOG_JOB = logging.getLogger("avocado.test")
1212

@@ -62,6 +62,7 @@ def run(test, params, env):
6262
guest_ver_cmd = params["guest_ver_cmd"]
6363
base = params.get("format_base", "12")
6464
fbase = params.get("format_fbase", "2")
65+
add_flows = params.get("add_flows", "yes") == "yes"
6566

6667
session = vm.wait_for_login(timeout=login_timeout, restart_network=True)
6768

@@ -75,6 +76,9 @@ def run(test, params, env):
7576
result_file.write("### kvm_version : %s\n" % host_ver)
7677
result_file.write("### guest-kernel-ver :%s" % guest_ver)
7778

79+
ovs_handler = vdpa_utils.OVSHandler(vm)
80+
ovs_handler.get_vdpa_ovs_info(add_flows=add_flows, return_ports=False)
81+
7882
dpdk_utils.install_dpdk(params, session)
7983
dpdk_ver = session.cmd_output("rpm -qa |grep dpdk | head -n 1")
8084
result_file.write("### guest-dpdk-ver :%s" % dpdk_ver)

0 commit comments

Comments
 (0)