@@ -314,8 +314,13 @@ def _test_xdp_native_tx(cfg, bpf_info, payload_lens):
314314
315315 rx_udp = f"socat -{ cfg .addr_ipver } -T 2 " + \
316316 f"-u UDP-RECV:{ port } ,reuseport STDOUT"
317+
318+ # Writing zero bytes to stdin gets ignored by socat,
319+ # but with the shut-null flag socat generates a zero sized packet
320+ # when the socket is closed.
321+ tx_cmd_suffix = ",shut-null" if payload_len == 0 else ""
317322 tx_udp = f"echo -n { test_string } | socat -t 2 " + \
318- f"-u STDIN UDP:{ cfg .baddr } :{ port } "
323+ f"-u STDIN UDP:{ cfg .baddr } :{ port } { tx_cmd_suffix } "
319324
320325 with bkg (rx_udp , host = cfg .remote , exit_wait = True ) as rnc :
321326 wait_port_listen (port , proto = "udp" , host = cfg .remote )
@@ -329,6 +334,21 @@ def _test_xdp_native_tx(cfg, bpf_info, payload_lens):
329334 ksft_eq (stats [XDPStats .TX .value ], expected_pkts , "TX stats mismatch" )
330335
331336
337+ def test_xdp_native_tx_sb (cfg ):
338+ """
339+ Tests the XDP_TX action for a single-buff case.
340+
341+ Args:
342+ cfg: Configuration object containing network settings.
343+ """
344+ bpf_info = BPFProgInfo ("xdp_prog" , "xdp_native.bpf.o" , "xdp" , 1500 )
345+
346+ # Ensure there's enough room for an ETH / IP / UDP header
347+ pkt_hdr_len = 42 if cfg .addr_ipver == "4" else 62
348+
349+ _test_xdp_native_tx (cfg , bpf_info , [0 , 1500 // 2 , 1500 - pkt_hdr_len ])
350+
351+
332352def test_xdp_native_tx_mb (cfg ):
333353 """
334354 Tests the XDP_TX action for a multi-buff case.
@@ -665,6 +685,7 @@ def main():
665685 test_xdp_native_pass_mb ,
666686 test_xdp_native_drop_sb ,
667687 test_xdp_native_drop_mb ,
688+ test_xdp_native_tx_sb ,
668689 test_xdp_native_tx_mb ,
669690 test_xdp_native_adjst_tail_grow_data ,
670691 test_xdp_native_adjst_tail_shrnk_data ,
0 commit comments