Commit cd31182c authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'selftests-test-xdp_tx-for-single-buffer'

Dimitri Daskalakis says:

====================
selftests: Test XDP_TX for single-buffer

Ensure single buffer XDP functions correctly by covering the following cases:
1) Zero size payload
2) Full MTU
3) Single buffer packets through a multi-buffer XDP program

These changes were tested with netdevsim and fbnic.

 # ./ksft-net-drv/drivers/net/xdp.py
 TAP version 13
 1..10
 ok 1 xdp.test_xdp_native_pass_sb
 ok 2 xdp.test_xdp_native_pass_mb
 ok 3 xdp.test_xdp_native_drop_sb
 ok 4 xdp.test_xdp_native_drop_mb
 ok 5 xdp.test_xdp_native_tx_sb
 ok 6 xdp.test_xdp_native_tx_mb
 # Failed run: pkt_sz 2048, offset 1. Last successful run: pkt_sz 1024, offset 256. Reason: Adjustment failed
 ok 7 xdp.test_xdp_native_adjst_tail_grow_data
 ok 8 xdp.test_xdp_native_adjst_tail_shrnk_data
 # Failed run: pkt_sz 512, offset -256. Last successful run: pkt_sz 512, offset -128. Reason: Adjustment failed
 ok 9 xdp.test_xdp_native_adjst_head_grow_data
 # Failed run: pkt_sz (2048) > HDS threshold (1536) and offset 64 > 48
 ok 10 xdp.test_xdp_native_adjst_head_shrnk_data
 # Totals: pass:10 fail:0 xfail:0 xpass:0 skip:0 error:0
====================

Link: https://patch.msgid.link/20250821014023.1481662-1-dimitri.daskalakis1@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents a7bd7215 bbd885b1
Loading
Loading
Loading
Loading
+58 −13
Original line number Diff line number Diff line
@@ -290,34 +290,78 @@ def test_xdp_native_drop_mb(cfg):
    _test_drop(cfg, bpf_info, 8000)


def test_xdp_native_tx_mb(cfg):
def _test_xdp_native_tx(cfg, bpf_info, payload_lens):
    """
    Tests the XDP_TX action for a multi-buff case.
    Tests the XDP_TX action.

    Args:
        cfg: Configuration object containing network settings.
        bpf_info: BPFProgInfo object containing the BPF program metadata.
        payload_lens: Array of packet lengths to send.
    """
    cfg.require_cmd("socat", remote=True)

    bpf_info = BPFProgInfo("xdp_prog_frags", "xdp_native.bpf.o", "xdp.frags", 9000)
    prog_info = _load_xdp_prog(cfg, bpf_info)
    port = rand_port()

    _set_xdp_map("map_xdp_setup", TestConfig.MODE.value, XDPAction.TX.value)
    _set_xdp_map("map_xdp_setup", TestConfig.PORT.value, port)

    test_string = ''.join(random.choice(string.ascii_lowercase) for _ in range(8000))
    rx_udp = f"socat -{cfg.addr_ipver} -T 2 -u UDP-RECV:{port},reuseport STDOUT"
    tx_udp = f"echo {test_string} | socat -t 2 -u STDIN UDP:{cfg.baddr}:{port}"
    expected_pkts = 0
    for payload_len in payload_lens:
        test_string = "".join(
            random.choice(string.ascii_lowercase) for _ in range(payload_len)
        )

        rx_udp = f"socat -{cfg.addr_ipver} -T 2 " + \
                 f"-u UDP-RECV:{port},reuseport STDOUT"

        # Writing zero bytes to stdin gets ignored by socat,
        # but with the shut-null flag socat generates a zero sized packet
        # when the socket is closed.
        tx_cmd_suffix = ",shut-null" if payload_len == 0 else ""
        tx_udp = f"echo -n {test_string} | socat -t 2 " + \
                 f"-u STDIN UDP:{cfg.baddr}:{port}{tx_cmd_suffix}"

        with bkg(rx_udp, host=cfg.remote, exit_wait=True) as rnc:
            wait_port_listen(port, proto="udp", host=cfg.remote)
            cmd(tx_udp, host=cfg.remote, shell=True)

    stats = _get_stats(prog_info['maps']['map_xdp_stats'])

        ksft_eq(rnc.stdout.strip(), test_string, "UDP packet exchange failed")
    ksft_eq(stats[XDPStats.TX.value], 1, "TX stats mismatch")

        expected_pkts += 1
        stats = _get_stats(prog_info["maps"]["map_xdp_stats"])
        ksft_eq(stats[XDPStats.RX.value], expected_pkts, "RX stats mismatch")
        ksft_eq(stats[XDPStats.TX.value], expected_pkts, "TX stats mismatch")


def test_xdp_native_tx_sb(cfg):
    """
    Tests the XDP_TX action for a single-buff case.

    Args:
        cfg: Configuration object containing network settings.
    """
    bpf_info = BPFProgInfo("xdp_prog", "xdp_native.bpf.o", "xdp", 1500)

    # Ensure there's enough room for an ETH / IP / UDP header
    pkt_hdr_len = 42 if cfg.addr_ipver == "4" else 62

    _test_xdp_native_tx(cfg, bpf_info, [0, 1500 // 2, 1500 - pkt_hdr_len])


def test_xdp_native_tx_mb(cfg):
    """
    Tests the XDP_TX action for a multi-buff case.

    Args:
        cfg: Configuration object containing network settings.
    """
    bpf_info = BPFProgInfo("xdp_prog_frags", "xdp_native.bpf.o",
                           "xdp.frags", 9000)
    # The first packet ensures we exercise the fragmented code path.
    # And the subsequent 0-sized packet ensures the driver
    # reinitializes xdp_buff correctly.
    _test_xdp_native_tx(cfg, bpf_info, [8000, 0])


def _validate_res(res, offset_lst, pkt_sz_lst):
@@ -644,6 +688,7 @@ def main():
                test_xdp_native_pass_mb,
                test_xdp_native_drop_sb,
                test_xdp_native_drop_mb,
                test_xdp_native_tx_sb,
                test_xdp_native_tx_mb,
                test_xdp_native_adjst_tail_grow_data,
                test_xdp_native_adjst_tail_shrnk_data,