Skip to content

Commit bec809d

Browse files
committed
Add case to support jumbo frame test
Automate VIRT-95907 Jumbo Frame Signed-off-by: Lei Yang <leiyang@redhat.com>
1 parent 875c970 commit bec809d

File tree

2 files changed

+229
-0
lines changed

2 files changed

+229
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
- virtual_network.qemu_test.jumbo: image_copy
2+
requires_root = yes
3+
create_vm_libvirt = yes
4+
master_images_clone = img1
5+
kill_vm_libvirt = yes
6+
type = jumbo
7+
start_vm = no
8+
mtu = 9000
9+
e1000e:
10+
only Linux
11+
virtio_net:
12+
Windows:
13+
mtu_key = MTU
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
import random
2+
import re
3+
4+
from avocado.utils import process
5+
from virttest import (
6+
env_process,
7+
error_context,
8+
utils_misc,
9+
utils_net,
10+
utils_sriov,
11+
utils_test,
12+
)
13+
from virttest.utils_test import libvirt
14+
15+
16+
@error_context.context_aware
17+
def run(test, params, env):
18+
"""
19+
Test the RX jumbo frame function of vnics:
20+
21+
1) Boot the VM.
22+
2) Change the MTU of guest nics and host taps depending on the NIC model.
23+
3) Add the static ARP entry for guest NIC.
24+
4) Wait for the MTU ok.
25+
5) Verify the path MTU using ping.
26+
6) Ping the guest with large frames.
27+
7) Increment size ping.
28+
8) Flood ping the guest with large frames.
29+
9) Verify the path MTU.
30+
10) Recover the MTU.
31+
32+
:param test: LIBVIRT test object.
33+
:param params: Dictionary with the test parameters.
34+
:param env: Dictionary with test environment.
35+
"""
36+
37+
def get_ovs_ports(ovs):
38+
"""
39+
get the ovs bridge all Interface list.
40+
41+
:param ovs: Ovs bridge name
42+
"""
43+
cmd = "ovs-vsctl list-ports %s" % ovs
44+
return process.getoutput(cmd, shell=True)
45+
46+
netdst = params.get("netdst", "switch")
47+
host_bridges = utils_net.find_bridge_manager(netdst)
48+
if not isinstance(host_bridges, utils_net.Bridge):
49+
host_hw_interface = get_ovs_ports(netdst)
50+
tmp_ports = re.findall(r"t[0-9]{1,}-[a-zA-Z0-9]{6}", host_hw_interface)
51+
if tmp_ports:
52+
for p in tmp_ports:
53+
process.system_output("ovs-vsctl del-port %s %s" % (netdst, p))
54+
55+
params["start_vm"] = "yes"
56+
env_process.preprocess_vm(test, params, env, params["main_vm"])
57+
58+
timeout = params.get_numeric("login_timeout", 360)
59+
mtu_default = 1500
60+
mtu = params.get_numeric("mtu", "1500")
61+
def_max_icmp_size = int(mtu) - 28
62+
max_icmp_pkt_size = params.get_numeric("max_icmp_pkt_size", def_max_icmp_size)
63+
flood_time = params.get_numeric("flood_time", "300")
64+
os_type = params.get("os_type")
65+
hint = params.get("hint", "do")
66+
67+
vm = env.get_vm(params["main_vm"])
68+
vm.verify_alive()
69+
session = vm.wait_for_login(timeout=timeout)
70+
session_serial = vm.wait_for_serial_login(timeout=timeout)
71+
72+
iface_mac = vm.get_mac_address(0)
73+
vm_name = params.get("main_vm")
74+
ifname = libvirt.get_ifname_host(vm_name, iface_mac)
75+
guest_ip = vm.get_address(0)
76+
if guest_ip is None:
77+
test.error("Could not get the guest ip address")
78+
79+
host_mtu_cmd = "ip link set dev %s mtu %s"
80+
if not isinstance(host_bridges, utils_net.Bridge):
81+
target_ifaces = set(get_ovs_ports(netdst).splitlines())
82+
else:
83+
br_in_use = host_bridges.list_br()
84+
ifaces_in_use = host_bridges.list_iface()
85+
target_ifaces = set(ifaces_in_use) - set(br_in_use)
86+
87+
error_context.context("Change all Bridge NICs MTU to %s" % mtu, test.log.info)
88+
for iface in target_ifaces:
89+
process.run(host_mtu_cmd % (iface, mtu), shell=True)
90+
91+
try:
92+
error_context.context("Changing the MTU of guest", test.log.info)
93+
# Environment preparation
94+
if os_type == "linux":
95+
ethname = utils_net.get_linux_ifname(session, iface_mac)
96+
guest_mtu_cmd = "ip link set dev %s mtu %s" % (ethname, mtu)
97+
else:
98+
connection_id = utils_net.get_windows_nic_attribute(
99+
session, "macaddress", iface_mac, "netconnectionid"
100+
)
101+
102+
index = utils_net.get_windows_nic_attribute(
103+
session, "netconnectionid", connection_id, "index"
104+
)
105+
106+
reg_set_mtu_pattern = params.get("reg_mtu_cmd")
107+
mtu_key_word = params.get("mtu_key", "MTU")
108+
reg_set_mtu = reg_set_mtu_pattern % (int(index), mtu_key_word, int(mtu))
109+
guest_mtu_cmd = "%s " % reg_set_mtu
110+
111+
session.cmd(guest_mtu_cmd)
112+
if os_type == "windows":
113+
mode = "netsh"
114+
utils_net.restart_windows_guest_network(
115+
session_serial, connection_id, mode=mode
116+
)
117+
118+
error_context.context("Chaning the MTU of host tap ...", test.log.info)
119+
process.run(host_mtu_cmd % (ifname, mtu), shell=True)
120+
121+
error_context.context("Add a temporary static ARP entry ...", test.log.info)
122+
arp_add_cmd = "arp -s %s %s -i %s" % (guest_ip, iface_mac, ifname)
123+
process.run(arp_add_cmd, shell=True)
124+
125+
def is_mtu_ok():
126+
status, _ = utils_test.ping(
127+
guest_ip, 1, packetsize=max_icmp_pkt_size, hint="do", timeout=2
128+
)
129+
return status == 0
130+
131+
def verify_mtu():
132+
test.log.info("Verify the path MTU")
133+
status, output = utils_test.ping(
134+
guest_ip, 10, packetsize=max_icmp_pkt_size, hint="do", timeout=15
135+
)
136+
if status != 0:
137+
test.log.error(output)
138+
test.fail("Path MTU is not as expected")
139+
if utils_test.get_loss_ratio(output) != 0:
140+
test.log.error(output)
141+
test.fail("Packet loss ratio during MTU verification is not zero")
142+
143+
def flood_ping():
144+
test.log.info("Flood with large frames")
145+
utils_test.ping(
146+
guest_ip,
147+
packetsize=max_icmp_pkt_size,
148+
flood=True,
149+
timeout=float(flood_time),
150+
)
151+
152+
def large_frame_ping(count=100):
153+
test.log.info("Large frame ping")
154+
_, output = utils_test.ping(
155+
guest_ip, count, packetsize=max_icmp_pkt_size, timeout=float(count) * 2
156+
)
157+
ratio = utils_test.get_loss_ratio(output)
158+
if ratio != 0:
159+
test.fail("Loss ratio of large frame ping is %s" % ratio)
160+
161+
def size_increase_ping(step=random.randrange(90, 110)):
162+
test.log.info("Size increase ping")
163+
for size in range(0, max_icmp_pkt_size + 1, step):
164+
test.log.info("Ping %s with size %s", guest_ip, size)
165+
status, output = utils_test.ping(
166+
guest_ip, 1, packetsize=size, hint=hint, timeout=1
167+
)
168+
if status != 0:
169+
status, output = utils_test.ping(
170+
guest_ip,
171+
10,
172+
packetsize=size,
173+
adaptive=True,
174+
hint=hint,
175+
timeout=20,
176+
)
177+
178+
fail_ratio = int(params.get("fail_ratio", 50))
179+
if utils_test.get_loss_ratio(output) > fail_ratio:
180+
test.fail(
181+
"Ping loss ratio is greater than 50% for size %s" % size
182+
)
183+
184+
test.log.info("Waiting for the MTU to be OK")
185+
wait_mtu_ok = 20
186+
if not utils_misc.wait_for(is_mtu_ok, wait_mtu_ok, 0, 1):
187+
test.log.debug(
188+
process.getoutput(
189+
"ifconfig -a", verbose=False, ignore_status=True, shell=True
190+
)
191+
)
192+
test.error("MTU is not as expected even after %s seconds" % wait_mtu_ok)
193+
194+
# Functional Test
195+
error_context.context("Checking whether MTU change is ok", test.log.info)
196+
197+
verify_mtu()
198+
large_frame_ping()
199+
size_increase_ping()
200+
201+
# Stress test
202+
flood_ping()
203+
verify_mtu()
204+
205+
finally:
206+
# Environment clean
207+
if session:
208+
session.close()
209+
grep_cmd = "grep '%s.*%s' /proc/net/arp" % (guest_ip, ifname)
210+
if process.system(grep_cmd, shell=True) == "0":
211+
process.run("arp -d %s -i %s" % (guest_ip, ifname), shell=True)
212+
test.log.info("Removing the temporary ARP entry successfully")
213+
214+
test.log.info("Change back Bridge NICs MTU to %s", mtu_default)
215+
for iface in target_ifaces:
216+
process.run(host_mtu_cmd % (iface, mtu_default), shell=True)

0 commit comments

Comments
 (0)