[PATCH net-next 5/6] selftests: drv-net: add netkit devmem RX test

Bobby Eshleman posted 6 patches 3 weeks ago
[PATCH net-next 5/6] selftests: drv-net: add netkit devmem RX test
Posted by Bobby Eshleman 3 weeks ago
From: Bobby Eshleman <bobbyeshleman@meta.com>

Add tests for devmem RX over a netkit device with a leased queue. This
is the same as the other devmem RX test except for ncdevmem executes in
a namespace, binds to a netkit, and skips the ethtool NIC configuration
steps (relying on the test runner for that setup).

The RX path is setup as the following:

 RX Path
 -------

 Remote            Physical NIC          Netkit Host        Netkit Guest (netns)
   |                    |                     |                    |
   |--- TCP send ------>|                     |                    |
                        |-------------------->|                    |
                      dmabuf                  |--- BPF redirect -->|

Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
---
 tools/testing/selftests/drivers/net/hw/Makefile    |   1 +
 .../testing/selftests/drivers/net/hw/nk_devmem.py  | 104 +++++++++++++++++++++
 2 files changed, 105 insertions(+)

diff --git a/tools/testing/selftests/drivers/net/hw/Makefile b/tools/testing/selftests/drivers/net/hw/Makefile
index 91df028abfc0..3cd68e06f592 100644
--- a/tools/testing/selftests/drivers/net/hw/Makefile
+++ b/tools/testing/selftests/drivers/net/hw/Makefile
@@ -32,6 +32,7 @@ TEST_PROGS = \
 	irq.py \
 	loopback.sh \
 	nic_timestamp.py \
+	nk_devmem.py \
 	nk_netns.py \
 	pp_alloc_fail.py \
 	rss_api.py \
diff --git a/tools/testing/selftests/drivers/net/hw/nk_devmem.py b/tools/testing/selftests/drivers/net/hw/nk_devmem.py
new file mode 100755
index 000000000000..0a66ff85db9d
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/hw/nk_devmem.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+"""Test devmem TCP through netkit with queue leasing."""
+
+import re
+from os import path
+from lib.py import ksft_run, ksft_exit, ksft_eq, KsftSkipEx
+from lib.py import NetDrvContEnv, NetNSEnter, EthtoolFamily, NetdevFamily
+from lib.py import bkg, cmd, defer, ethtool, rand_port, wait_port_listen
+
+
+def set_flow_rule(cfg):
+    """Insert an ethtool flow rule steering traffic to the leased queue."""
+    output = ethtool(
+        f"-N {cfg.ifname} flow-type tcp6 dst-port {cfg.port}"
+        f" action {cfg.src_queue}"
+    ).stdout
+    values = re.search(r'ID (\d+)', output).group(1)
+    return int(values)
+
+
+def configure_nic(cfg):
+    """Common setup for devmem tests: channels, rings, RSS, queue lease."""
+    cfg.require_ipver('6')
+    ethnl = EthtoolFamily()
+
+    channels = ethnl.channels_get({'header': {'dev-index': cfg.ifindex}})
+    channels = channels['combined-count']
+    if channels < 2:
+        raise KsftSkipEx(
+            'Test requires NETIF with at least 2 combined channels'
+        )
+
+    rings = ethnl.rings_get({'header': {'dev-index': cfg.ifindex}})
+    rx_rings = rings['rx']
+    hds_thresh = rings.get('hds-thresh', 0)
+    orig_data_split = rings.get('tcp-data-split', 'unknown')
+
+    ethnl.rings_set({'header': {'dev-index': cfg.ifindex},
+                         'tcp-data-split': 'enabled',
+                         'hds-thresh': 0,
+                         'rx': min(64, rx_rings)})
+    defer(ethnl.rings_set, {'header': {'dev-index': cfg.ifindex},
+                                'tcp-data-split': orig_data_split,
+                                'hds-thresh': hds_thresh,
+                                'rx': rx_rings})
+
+    cfg.src_queue = channels - 1
+    ethtool(f"-X {cfg.ifname} equal {cfg.src_queue}")
+    defer(ethtool, f"-X {cfg.ifname} default")
+
+    if hasattr(cfg, 'nk_queue'):
+        return
+
+    with NetNSEnter(str(cfg.netns)):
+        netdevnl = NetdevFamily()
+        lease_result = netdevnl.queue_create(
+            {
+                "ifindex": cfg.nk_guest_ifindex,
+                "type": "rx",
+                "lease": {
+                    "ifindex": cfg.ifindex,
+                    "queue": {"id": cfg.src_queue, "type": "rx"},
+                    "netns-id": 0,
+                },
+            }
+        )
+        cfg.nk_queue = lease_result['id']
+
+
+def test_devmem(cfg) -> None:
+    """Test devmem RX: send from remote, receive on netkit guest."""
+    configure_nic(cfg)
+
+    flow_rule_id = set_flow_rule(cfg)
+    defer(ethtool, f"-N {cfg.ifname} delete {flow_rule_id}")
+
+    rx_cmd = (f"ip netns exec {cfg.netns.name} {cfg.bin_local}"
+              f" -l -f {cfg._nk_guest_ifname} -s {cfg.nk_guest_ipv6}"
+              f" -p {cfg.port} -t {cfg.nk_queue} -q 1 -v 7 -n")
+    socat = f"socat -u - TCP6:[{cfg.nk_guest_ipv6}]:{cfg.port}"
+
+    with bkg(rx_cmd, exit_wait=True) as ncdevmem_rx:
+        wait_port_listen(cfg.port, proto="tcp", ns=cfg.netns)
+        cmd(f"yes $(echo -e \x01\x02\x03\x04\x05\x06) | head -c 1K"
+            f" | {socat}",
+            host=cfg.remote, shell=True)
+
+    ksft_eq(ncdevmem_rx.ret, 0)
+
+
+def main() -> None:
+    """Run netkit devmem tests."""
+    with NetDrvContEnv(__file__, rxqueues=2) as cfg:
+        cfg.bin_local = path.abspath(
+            path.dirname(__file__) + "/ncdevmem"
+        )
+        cfg.port = rand_port()
+        ksft_run([test_devmem], args=(cfg,))
+    ksft_exit()
+
+
+if __name__ == "__main__":
+    main()

-- 
2.52.0
Re: [PATCH net-next 5/6] selftests: drv-net: add netkit devmem RX test
Posted by Stanislav Fomichev 2 weeks, 6 days ago
On 03/16, Bobby Eshleman wrote:
> From: Bobby Eshleman <bobbyeshleman@meta.com>
> 
> Add tests for devmem RX over a netkit device with a leased queue. This
> is the same as the other devmem RX test except for ncdevmem executes in
> a namespace, binds to a netkit, and skips the ethtool NIC configuration
> steps (relying on the test runner for that setup).
> 
> The RX path is setup as the following:
> 
>  RX Path
>  -------
> 
>  Remote            Physical NIC          Netkit Host        Netkit Guest (netns)
>    |                    |                     |                    |
>    |--- TCP send ------>|                     |                    |
>                         |-------------------->|                    |
>                       dmabuf                  |--- BPF redirect -->|
> 

Is it too messy to parametrize the existing test to run both with and
without the namespaces? Feels like should be somewhat doable in python?
Re: [PATCH net-next 5/6] selftests: drv-net: add netkit devmem RX test
Posted by Bobby Eshleman 2 weeks, 6 days ago
On Tue, Mar 17, 2026 at 05:08:20PM -0700, Stanislav Fomichev wrote:
> On 03/16, Bobby Eshleman wrote:
> > From: Bobby Eshleman <bobbyeshleman@meta.com>
> > 
> > Add tests for devmem RX over a netkit device with a leased queue. This
> > is the same as the other devmem RX test except for ncdevmem executes in
> > a namespace, binds to a netkit, and skips the ethtool NIC configuration
> > steps (relying on the test runner for that setup).
> > 
> > The RX path is setup as the following:
> > 
> >  RX Path
> >  -------
> > 
> >  Remote            Physical NIC          Netkit Host        Netkit Guest (netns)
> >    |                    |                     |                    |
> >    |--- TCP send ------>|                     |                    |
> >                         |-------------------->|                    |
> >                       dmabuf                  |--- BPF redirect -->|
> > 
> 
> Is it too messy to parametrize the existing test to run both with and
> without the namespaces? Feels like should be somewhat doable in python?

IIUC, we could have main() do something like:

for env [NetDrvContEnv, NetDrvEpEnv]:
    with env as cfg:
        [...]
        ksft_run(tests, args=(cfg,))


And then the tests could call helpers that check cfg.netns to use the
nk_{guest,host}_ip6 addresses when true, otherwise use the regular
addresses?

It should be doable if I'm following your drift.

Best,
Bobby
Re: [PATCH net-next 5/6] selftests: drv-net: add netkit devmem RX test
Posted by Stanislav Fomichev 2 weeks, 5 days ago
On 03/17, Bobby Eshleman wrote:
> On Tue, Mar 17, 2026 at 05:08:20PM -0700, Stanislav Fomichev wrote:
> > On 03/16, Bobby Eshleman wrote:
> > > From: Bobby Eshleman <bobbyeshleman@meta.com>
> > > 
> > > Add tests for devmem RX over a netkit device with a leased queue. This
> > > is the same as the other devmem RX test except for ncdevmem executes in
> > > a namespace, binds to a netkit, and skips the ethtool NIC configuration
> > > steps (relying on the test runner for that setup).
> > > 
> > > The RX path is setup as the following:
> > > 
> > >  RX Path
> > >  -------
> > > 
> > >  Remote            Physical NIC          Netkit Host        Netkit Guest (netns)
> > >    |                    |                     |                    |
> > >    |--- TCP send ------>|                     |                    |
> > >                         |-------------------->|                    |
> > >                       dmabuf                  |--- BPF redirect -->|
> > > 
> > 
> > Is it too messy to parametrize the existing test to run both with and
> > without the namespaces? Feels like should be somewhat doable in python?
> 
> IIUC, we could have main() do something like:
> 
> for env [NetDrvContEnv, NetDrvEpEnv]:
>     with env as cfg:
>         [...]
>         ksft_run(tests, args=(cfg,))
> 
> 
> And then the tests could call helpers that check cfg.netns to use the
> nk_{guest,host}_ip6 addresses when true, otherwise use the regular
> addresses?
> 
> It should be doable if I'm following your drift.

Yeah, yeah, this plus some small changes here and there (to pass your
new -n in the netns mode for example).
Re: [PATCH net-next 5/6] selftests: drv-net: add netkit devmem RX test
Posted by Bobby Eshleman 2 weeks, 5 days ago
On Wed, Mar 18, 2026 at 07:59:57AM -0700, Stanislav Fomichev wrote:
> On 03/17, Bobby Eshleman wrote:
> > On Tue, Mar 17, 2026 at 05:08:20PM -0700, Stanislav Fomichev wrote:
> > > On 03/16, Bobby Eshleman wrote:
> > > > From: Bobby Eshleman <bobbyeshleman@meta.com>
> > > > 
> > > > Add tests for devmem RX over a netkit device with a leased queue. This
> > > > is the same as the other devmem RX test except for ncdevmem executes in
> > > > a namespace, binds to a netkit, and skips the ethtool NIC configuration
> > > > steps (relying on the test runner for that setup).
> > > > 
> > > > The RX path is setup as the following:
> > > > 
> > > >  RX Path
> > > >  -------
> > > > 
> > > >  Remote            Physical NIC          Netkit Host        Netkit Guest (netns)
> > > >    |                    |                     |                    |
> > > >    |--- TCP send ------>|                     |                    |
> > > >                         |-------------------->|                    |
> > > >                       dmabuf                  |--- BPF redirect -->|
> > > > 
> > > 
> > > Is it too messy to parametrize the existing test to run both with and
> > > without the namespaces? Feels like should be somewhat doable in python?
> > 
> > IIUC, we could have main() do something like:
> > 
> > for env [NetDrvContEnv, NetDrvEpEnv]:
> >     with env as cfg:
> >         [...]
> >         ksft_run(tests, args=(cfg,))
> > 
> > 
> > And then the tests could call helpers that check cfg.netns to use the
> > nk_{guest,host}_ip6 addresses when true, otherwise use the regular
> > addresses?
> > 
> > It should be doable if I'm following your drift.
> 
> Yeah, yeah, this plus some small changes here and there (to pass your
> new -n in the netns mode for example).

Sounds good, I'll give it a look.
Re: [PATCH net-next 5/6] selftests: drv-net: add netkit devmem RX test
Posted by Jakub Kicinski 2 weeks, 5 days ago
On Wed, 18 Mar 2026 09:21:32 -0700 Bobby Eshleman wrote:
> > > IIUC, we could have main() do something like:
> > > 
> > > for env [NetDrvContEnv, NetDrvEpEnv]:
> > >     with env as cfg:
> > >         [...]
> > >         ksft_run(tests, args=(cfg,))
> > > 
> > > 
> > > And then the tests could call helpers that check cfg.netns to use the
> > > nk_{guest,host}_ip6 addresses when true, otherwise use the regular
> > > addresses?
> > > 
> > > It should be doable if I'm following your drift.  
> > 
> > Yeah, yeah, this plus some small changes here and there (to pass your
> > new -n in the netns mode for example).  
> 
> Sounds good, I'll give it a look.

I haven't actually looked but double check ksft_run can actually 
be called multiple times. We may have some global state :S
Re: [PATCH net-next 5/6] selftests: drv-net: add netkit devmem RX test
Posted by Bobby Eshleman 2 weeks, 5 days ago
On Wed, Mar 18, 2026 at 04:10:10PM -0700, Jakub Kicinski wrote:
> On Wed, 18 Mar 2026 09:21:32 -0700 Bobby Eshleman wrote:
> > > > IIUC, we could have main() do something like:
> > > > 
> > > > for env [NetDrvContEnv, NetDrvEpEnv]:
> > > >     with env as cfg:
> > > >         [...]
> > > >         ksft_run(tests, args=(cfg,))
> > > > 
> > > > 
> > > > And then the tests could call helpers that check cfg.netns to use the
> > > > nk_{guest,host}_ip6 addresses when true, otherwise use the regular
> > > > addresses?
> > > > 
> > > > It should be doable if I'm following your drift.  
> > > 
> > > Yeah, yeah, this plus some small changes here and there (to pass your
> > > new -n in the netns mode for example).  
> > 
> > Sounds good, I'll give it a look.
> 
> I haven't actually looked but double check ksft_run can actually 
> be called multiple times. We may have some global state :S

The result is global, but accumulates correctly.

But the tap output doubles:

TAP version 13
1..2
ok 1 devmem.check_nk_rx
ok 2 devmem.check_nk_tx
# Totals: pass:2 ...
TAP version 13
1..4
ok 1 devmem.check_rx
ok 2 devmem.check_tx
ok 3 devmem.check_tx_chunks
ok 4 devmem.check_rx_hds
# Totals: pass:4 ...

Not sure what outside parsing expects yet...