aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests/bpf
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-07-21 02:58:30 -0400
committerDavid S. Miller <davem@davemloft.net>2018-07-21 02:58:30 -0400
commiteae249b27f0447a92b3f8c72cc45fcc4609ae00d (patch)
tree76a0df9c4ada3520bd654968afdfc8ea2b3e653a /tools/testing/selftests/bpf
parentc59e18b876da3e466abe5fa066aa69050f5be17c (diff)
parent8ae71e76cf1f7b8de5c75356a00840e54c93e7a5 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
Daniel Borkmann says: ==================== pull-request: bpf-next 2018-07-20 The following pull-request contains BPF updates for your *net-next* tree. The main changes are: 1) Add sharing of BPF objects within one ASIC: this allows for reuse of the same program on multiple ports of a device, and therefore gains better code store utilization. On top of that, this now also enables sharing of maps between programs attached to different ports of a device, from Jakub. 2) Cleanup in libbpf and bpftool's Makefile to reduce unneeded feature detections and unused variable exports, also from Jakub. 3) First batch of RCU annotation fixes in prog array handling, i.e. there are several __rcu markers which are not correct as well as some of the RCU handling, from Roman. 4) Two fixes in BPF sample files related to checking of the prog_cnt upper limit from sample loader, from Dan. 5) Minor cleanup in sockmap to remove a set but not used variable, from Colin. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'tools/testing/selftests/bpf')
-rwxr-xr-xtools/testing/selftests/bpf/test_offload.py151
1 files changed, 145 insertions, 6 deletions
diff --git a/tools/testing/selftests/bpf/test_offload.py b/tools/testing/selftests/bpf/test_offload.py
index b746227eaff2..d59642e70f56 100755
--- a/tools/testing/selftests/bpf/test_offload.py
+++ b/tools/testing/selftests/bpf/test_offload.py
@@ -158,8 +158,9 @@ def tool(name, args, flags, JSON=True, ns="", fail=True, include_stderr=False):
158 else: 158 else:
159 return ret, out 159 return ret, out
160 160
161def bpftool(args, JSON=True, ns="", fail=True): 161def bpftool(args, JSON=True, ns="", fail=True, include_stderr=False):
162 return tool("bpftool", args, {"json":"-p"}, JSON=JSON, ns=ns, fail=fail) 162 return tool("bpftool", args, {"json":"-p"}, JSON=JSON, ns=ns,
163 fail=fail, include_stderr=include_stderr)
163 164
164def bpftool_prog_list(expected=None, ns=""): 165def bpftool_prog_list(expected=None, ns=""):
165 _, progs = bpftool("prog show", JSON=True, ns=ns, fail=True) 166 _, progs = bpftool("prog show", JSON=True, ns=ns, fail=True)
@@ -201,6 +202,21 @@ def bpftool_map_list_wait(expected=0, n_retry=20):
201 time.sleep(0.05) 202 time.sleep(0.05)
202 raise Exception("Time out waiting for map counts to stabilize want %d, have %d" % (expected, nmaps)) 203 raise Exception("Time out waiting for map counts to stabilize want %d, have %d" % (expected, nmaps))
203 204
205def bpftool_prog_load(sample, file_name, maps=[], prog_type="xdp", dev=None,
206 fail=True, include_stderr=False):
207 args = "prog load %s %s" % (os.path.join(bpf_test_dir, sample), file_name)
208 if prog_type is not None:
209 args += " type " + prog_type
210 if dev is not None:
211 args += " dev " + dev
212 if len(maps):
213 args += " map " + " map ".join(maps)
214
215 res = bpftool(args, fail=fail, include_stderr=include_stderr)
216 if res[0] == 0:
217 files.append(file_name)
218 return res
219
204def ip(args, force=False, JSON=True, ns="", fail=True, include_stderr=False): 220def ip(args, force=False, JSON=True, ns="", fail=True, include_stderr=False):
205 if force: 221 if force:
206 args = "-force " + args 222 args = "-force " + args
@@ -307,21 +323,25 @@ class NetdevSim:
307 Class for netdevsim netdevice and its attributes. 323 Class for netdevsim netdevice and its attributes.
308 """ 324 """
309 325
310 def __init__(self): 326 def __init__(self, link=None):
327 self.link = link
328
311 self.dev = self._netdevsim_create() 329 self.dev = self._netdevsim_create()
312 devs.append(self) 330 devs.append(self)
313 331
314 self.ns = "" 332 self.ns = ""
315 333
316 self.dfs_dir = '/sys/kernel/debug/netdevsim/%s' % (self.dev['ifname']) 334 self.dfs_dir = '/sys/kernel/debug/netdevsim/%s' % (self.dev['ifname'])
335 self.sdev_dir = self.dfs_dir + '/sdev/'
317 self.dfs_refresh() 336 self.dfs_refresh()
318 337
319 def __getitem__(self, key): 338 def __getitem__(self, key):
320 return self.dev[key] 339 return self.dev[key]
321 340
322 def _netdevsim_create(self): 341 def _netdevsim_create(self):
342 link = "" if self.link is None else "link " + self.link.dev['ifname']
323 _, old = ip("link show") 343 _, old = ip("link show")
324 ip("link add sim%d type netdevsim") 344 ip("link add sim%d {link} type netdevsim".format(link=link))
325 _, new = ip("link show") 345 _, new = ip("link show")
326 346
327 for dev in new: 347 for dev in new:
@@ -345,12 +365,12 @@ class NetdevSim:
345 return data.strip() 365 return data.strip()
346 366
347 def dfs_num_bound_progs(self): 367 def dfs_num_bound_progs(self):
348 path = os.path.join(self.dfs_dir, "bpf_bound_progs") 368 path = os.path.join(self.sdev_dir, "bpf_bound_progs")
349 _, progs = cmd('ls %s' % (path)) 369 _, progs = cmd('ls %s' % (path))
350 return len(progs.split()) 370 return len(progs.split())
351 371
352 def dfs_get_bound_progs(self, expected): 372 def dfs_get_bound_progs(self, expected):
353 progs = DebugfsDir(os.path.join(self.dfs_dir, "bpf_bound_progs")) 373 progs = DebugfsDir(os.path.join(self.sdev_dir, "bpf_bound_progs"))
354 if expected is not None: 374 if expected is not None:
355 if len(progs) != expected: 375 if len(progs) != expected:
356 fail(True, "%d BPF programs bound, expected %d" % 376 fail(True, "%d BPF programs bound, expected %d" %
@@ -847,6 +867,25 @@ try:
847 sim.set_mtu(1500) 867 sim.set_mtu(1500)
848 868
849 sim.wait_for_flush() 869 sim.wait_for_flush()
870 start_test("Test non-offload XDP attaching to HW...")
871 bpftool_prog_load("sample_ret0.o", "/sys/fs/bpf/nooffload")
872 nooffload = bpf_pinned("/sys/fs/bpf/nooffload")
873 ret, _, err = sim.set_xdp(nooffload, "offload",
874 fail=False, include_stderr=True)
875 fail(ret == 0, "attached non-offloaded XDP program to HW")
876 check_extack_nsim(err, "xdpoffload of non-bound program.", args)
877 rm("/sys/fs/bpf/nooffload")
878
879 start_test("Test offload XDP attaching to drv...")
880 bpftool_prog_load("sample_ret0.o", "/sys/fs/bpf/offload",
881 dev=sim['ifname'])
882 offload = bpf_pinned("/sys/fs/bpf/offload")
883 ret, _, err = sim.set_xdp(offload, "drv", fail=False, include_stderr=True)
884 fail(ret == 0, "attached offloaded XDP program to drv")
885 check_extack(err, "using device-bound program without HW_MODE flag is not supported.", args)
886 rm("/sys/fs/bpf/offload")
887 sim.wait_for_flush()
888
850 start_test("Test XDP offload...") 889 start_test("Test XDP offload...")
851 _, _, err = sim.set_xdp(obj, "offload", verbose=True, include_stderr=True) 890 _, _, err = sim.set_xdp(obj, "offload", verbose=True, include_stderr=True)
852 ipl = sim.ip_link_show(xdp=True) 891 ipl = sim.ip_link_show(xdp=True)
@@ -1140,6 +1179,106 @@ try:
1140 fail(ret == 0, 1179 fail(ret == 0,
1141 "netdevsim didn't refuse to create a map with offload disabled") 1180 "netdevsim didn't refuse to create a map with offload disabled")
1142 1181
1182 sim.remove()
1183
1184 start_test("Test multi-dev ASIC program reuse...")
1185 simA = NetdevSim()
1186 simB1 = NetdevSim()
1187 simB2 = NetdevSim(link=simB1)
1188 simB3 = NetdevSim(link=simB1)
1189 sims = (simA, simB1, simB2, simB3)
1190 simB = (simB1, simB2, simB3)
1191
1192 bpftool_prog_load("sample_map_ret0.o", "/sys/fs/bpf/nsimA",
1193 dev=simA['ifname'])
1194 progA = bpf_pinned("/sys/fs/bpf/nsimA")
1195 bpftool_prog_load("sample_map_ret0.o", "/sys/fs/bpf/nsimB",
1196 dev=simB1['ifname'])
1197 progB = bpf_pinned("/sys/fs/bpf/nsimB")
1198
1199 simA.set_xdp(progA, "offload", JSON=False)
1200 for d in simB:
1201 d.set_xdp(progB, "offload", JSON=False)
1202
1203 start_test("Test multi-dev ASIC cross-dev replace...")
1204 ret, _ = simA.set_xdp(progB, "offload", force=True, JSON=False, fail=False)
1205 fail(ret == 0, "cross-ASIC program allowed")
1206 for d in simB:
1207 ret, _ = d.set_xdp(progA, "offload", force=True, JSON=False, fail=False)
1208 fail(ret == 0, "cross-ASIC program allowed")
1209
1210 start_test("Test multi-dev ASIC cross-dev install...")
1211 for d in sims:
1212 d.unset_xdp("offload")
1213
1214 ret, _, err = simA.set_xdp(progB, "offload", force=True, JSON=False,
1215 fail=False, include_stderr=True)
1216 fail(ret == 0, "cross-ASIC program allowed")
1217 check_extack_nsim(err, "program bound to different dev.", args)
1218 for d in simB:
1219 ret, _, err = d.set_xdp(progA, "offload", force=True, JSON=False,
1220 fail=False, include_stderr=True)
1221 fail(ret == 0, "cross-ASIC program allowed")
1222 check_extack_nsim(err, "program bound to different dev.", args)
1223
1224 start_test("Test multi-dev ASIC cross-dev map reuse...")
1225
1226 mapA = bpftool("prog show %s" % (progA))[1]["map_ids"][0]
1227 mapB = bpftool("prog show %s" % (progB))[1]["map_ids"][0]
1228
1229 ret, _ = bpftool_prog_load("sample_map_ret0.o", "/sys/fs/bpf/nsimB_",
1230 dev=simB3['ifname'],
1231 maps=["idx 0 id %d" % (mapB)],
1232 fail=False)
1233 fail(ret != 0, "couldn't reuse a map on the same ASIC")
1234 rm("/sys/fs/bpf/nsimB_")
1235
1236 ret, _, err = bpftool_prog_load("sample_map_ret0.o", "/sys/fs/bpf/nsimA_",
1237 dev=simA['ifname'],
1238 maps=["idx 0 id %d" % (mapB)],
1239 fail=False, include_stderr=True)
1240 fail(ret == 0, "could reuse a map on a different ASIC")
1241 fail(err.count("offload device mismatch between prog and map") == 0,
1242 "error message missing for cross-ASIC map")
1243
1244 ret, _, err = bpftool_prog_load("sample_map_ret0.o", "/sys/fs/bpf/nsimB_",
1245 dev=simB1['ifname'],
1246 maps=["idx 0 id %d" % (mapA)],
1247 fail=False, include_stderr=True)
1248 fail(ret == 0, "could reuse a map on a different ASIC")
1249 fail(err.count("offload device mismatch between prog and map") == 0,
1250 "error message missing for cross-ASIC map")
1251
1252 start_test("Test multi-dev ASIC cross-dev destruction...")
1253 bpftool_prog_list_wait(expected=2)
1254
1255 simA.remove()
1256 bpftool_prog_list_wait(expected=1)
1257
1258 ifnameB = bpftool("prog show %s" % (progB))[1]["dev"]["ifname"]
1259 fail(ifnameB != simB1['ifname'], "program not bound to originial device")
1260 simB1.remove()
1261 bpftool_prog_list_wait(expected=1)
1262
1263 start_test("Test multi-dev ASIC cross-dev destruction - move...")
1264 ifnameB = bpftool("prog show %s" % (progB))[1]["dev"]["ifname"]
1265 fail(ifnameB not in (simB2['ifname'], simB3['ifname']),
1266 "program not bound to remaining devices")
1267
1268 simB2.remove()
1269 ifnameB = bpftool("prog show %s" % (progB))[1]["dev"]["ifname"]
1270 fail(ifnameB != simB3['ifname'], "program not bound to remaining device")
1271
1272 simB3.remove()
1273 bpftool_prog_list_wait(expected=0)
1274
1275 start_test("Test multi-dev ASIC cross-dev destruction - orphaned...")
1276 ret, out = bpftool("prog show %s" % (progB), fail=False)
1277 fail(ret == 0, "got information about orphaned program")
1278 fail("error" not in out, "no error reported for get info on orphaned")
1279 fail(out["error"] != "can't get prog info: No such device",
1280 "wrong error for get info on orphaned")
1281
1143 print("%s: OK" % (os.path.basename(__file__))) 1282 print("%s: OK" % (os.path.basename(__file__)))
1144 1283
1145finally: 1284finally: