aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-01-23 20:24:32 -0500
committerDavid S. Miller <davem@davemloft.net>2018-01-23 20:25:28 -0500
commit43df215d99e6049d4680309c54232689e16ddd6b (patch)
treee7abd23f51bec81c3ae713c54009668fca214ea0 /tools
parent521504640f9ebec384a9c3ecd5e6de82fec6d928 (diff)
parent6d2d58f1b7ec379eb9467a5bc010ba49295d7714 (diff)
Merge branch 'bpf-and-netdevsim-test-updates'
Jakub Kicinski says: ==================== bpf and netdevsim test updates A number of test improvements (delayed by merges). Quentin provides patches for checking printing to the verifier log from the drivers and validating extack messages are propagated. There is also a test for replacing TC filters to avoid adding back the bug Daniel recently fixed in net and stable. ==================== Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'tools')
-rwxr-xr-xtools/testing/selftests/bpf/test_offload.py179
1 files changed, 149 insertions, 30 deletions
diff --git a/tools/testing/selftests/bpf/test_offload.py b/tools/testing/selftests/bpf/test_offload.py
index 833b9c1ec450..ae3eea3ab820 100755
--- a/tools/testing/selftests/bpf/test_offload.py
+++ b/tools/testing/selftests/bpf/test_offload.py
@@ -26,6 +26,7 @@ import time
26 26
27logfile = None 27logfile = None
28log_level = 1 28log_level = 1
29skip_extack = False
29bpf_test_dir = os.path.dirname(os.path.realpath(__file__)) 30bpf_test_dir = os.path.dirname(os.path.realpath(__file__))
30pp = pprint.PrettyPrinter() 31pp = pprint.PrettyPrinter()
31devs = [] # devices we created for clean up 32devs = [] # devices we created for clean up
@@ -132,7 +133,7 @@ def rm(f):
132 if f in files: 133 if f in files:
133 files.remove(f) 134 files.remove(f)
134 135
135def tool(name, args, flags, JSON=True, ns="", fail=True): 136def tool(name, args, flags, JSON=True, ns="", fail=True, include_stderr=False):
136 params = "" 137 params = ""
137 if JSON: 138 if JSON:
138 params += "%s " % (flags["json"]) 139 params += "%s " % (flags["json"])
@@ -140,9 +141,20 @@ def tool(name, args, flags, JSON=True, ns="", fail=True):
140 if ns != "": 141 if ns != "":
141 ns = "ip netns exec %s " % (ns) 142 ns = "ip netns exec %s " % (ns)
142 143
143 ret, out = cmd(ns + name + " " + params + args, fail=fail) 144 if include_stderr:
144 if JSON and len(out.strip()) != 0: 145 ret, stdout, stderr = cmd(ns + name + " " + params + args,
145 return ret, json.loads(out) 146 fail=fail, include_stderr=True)
147 else:
148 ret, stdout = cmd(ns + name + " " + params + args,
149 fail=fail, include_stderr=False)
150
151 if JSON and len(stdout.strip()) != 0:
152 out = json.loads(stdout)
153 else:
154 out = stdout
155
156 if include_stderr:
157 return ret, out, stderr
146 else: 158 else:
147 return ret, out 159 return ret, out
148 160
@@ -181,13 +193,15 @@ def bpftool_map_list_wait(expected=0, n_retry=20):
181 time.sleep(0.05) 193 time.sleep(0.05)
182 raise Exception("Time out waiting for map counts to stabilize want %d, have %d" % (expected, nmaps)) 194 raise Exception("Time out waiting for map counts to stabilize want %d, have %d" % (expected, nmaps))
183 195
184def ip(args, force=False, JSON=True, ns="", fail=True): 196def ip(args, force=False, JSON=True, ns="", fail=True, include_stderr=False):
185 if force: 197 if force:
186 args = "-force " + args 198 args = "-force " + args
187 return tool("ip", args, {"json":"-j"}, JSON=JSON, ns=ns, fail=fail) 199 return tool("ip", args, {"json":"-j"}, JSON=JSON, ns=ns,
200 fail=fail, include_stderr=include_stderr)
188 201
189def tc(args, JSON=True, ns="", fail=True): 202def tc(args, JSON=True, ns="", fail=True, include_stderr=False):
190 return tool("tc", args, {"json":"-p"}, JSON=JSON, ns=ns, fail=fail) 203 return tool("tc", args, {"json":"-p"}, JSON=JSON, ns=ns,
204 fail=fail, include_stderr=include_stderr)
191 205
192def ethtool(dev, opt, args, fail=True): 206def ethtool(dev, opt, args, fail=True):
193 return cmd("ethtool %s %s %s" % (opt, dev["ifname"], args), fail=fail) 207 return cmd("ethtool %s %s %s" % (opt, dev["ifname"], args), fail=fail)
@@ -348,13 +362,19 @@ class NetdevSim:
348 return ip("link set dev %s mtu %d" % (self.dev["ifname"], mtu), 362 return ip("link set dev %s mtu %d" % (self.dev["ifname"], mtu),
349 fail=fail) 363 fail=fail)
350 364
351 def set_xdp(self, bpf, mode, force=False, JSON=True, fail=True): 365 def set_xdp(self, bpf, mode, force=False, JSON=True, verbose=False,
366 fail=True, include_stderr=False):
367 if verbose:
368 bpf += " verbose"
352 return ip("link set dev %s xdp%s %s" % (self.dev["ifname"], mode, bpf), 369 return ip("link set dev %s xdp%s %s" % (self.dev["ifname"], mode, bpf),
353 force=force, JSON=JSON, fail=fail) 370 force=force, JSON=JSON,
371 fail=fail, include_stderr=include_stderr)
354 372
355 def unset_xdp(self, mode, force=False, JSON=True, fail=True): 373 def unset_xdp(self, mode, force=False, JSON=True,
374 fail=True, include_stderr=False):
356 return ip("link set dev %s xdp%s off" % (self.dev["ifname"], mode), 375 return ip("link set dev %s xdp%s off" % (self.dev["ifname"], mode),
357 force=force, JSON=JSON, fail=fail) 376 force=force, JSON=JSON,
377 fail=fail, include_stderr=include_stderr)
358 378
359 def ip_link_show(self, xdp): 379 def ip_link_show(self, xdp):
360 _, link = ip("link show dev %s" % (self['ifname'])) 380 _, link = ip("link show dev %s" % (self['ifname']))
@@ -409,17 +429,39 @@ class NetdevSim:
409 (len(filters), expected)) 429 (len(filters), expected))
410 return filters 430 return filters
411 431
412 def cls_bpf_add_filter(self, bpf, da=False, skip_sw=False, skip_hw=False, 432 def cls_filter_op(self, op, qdisc="ingress", prio=None, handle=None,
413 fail=True): 433 cls="", params="",
434 fail=True, include_stderr=False):
435 spec = ""
436 if prio is not None:
437 spec += " prio %d" % (prio)
438 if handle:
439 spec += " handle %s" % (handle)
440
441 return tc("filter {op} dev {dev} {qdisc} {spec} {cls} {params}"\
442 .format(op=op, dev=self['ifname'], qdisc=qdisc, spec=spec,
443 cls=cls, params=params),
444 fail=fail, include_stderr=include_stderr)
445
446 def cls_bpf_add_filter(self, bpf, op="add", prio=None, handle=None,
447 da=False, verbose=False,
448 skip_sw=False, skip_hw=False,
449 fail=True, include_stderr=False):
450 cls = "bpf " + bpf
451
414 params = "" 452 params = ""
415 if da: 453 if da:
416 params += " da" 454 params += " da"
455 if verbose:
456 params += " verbose"
417 if skip_sw: 457 if skip_sw:
418 params += " skip_sw" 458 params += " skip_sw"
419 if skip_hw: 459 if skip_hw:
420 params += " skip_hw" 460 params += " skip_hw"
421 return tc("filter add dev %s ingress bpf %s %s" % 461
422 (self['ifname'], bpf, params), fail=fail) 462 return self.cls_filter_op(op=op, prio=prio, handle=handle, cls=cls,
463 params=params,
464 fail=fail, include_stderr=include_stderr)
423 465
424 def set_ethtool_tc_offloads(self, enable, fail=True): 466 def set_ethtool_tc_offloads(self, enable, fail=True):
425 args = "hw-tc-offload %s" % ("on" if enable else "off") 467 args = "hw-tc-offload %s" % ("on" if enable else "off")
@@ -491,6 +533,23 @@ def check_dev_info(other_ns, ns, prog_file=None, map_file=None, removed=False):
491 fail("dev" not in m.keys(), "Device parameters not reported") 533 fail("dev" not in m.keys(), "Device parameters not reported")
492 fail(dev != m["dev"], "Map's device different than program's") 534 fail(dev != m["dev"], "Map's device different than program's")
493 535
536def check_extack(output, reference, args):
537 if skip_extack:
538 return
539 lines = output.split("\n")
540 comp = len(lines) >= 2 and lines[1] == reference
541 fail(not comp, "Missing or incorrect netlink extack message")
542
543def check_extack_nsim(output, reference, args):
544 check_extack(output, "Error: netdevsim: " + reference, args)
545
546def check_verifier_log(output, reference):
547 lines = output.split("\n")
548 for l in reversed(lines):
549 if l == reference:
550 return
551 fail(True, "Missing or incorrect message from netdevsim in verifier log")
552
494# Parse command line 553# Parse command line
495parser = argparse.ArgumentParser() 554parser = argparse.ArgumentParser()
496parser.add_argument("--log", help="output verbose log to given file") 555parser.add_argument("--log", help="output verbose log to given file")
@@ -527,6 +586,14 @@ for s in samples:
527 skip(ret != 0, "sample %s/%s not found, please compile it" % 586 skip(ret != 0, "sample %s/%s not found, please compile it" %
528 (bpf_test_dir, s)) 587 (bpf_test_dir, s))
529 588
589# Check if iproute2 is built with libmnl (needed by extack support)
590_, _, err = cmd("tc qdisc delete dev lo handle 0",
591 fail=False, include_stderr=True)
592if err.find("Error: Failed to find qdisc with specified handle.") == -1:
593 print("Warning: no extack message in iproute2 output, libmnl missing?")
594 log("Warning: no extack message in iproute2 output, libmnl missing?", "")
595 skip_extack = True
596
530# Check if net namespaces seem to work 597# Check if net namespaces seem to work
531ns = mknetns() 598ns = mknetns()
532skip(ns is None, "Could not create a net namespace") 599skip(ns is None, "Could not create a net namespace")
@@ -558,8 +625,10 @@ try:
558 sim.tc_flush_filters() 625 sim.tc_flush_filters()
559 626
560 start_test("Test TC offloads are off by default...") 627 start_test("Test TC offloads are off by default...")
561 ret, _ = sim.cls_bpf_add_filter(obj, skip_sw=True, fail=False) 628 ret, _, err = sim.cls_bpf_add_filter(obj, skip_sw=True,
629 fail=False, include_stderr=True)
562 fail(ret == 0, "TC filter loaded without enabling TC offloads") 630 fail(ret == 0, "TC filter loaded without enabling TC offloads")
631 check_extack(err, "Error: TC offload is disabled on net device.", args)
563 sim.wait_for_flush() 632 sim.wait_for_flush()
564 633
565 sim.set_ethtool_tc_offloads(True) 634 sim.set_ethtool_tc_offloads(True)
@@ -587,13 +656,44 @@ try:
587 sim.dfs["bpf_tc_non_bound_accept"] = "N" 656 sim.dfs["bpf_tc_non_bound_accept"] = "N"
588 657
589 start_test("Test TC cBPF unbound bytecode doesn't offload...") 658 start_test("Test TC cBPF unbound bytecode doesn't offload...")
590 ret, _ = sim.cls_bpf_add_filter(bytecode, skip_sw=True, fail=False) 659 ret, _, err = sim.cls_bpf_add_filter(bytecode, skip_sw=True,
660 fail=False, include_stderr=True)
591 fail(ret == 0, "TC bytecode loaded for offload") 661 fail(ret == 0, "TC bytecode loaded for offload")
662 check_extack_nsim(err, "netdevsim configured to reject unbound programs.",
663 args)
592 sim.wait_for_flush() 664 sim.wait_for_flush()
593 665
666 start_test("Test TC replace...")
667 sim.cls_bpf_add_filter(obj, prio=1, handle=1)
668 sim.cls_bpf_add_filter(obj, op="replace", prio=1, handle=1)
669 sim.cls_filter_op(op="delete", prio=1, handle=1, cls="bpf")
670
671 sim.cls_bpf_add_filter(obj, prio=1, handle=1, skip_sw=True)
672 sim.cls_bpf_add_filter(obj, op="replace", prio=1, handle=1, skip_sw=True)
673 sim.cls_filter_op(op="delete", prio=1, handle=1, cls="bpf")
674
675 sim.cls_bpf_add_filter(obj, prio=1, handle=1, skip_hw=True)
676 sim.cls_bpf_add_filter(obj, op="replace", prio=1, handle=1, skip_hw=True)
677 sim.cls_filter_op(op="delete", prio=1, handle=1, cls="bpf")
678
679 start_test("Test TC replace bad flags...")
680 for i in range(3):
681 for j in range(3):
682 ret, _ = sim.cls_bpf_add_filter(obj, op="replace", prio=1, handle=1,
683 skip_sw=(j == 1), skip_hw=(j == 2),
684 fail=False)
685 fail(bool(ret) != bool(j),
686 "Software TC incorrect load in replace test, iteration %d" %
687 (j))
688 sim.cls_filter_op(op="delete", prio=1, handle=1, cls="bpf")
689
690 sim.tc_flush_filters()
691
594 start_test("Test TC offloads work...") 692 start_test("Test TC offloads work...")
595 ret, _ = sim.cls_bpf_add_filter(obj, skip_sw=True, fail=False) 693 ret, _, err = sim.cls_bpf_add_filter(obj, verbose=True, skip_sw=True,
694 fail=False, include_stderr=True)
596 fail(ret != 0, "TC filter did not load with TC offloads enabled") 695 fail(ret != 0, "TC filter did not load with TC offloads enabled")
696 check_verifier_log(err, "[netdevsim] Hello from netdevsim!")
597 697
598 start_test("Test TC offload basics...") 698 start_test("Test TC offload basics...")
599 dfs = sim.dfs_get_bound_progs(expected=1) 699 dfs = sim.dfs_get_bound_progs(expected=1)
@@ -669,16 +769,24 @@ try:
669 "Device parameters reported for non-offloaded program") 769 "Device parameters reported for non-offloaded program")
670 770
671 start_test("Test XDP prog replace with bad flags...") 771 start_test("Test XDP prog replace with bad flags...")
672 ret, _ = sim.set_xdp(obj, "offload", force=True, fail=False) 772 ret, _, err = sim.set_xdp(obj, "offload", force=True,
773 fail=False, include_stderr=True)
673 fail(ret == 0, "Replaced XDP program with a program in different mode") 774 fail(ret == 0, "Replaced XDP program with a program in different mode")
674 ret, _ = sim.set_xdp(obj, "", force=True, fail=False) 775 check_extack_nsim(err, "program loaded with different flags.", args)
776 ret, _, err = sim.set_xdp(obj, "", force=True,
777 fail=False, include_stderr=True)
675 fail(ret == 0, "Replaced XDP program with a program in different mode") 778 fail(ret == 0, "Replaced XDP program with a program in different mode")
779 check_extack_nsim(err, "program loaded with different flags.", args)
676 780
677 start_test("Test XDP prog remove with bad flags...") 781 start_test("Test XDP prog remove with bad flags...")
678 ret, _ = sim.unset_xdp("offload", force=True, fail=False) 782 ret, _, err = sim.unset_xdp("offload", force=True,
783 fail=False, include_stderr=True)
679 fail(ret == 0, "Removed program with a bad mode mode") 784 fail(ret == 0, "Removed program with a bad mode mode")
680 ret, _ = sim.unset_xdp("", force=True, fail=False) 785 check_extack_nsim(err, "program loaded with different flags.", args)
786 ret, _, err = sim.unset_xdp("", force=True,
787 fail=False, include_stderr=True)
681 fail(ret == 0, "Removed program with a bad mode mode") 788 fail(ret == 0, "Removed program with a bad mode mode")
789 check_extack_nsim(err, "program loaded with different flags.", args)
682 790
683 start_test("Test MTU restrictions...") 791 start_test("Test MTU restrictions...")
684 ret, _ = sim.set_mtu(9000, fail=False) 792 ret, _ = sim.set_mtu(9000, fail=False)
@@ -687,18 +795,20 @@ try:
687 sim.unset_xdp("drv") 795 sim.unset_xdp("drv")
688 bpftool_prog_list_wait(expected=0) 796 bpftool_prog_list_wait(expected=0)
689 sim.set_mtu(9000) 797 sim.set_mtu(9000)
690 ret, _ = sim.set_xdp(obj, "drv", fail=False) 798 ret, _, err = sim.set_xdp(obj, "drv", fail=False, include_stderr=True)
691 fail(ret == 0, "Driver should refuse to load program with MTU of 9000...") 799 fail(ret == 0, "Driver should refuse to load program with MTU of 9000...")
800 check_extack_nsim(err, "MTU too large w/ XDP enabled.", args)
692 sim.set_mtu(1500) 801 sim.set_mtu(1500)
693 802
694 sim.wait_for_flush() 803 sim.wait_for_flush()
695 start_test("Test XDP offload...") 804 start_test("Test XDP offload...")
696 sim.set_xdp(obj, "offload") 805 _, _, err = sim.set_xdp(obj, "offload", verbose=True, include_stderr=True)
697 ipl = sim.ip_link_show(xdp=True) 806 ipl = sim.ip_link_show(xdp=True)
698 link_xdp = ipl["xdp"]["prog"] 807 link_xdp = ipl["xdp"]["prog"]
699 progs = bpftool_prog_list(expected=1) 808 progs = bpftool_prog_list(expected=1)
700 prog = progs[0] 809 prog = progs[0]
701 fail(link_xdp["id"] != prog["id"], "Loaded program has wrong ID") 810 fail(link_xdp["id"] != prog["id"], "Loaded program has wrong ID")
811 check_verifier_log(err, "[netdevsim] Hello from netdevsim!")
702 812
703 start_test("Test XDP offload is device bound...") 813 start_test("Test XDP offload is device bound...")
704 dfs = sim.dfs_get_bound_progs(expected=1) 814 dfs = sim.dfs_get_bound_progs(expected=1)
@@ -724,25 +834,32 @@ try:
724 sim2.set_xdp(obj, "offload") 834 sim2.set_xdp(obj, "offload")
725 pin_file, pinned = pin_prog("/sys/fs/bpf/tmp") 835 pin_file, pinned = pin_prog("/sys/fs/bpf/tmp")
726 836
727 ret, _ = sim.set_xdp(pinned, "offload", fail=False) 837 ret, _, err = sim.set_xdp(pinned, "offload",
838 fail=False, include_stderr=True)
728 fail(ret == 0, "Pinned program loaded for a different device accepted") 839 fail(ret == 0, "Pinned program loaded for a different device accepted")
840 check_extack_nsim(err, "program bound to different dev.", args)
729 sim2.remove() 841 sim2.remove()
730 ret, _ = sim.set_xdp(pinned, "offload", fail=False) 842 ret, _, err = sim.set_xdp(pinned, "offload",
843 fail=False, include_stderr=True)
731 fail(ret == 0, "Pinned program loaded for a removed device accepted") 844 fail(ret == 0, "Pinned program loaded for a removed device accepted")
845 check_extack_nsim(err, "xdpoffload of non-bound program.", args)
732 rm(pin_file) 846 rm(pin_file)
733 bpftool_prog_list_wait(expected=0) 847 bpftool_prog_list_wait(expected=0)
734 848
735 start_test("Test mixing of TC and XDP...") 849 start_test("Test mixing of TC and XDP...")
736 sim.tc_add_ingress() 850 sim.tc_add_ingress()
737 sim.set_xdp(obj, "offload") 851 sim.set_xdp(obj, "offload")
738 ret, _ = sim.cls_bpf_add_filter(obj, skip_sw=True, fail=False) 852 ret, _, err = sim.cls_bpf_add_filter(obj, skip_sw=True,
853 fail=False, include_stderr=True)
739 fail(ret == 0, "Loading TC when XDP active should fail") 854 fail(ret == 0, "Loading TC when XDP active should fail")
855 check_extack_nsim(err, "driver and netdev offload states mismatch.", args)
740 sim.unset_xdp("offload") 856 sim.unset_xdp("offload")
741 sim.wait_for_flush() 857 sim.wait_for_flush()
742 858
743 sim.cls_bpf_add_filter(obj, skip_sw=True) 859 sim.cls_bpf_add_filter(obj, skip_sw=True)
744 ret, _ = sim.set_xdp(obj, "offload", fail=False) 860 ret, _, err = sim.set_xdp(obj, "offload", fail=False, include_stderr=True)
745 fail(ret == 0, "Loading XDP when TC active should fail") 861 fail(ret == 0, "Loading XDP when TC active should fail")
862 check_extack_nsim(err, "TC program is already loaded.", args)
746 863
747 start_test("Test binding TC from pinned...") 864 start_test("Test binding TC from pinned...")
748 pin_file, pinned = pin_prog("/sys/fs/bpf/tmp") 865 pin_file, pinned = pin_prog("/sys/fs/bpf/tmp")
@@ -765,8 +882,10 @@ try:
765 882
766 start_test("Test asking for TC offload of two filters...") 883 start_test("Test asking for TC offload of two filters...")
767 sim.cls_bpf_add_filter(obj, da=True, skip_sw=True) 884 sim.cls_bpf_add_filter(obj, da=True, skip_sw=True)
768 ret, _ = sim.cls_bpf_add_filter(obj, da=True, skip_sw=True, fail=False) 885 ret, _, err = sim.cls_bpf_add_filter(obj, da=True, skip_sw=True,
886 fail=False, include_stderr=True)
769 fail(ret == 0, "Managed to offload two TC filters at the same time") 887 fail(ret == 0, "Managed to offload two TC filters at the same time")
888 check_extack_nsim(err, "driver and netdev offload states mismatch.", args)
770 889
771 sim.tc_flush_filters(bound=2, total=2) 890 sim.tc_flush_filters(bound=2, total=2)
772 891