summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/tc-testing/tdc_gso.py
blob: b66528ea4b680a1f988677686e571a1d727ee896 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0

"""
tdc_gso.py - send a UDP GSO datagram

Copyright (C) 2026 Xingquan Liu <b1n@b1n.io>
"""

import argparse
import socket
import struct
import sys

UDP_MAX_SEGMENTS = 1 << 7


parser = argparse.ArgumentParser(description="UDP GSO datagram sender")
parser.add_argument("src", help="source IPv4 address")
parser.add_argument("dst", help="destination IPv4 address")
parser.add_argument("port", type=int, help="destination UDP port")
parser.add_argument("gso_size", type=int, help="UDP GSO segment payload size")
parser.add_argument("payload_len", type=int, help="total UDP payload length")
args = parser.parse_args()

if args.gso_size <= 0 or args.gso_size > 0xFFFF:
    parser.error("gso_size must fit in an unsigned 16-bit integer")
if args.payload_len <= args.gso_size:
    parser.error("payload_len must be larger than gso_size")
if args.payload_len > args.gso_size * UDP_MAX_SEGMENTS:
    parser.error("payload_len exceeds UDP_MAX_SEGMENTS")

SOL_UDP = getattr(socket, "SOL_UDP", socket.IPPROTO_UDP)
UDP_SEGMENT = getattr(socket, "UDP_SEGMENT", 103)

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((args.src, 0))

payload = b"b" * args.payload_len
cmsg = [(SOL_UDP, UDP_SEGMENT, struct.pack("=H", args.gso_size))]

sent = sock.sendmsg([payload], cmsg, 0, (args.dst, args.port))
sys.exit(sent != len(payload))