Commit 6ce2b689 authored by Jakub Kicinski's avatar Jakub Kicinski

selftests: net: reuse common code in bpf_offload

net/lib/py/nsim.py already contains the most useful parts
of the netdevsim wrapper classes. Reuse them.
Acked-by: default avatarStanislav Fomichev <sdf@google.com>
Acked-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
Link: https://lore.kernel.org/r/20240409031549.3531084-5-kuba@kernel.orgSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent b1c2ce11
......@@ -29,6 +29,9 @@ import subprocess
import time
import traceback
from lib.py import NetdevSim, NetdevSimDev
logfile = None
log_level = 1
skip_extack = False
......@@ -145,8 +148,10 @@ def tool(name, args, flags, JSON=True, ns="", fail=True, include_stderr=False):
if JSON:
params += "%s " % (flags["json"])
if ns != "":
if ns:
ns = "ip netns exec %s " % (ns)
elif ns is None:
ns = ""
if include_stderr:
ret, stdout, stderr = cmd(ns + name + " " + params + args,
......@@ -334,72 +339,16 @@ class DebugfsDir:
return dfs
class NetdevSimDev:
class BpfNetdevSimDev(NetdevSimDev):
"""
Class for netdevsim bus device and its attributes.
"""
@staticmethod
def ctrl_write(path, val):
fullpath = os.path.join("/sys/bus/netdevsim/", path)
try:
with open(fullpath, "w") as f:
f.write(val)
except OSError as e:
log("WRITE %s: %r" % (fullpath, val), -e.errno)
raise e
log("WRITE %s: %r" % (fullpath, val), 0)
def __init__(self, port_count=1):
addr = 0
while True:
try:
self.ctrl_write("new_device", "%u %u" % (addr, port_count))
except OSError as e:
if e.errno == errno.ENOSPC:
addr += 1
continue
raise e
break
self.addr = addr
# As probe of netdevsim device might happen from a workqueue,
# so wait here until all netdevs appear.
self.wait_for_netdevs(port_count)
ret, out = cmd("udevadm settle", fail=False)
if ret:
raise Exception("udevadm settle failed")
ifnames = self.get_ifnames()
def __init__(self, port_count=1, ns=None):
super().__init__(port_count, ns=ns)
devs.append(self)
self.dfs_dir = "/sys/kernel/debug/netdevsim/netdevsim%u/" % addr
self.nsims = []
for port_index in range(port_count):
self.nsims.append(NetdevSim(self, port_index, ifnames[port_index]))
def get_ifnames(self):
ifnames = []
listdir = os.listdir("/sys/bus/netdevsim/devices/netdevsim%u/net/" % self.addr)
for ifname in listdir:
ifnames.append(ifname)
ifnames.sort()
return ifnames
def wait_for_netdevs(self, port_count):
timeout = 5
timeout_start = time.time()
while True:
try:
ifnames = self.get_ifnames()
except FileNotFoundError as e:
ifnames = []
if len(ifnames) == port_count:
break
if time.time() < timeout_start + timeout:
continue
raise Exception("netdevices did not appear within timeout")
def _make_port(self, port_index, ifname):
return BpfNetdevSim(self, port_index, ifname, self.ns)
def dfs_num_bound_progs(self):
path = os.path.join(self.dfs_dir, "bpf_bound_progs")
......@@ -415,33 +364,20 @@ class NetdevSimDev:
return progs
def remove(self):
self.ctrl_write("del_device", "%u" % (self.addr, ))
super().remove()
devs.remove(self)
def remove_nsim(self, nsim):
self.nsims.remove(nsim)
self.ctrl_write("devices/netdevsim%u/del_port" % (self.addr, ),
"%u" % (nsim.port_index, ))
class NetdevSim:
class BpfNetdevSim(NetdevSim):
"""
Class for netdevsim netdevice and its attributes.
"""
def __init__(self, nsimdev, port_index, ifname):
# In case udev renamed the netdev to according to new schema,
# check if the name matches the port_index.
nsimnamere = re.compile("eni\d+np(\d+)")
match = nsimnamere.match(ifname)
if match and int(match.groups()[0]) != port_index + 1:
raise Exception("netdevice name mismatches the expected one")
self.nsimdev = nsimdev
self.port_index = port_index
self.ns = ""
def __init__(self, nsimdev, port_index, ifname, ns=None):
super().__init__(nsimdev, port_index, ifname, ns=ns)
self.dfs_dir = "%s/ports/%u/" % (nsimdev.dfs_dir, port_index)
self.dfs_refresh()
_, [self.dev] = ip("link show dev %s" % ifname)
def __getitem__(self, key):
return self.dev[key]
......@@ -468,7 +404,7 @@ class NetdevSim:
raise Exception("Time out waiting for program counts to stabilize want %d/%d, have %d bound, %d loaded" % (bound, total, nbound, nprogs))
def set_ns(self, ns):
name = "1" if ns == "" else ns
name = ns if ns else "1"
ip("link set dev %s netns %s" % (self.dev["ifname"], name), ns=self.ns)
self.ns = ns
......@@ -744,7 +680,7 @@ def test_multi_prog(simdev, sim, obj, modename, modeid):
start_test("Test multi-attachment XDP - device remove...")
simdev.remove()
simdev = NetdevSimDev()
simdev = BpfNetdevSimDev()
sim, = simdev.nsims
sim.set_ethtool_tc_offloads(True)
return [simdev, sim]
......@@ -809,13 +745,13 @@ try:
bytecode = bpf_bytecode("1,6 0 0 4294967295,")
start_test("Test destruction of generic XDP...")
simdev = NetdevSimDev()
simdev = BpfNetdevSimDev()
sim, = simdev.nsims
sim.set_xdp(obj, "generic")
simdev.remove()
bpftool_prog_list_wait(expected=0)
simdev = NetdevSimDev()
simdev = BpfNetdevSimDev()
sim, = simdev.nsims
sim.tc_add_ingress()
......@@ -967,7 +903,7 @@ try:
simdev.remove()
bpftool_prog_list_wait(expected=0)
simdev = NetdevSimDev()
simdev = BpfNetdevSimDev()
sim, = simdev.nsims
sim.set_ethtool_tc_offloads(True)
......@@ -976,7 +912,7 @@ try:
simdev.remove()
bpftool_prog_list_wait(expected=0)
simdev = NetdevSimDev()
simdev = BpfNetdevSimDev()
sim, = simdev.nsims
sim.set_ethtool_tc_offloads(True)
......@@ -1080,7 +1016,7 @@ try:
bpftool_prog_list_wait(expected=0)
start_test("Test attempt to use a program for a wrong device...")
simdev2 = NetdevSimDev()
simdev2 = BpfNetdevSimDev()
sim2, = simdev2.nsims
sim2.set_xdp(obj, "offload")
pin_file, pinned = pin_prog("/sys/fs/bpf/tmp")
......@@ -1169,7 +1105,7 @@ try:
clean_up()
bpftool_prog_list_wait(expected=0)
simdev = NetdevSimDev()
simdev = BpfNetdevSimDev()
sim, = simdev.nsims
map_obj = bpf_obj("sample_map_ret0.bpf.o")
start_test("Test loading program with maps...")
......@@ -1201,7 +1137,7 @@ try:
clean_up()
bpftool_prog_list_wait(expected=0)
simdev = NetdevSimDev()
simdev = BpfNetdevSimDev()
sim, = simdev.nsims
start_test("Test map update (no flags)...")
......@@ -1285,14 +1221,14 @@ try:
bpftool_map_list_wait(expected=0)
simdev.remove()
simdev = NetdevSimDev()
simdev = BpfNetdevSimDev()
sim, = simdev.nsims
sim.set_xdp(map_obj, "offload", JSON=False) # map fixup msg breaks JSON
simdev.remove()
bpftool_map_list_wait(expected=0)
start_test("Test map creation fail path...")
simdev = NetdevSimDev()
simdev = BpfNetdevSimDev()
sim, = simdev.nsims
sim.dfs["bpf_map_accept"] = "N"
ret, _ = sim.set_xdp(map_obj, "offload", JSON=False, fail=False)
......@@ -1302,9 +1238,9 @@ try:
simdev.remove()
start_test("Test multi-dev ASIC program reuse...")
simdevA = NetdevSimDev()
simdevA = BpfNetdevSimDev()
simA, = simdevA.nsims
simdevB = NetdevSimDev(3)
simdevB = BpfNetdevSimDev(3)
simB1, simB2, simB3 = simdevB.nsims
sims = (simA, simB1, simB2, simB3)
simB = (simB1, simB2, simB3)
......
......@@ -21,8 +21,11 @@ class NetdevSim:
if match and int(match.groups()[0]) != port_index + 1:
raise Exception("netdevice name mismatches the expected one")
self.ifname = ifname
self.nsimdev = nsimdev
self.port_index = port_index
self.ns = ns
self.dfs_dir = "%s/ports/%u/" % (nsimdev.dfs_dir, port_index)
ret = ip("-j link show dev %s" % ifname, ns=ns)
self.dev = json.loads(ret.stdout)[0]
......@@ -79,8 +82,10 @@ class NetdevSimDev:
self.nsims = []
for port_index in range(port_count):
self.nsims.append(NetdevSim(self, port_index, ifnames[port_index],
ns=ns))
self.nsims.append(self._make_port(port_index, ifnames[port_index]))
def _make_port(self, port_index, ifname):
return NetdevSim(self, port_index, ifname, self.ns)
def get_ifnames(self):
ifnames = []
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment