Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next] selftests: net: add IPv4 and IPv6 same scope address order check
@ 2026-09-01  8:22 Martin Jabůrek
  2026-09-01 15:34 ` Ido Schimmel
  2026-09-01 22:51 ` Jakub Kicinski
  0 siblings, 2 replies; 3+ messages in thread
From: Martin Jabůrek @ 2026-09-01  8:22 UTC (permalink / raw)
  To: netdev
  Cc: davem, edumazet, kuba, pabeni, horms, idosch, Martin Jabůrek,
	Fernando Fernandez Mancera

Introduce two new tests `ipv4_verify_addr_order` and
`ipv6_verify_addr_order`, to check the ordering of
a set of IP addresses after insertion.

The implementations of these protocols are inconsistent
in regard to address ordering. IPv4 addresses stay in the
same order as inserted while IPv6 addresses appear in
reverse order. This incosistency has prompted attempts
to unify the ordering, so both protocols act the same
(as IPv4). This however caused user-space regressions in
certain applications, which relied on the order as it
was prior to the change (particularly NetworkManager).

The addition of these tests aims to consolidate the
behaviour to prevent regressions in the future.
The expected behaviour is the initial one, where each
protocol acts differently.

Tests were verified on a recent commit with the expected
behaviour (61eb236c41c2) and a commit making both protocols
act the same way (cb3de96eea66). Tests respectively pass
and not pass as expected.

Conversations detailing the decision process for creating
these tests are linked below.

Link: https://lore.kernel.org/netdev/20260521135310.GC977@cmadams.net/
Link: https://lore.kernel.org/netdev/20260529112357.5079-1-fmancera@suse.de/
Suggested-by: Fernando Fernandez Mancera <fmancera@suse.de>
Signed-off-by: Martin Jabůrek <martin.jaburek@suse.com>
---
 tools/testing/selftests/net/rtnetlink.py | 58 +++++++++++++++++++++++-
 1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/net/rtnetlink.py b/tools/testing/selftests/net/rtnetlink.py
index 5cc3ebdcf08d..1ee604e4e5f6 100755
--- a/tools/testing/selftests/net/rtnetlink.py
+++ b/tools/testing/selftests/net/rtnetlink.py
@@ -314,11 +314,67 @@ def ipv6_route_del_reason_absent() -> None:
                         "user deletion must not carry del-reason")
 
 
+def ipv4_verify_addr_order() -> None:
+    """
+    After inserting multiple same scope IPv4 addresses, their order
+    must be the same as the insertion order.
+
+    See function ipv6_verify_addr_order in this file for further details.
+    """
+
+    DEV_NAME = "dummy_dev"
+    TEST_ADDRESSES = ["192.0.2.1", "192.0.2.2", "192.0.2.3"]
+
+    with NetNS() as ns:
+        with NetNSEnter(str(ns)):
+            ip(f"link add name {DEV_NAME} type dummy", ns=str(ns))
+            for addr in TEST_ADDRESSES:
+                ip(f"address add {addr}/24 dev {DEV_NAME}", ns=str(ns))
+            ip(f"link set dev {DEV_NAME} up", ns=str(ns))
+
+            rtnl = RtnlAddrFamily()
+            addrs = rtnl.getaddr({"ifa-family": socket.AF_INET}, dump=True)
+            address_list = [addr["address"] for addr in addrs]
+
+            ksft_eq(TEST_ADDRESSES, address_list, "Incorrect IPv4 address order")
+
+
+def ipv6_verify_addr_order() -> None:
+    """
+    After inserting multiple same scope IPv6 addresses, their order
+    must be the _reverse_ of the insertion order.
+
+    While this behaviour is different from how IPv4 acts,
+    updating the IPv6 implementation to act the same way
+    has proved to cause user-space application regressions
+    (particularly in NetworkManager). This behaviour is being
+    tested for to consolidate it as being expected and correct.
+    """
+
+    DEV_NAME = "dummy_dev"
+    TEST_ADDRESSES = ["2001:db8::1", "2001:db8::2", "2001:db8::3"]
+
+    with NetNS() as ns:
+        with NetNSEnter(str(ns)):
+            ip(f"link add name {DEV_NAME} type dummy", ns=str(ns))
+            for addr in TEST_ADDRESSES:
+                ip(f"address add {addr}/32 dev {DEV_NAME}", ns=str(ns))
+            ip(f"link set dev {DEV_NAME} up", ns=str(ns))
+
+            rtnl = RtnlAddrFamily()
+            addrs = rtnl.getaddr({"ifa-family": socket.AF_INET6}, dump=True)
+            address_list = [addr["address"] for addr in addrs]
+
+            # We ignore the link-local address present by default.
+            ksft_eq(TEST_ADDRESSES[::-1], address_list[:3], "Incorrect IPv6 address order")
+
+
 def main() -> None:
     ksft_run([dump_mcaddr_check, dump_mcaddr6_check, ipv4_devconf_notify,
               ipv6_route_del_reason_expired,
               ipv6_route_del_reason_ra_withdrawn,
-              ipv6_route_del_reason_absent])
+              ipv6_route_del_reason_absent,
+              ipv4_verify_addr_order, ipv6_verify_addr_order])
     ksft_exit()
 
 if __name__ == "__main__":
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-09-01 22:51 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-01  8:22 [PATCH net-next] selftests: net: add IPv4 and IPv6 same scope address order check Martin Jabůrek
2026-09-01 15:34 ` Ido Schimmel
2026-09-01 22:51 ` Jakub Kicinski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox