xref: /linux/tools/testing/selftests/tc-testing/tdc_gso.py (revision 2ed2e359dea752e7758d29a423033031a0b96584)
1*54704b32SXingquan Liu#!/usr/bin/env python3
2*54704b32SXingquan Liu# SPDX-License-Identifier: GPL-2.0
3*54704b32SXingquan Liu
4*54704b32SXingquan Liu"""
5*54704b32SXingquan Liutdc_gso.py - send a UDP GSO datagram
6*54704b32SXingquan Liu
7*54704b32SXingquan LiuCopyright (C) 2026 Xingquan Liu <b1n@b1n.io>
8*54704b32SXingquan Liu"""
9*54704b32SXingquan Liu
10*54704b32SXingquan Liuimport argparse
11*54704b32SXingquan Liuimport socket
12*54704b32SXingquan Liuimport struct
13*54704b32SXingquan Liuimport sys
14*54704b32SXingquan Liu
15*54704b32SXingquan LiuUDP_MAX_SEGMENTS = 1 << 7
16*54704b32SXingquan Liu
17*54704b32SXingquan Liu
18*54704b32SXingquan Liuparser = argparse.ArgumentParser(description="UDP GSO datagram sender")
19*54704b32SXingquan Liuparser.add_argument("src", help="source IPv4 address")
20*54704b32SXingquan Liuparser.add_argument("dst", help="destination IPv4 address")
21*54704b32SXingquan Liuparser.add_argument("port", type=int, help="destination UDP port")
22*54704b32SXingquan Liuparser.add_argument("gso_size", type=int, help="UDP GSO segment payload size")
23*54704b32SXingquan Liuparser.add_argument("payload_len", type=int, help="total UDP payload length")
24*54704b32SXingquan Liuargs = parser.parse_args()
25*54704b32SXingquan Liu
26*54704b32SXingquan Liuif args.gso_size <= 0 or args.gso_size > 0xFFFF:
27*54704b32SXingquan Liu    parser.error("gso_size must fit in an unsigned 16-bit integer")
28*54704b32SXingquan Liuif args.payload_len <= args.gso_size:
29*54704b32SXingquan Liu    parser.error("payload_len must be larger than gso_size")
30*54704b32SXingquan Liuif args.payload_len > args.gso_size * UDP_MAX_SEGMENTS:
31*54704b32SXingquan Liu    parser.error("payload_len exceeds UDP_MAX_SEGMENTS")
32*54704b32SXingquan Liu
33*54704b32SXingquan LiuSOL_UDP = getattr(socket, "SOL_UDP", socket.IPPROTO_UDP)
34*54704b32SXingquan LiuUDP_SEGMENT = getattr(socket, "UDP_SEGMENT", 103)
35*54704b32SXingquan Liu
36*54704b32SXingquan Liusock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
37*54704b32SXingquan Liusock.bind((args.src, 0))
38*54704b32SXingquan Liu
39*54704b32SXingquan Liupayload = b"b" * args.payload_len
40*54704b32SXingquan Liucmsg = [(SOL_UDP, UDP_SEGMENT, struct.pack("=H", args.gso_size))]
41*54704b32SXingquan Liu
42*54704b32SXingquan Liusent = sock.sendmsg([payload], cmsg, 0, (args.dst, args.port))
43*54704b32SXingquan Liusys.exit(sent != len(payload))
44