diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 3ee3378f8b26..d4ca82fec0b4 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -67,6 +67,7 @@ TEST_PROGS := \ nat6to4.sh \ ndisc_unsolicited_na_test.sh \ netdev-l2addr.sh \ + netdev_lock.py \ netdevice.sh \ netns-name.sh \ netns-sysctl.sh \ diff --git a/tools/testing/selftests/net/netdev_lock.py b/tools/testing/selftests/net/netdev_lock.py new file mode 100755 index 000000000000..0015b987eb9d --- /dev/null +++ b/tools/testing/selftests/net/netdev_lock.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 + +"""Tests for the netdev instance lock.""" + +from lib.py import ksft_run, ksft_exit +from lib.py import ip +from lib.py import NetNS + + +def test_unreg_order() -> None: + """Dismantle two netns holding the same two kinds of ops locked device, + registered in opposite order. + + unregister_netdevice_many_notify() takes the instance lock of every + device in the batch and holds them all at once, so the two kinds end up + nested one way round for the first netns and the other way round for + the second. + """ + with NetNS() as ns1, NetNS() as ns2: + net1, net2 = str(ns1), str(ns2) + + ip("link add du0 type dummy", ns=net1) + ip("link add nk0 type netkit peer name nk1", ns=net1) + + ip("link add nk0 type netkit peer name nk1", ns=net2) + ip("link add du0 type dummy", ns=net2) + + # only devices which are up get locked during unregister + for net in (net1, net2): + for dev in ("du0", "nk0", "nk1"): + ip(f"link set {dev} up", ns=net) + + +def main() -> None: + """Ksft boilerplate main.""" + ksft_run([test_unreg_order]) + ksft_exit() + + +if __name__ == "__main__": + main()