Skip to content

Commit 5ee0e8e

Browse files
committed
udp gso/gro: move policy to client; send explicit params; server accepts and applies locally
Client remains the source of truth for UDP GSO/GRO policy (including --no-gsro). During parameter exchange, the client now sends GSO/GRO flags and sizes in JSON, and the server simply consumes those values without recomputing. Kernel capability gating stays local and authoritative: each endpoint attempts to enable GSO/GRO on its own sockets via setsockopt, and if the kernel rejects it, we log and flip the local flag off. This handles the case where only one side supports the feature (GSO for the sender, GRO for the receiver). Backward compatibility: if talking to an older client that doesn’t send GSO fields, the server derives gso_dg_size from blksize and adjusts gso_bf_size, falling back to DEFAULT_UDP_BLKSIZE if zero. This preserves previous behavior without overriding explicit client intent. Behavior details: - --no-gsro on the client sends gso=0 and gro=0, so the server won’t try to enable them. - If -l/--length is provided, blksize (and therefore gso_dg_size when enabled) follows that value; otherwise default logic applies. Files: src/iperf_api.c (send_parameters adds gso/gro fields; get_parameters reads them and removes server-side recompute unless needed for compatibility).
1 parent d26a207 commit 5ee0e8e

File tree

1 file changed

+34
-3
lines changed

1 file changed

+34
-3
lines changed

src/iperf_api.c

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2479,6 +2479,22 @@ send_parameters(struct iperf_test *test)
24792479
cJSON_AddNumberToObject(j, "pacing_timer", test->settings->pacing_timer);
24802480
if (test->settings->burst)
24812481
cJSON_AddNumberToObject(j, "burst", test->settings->burst);
2482+
2483+
#ifdef HAVE_UDP_SEGMENT
2484+
/* Send UDP GSO settings from client to server */
2485+
if (test->protocol->id == Pudp) {
2486+
cJSON_AddNumberToObject(j, "gso", test->settings->gso);
2487+
cJSON_AddNumberToObject(j, "gso_dg_size", test->settings->gso_dg_size);
2488+
cJSON_AddNumberToObject(j, "gso_bf_size", test->settings->gso_bf_size);
2489+
}
2490+
#endif
2491+
#ifdef HAVE_UDP_GRO
2492+
/* Send UDP GRO settings from client to server */
2493+
if (test->protocol->id == Pudp) {
2494+
cJSON_AddNumberToObject(j, "gro", test->settings->gro);
2495+
cJSON_AddNumberToObject(j, "gro_bf_size", test->settings->gro_bf_size);
2496+
}
2497+
#endif
24822498
if (test->settings->tos)
24832499
cJSON_AddNumberToObject(j, "TOS", test->settings->tos);
24842500
if (test->settings->flowlabel)
@@ -2602,17 +2618,32 @@ get_parameters(struct iperf_test *test)
26022618
test->settings->socket_bufsize = j_p->valueint;
26032619
if ((j_p = iperf_cJSON_GetObjectItemType(j, "len", cJSON_Number)) != NULL)
26042620
test->settings->blksize = j_p->valueint;
2621+
26052622
#ifdef HAVE_UDP_SEGMENT
2606-
if (test->protocol->id == Pudp && test->settings->gso == 1) {
2623+
/* Accept UDP GSO settings provided by the client */
2624+
if ((j_p = iperf_cJSON_GetObjectItemType(j, "gso", cJSON_Number)) != NULL)
2625+
test->settings->gso = j_p->valueint;
2626+
if ((j_p = iperf_cJSON_GetObjectItemType(j, "gso_dg_size", cJSON_Number)) != NULL)
2627+
test->settings->gso_dg_size = j_p->valueint;
2628+
if ((j_p = iperf_cJSON_GetObjectItemType(j, "gso_bf_size", cJSON_Number)) != NULL)
2629+
test->settings->gso_bf_size = j_p->valueint;
2630+
2631+
/* Backward-compatibility: If client didn't send GSO params, derive from blksize. */
2632+
if (test->protocol->id == Pudp && test->settings->gso == 1 && test->settings->gso_dg_size == 0) {
26072633
test->settings->gso_dg_size = test->settings->blksize;
2608-
/* use the multiple of datagram size for the best efficiency. */
26092634
if (test->settings->gso_dg_size > 0) {
26102635
test->settings->gso_bf_size = (test->settings->gso_bf_size / test->settings->gso_dg_size) * test->settings->gso_dg_size;
26112636
} else {
2612-
/* If gso_dg_size is 0 (unlimited bandwidth), use default UDP datagram size */
26132637
test->settings->gso_dg_size = DEFAULT_UDP_BLKSIZE;
26142638
}
26152639
}
2640+
#endif
2641+
#ifdef HAVE_UDP_GRO
2642+
/* Accept UDP GRO settings provided by the client */
2643+
if ((j_p = iperf_cJSON_GetObjectItemType(j, "gro", cJSON_Number)) != NULL)
2644+
test->settings->gro = j_p->valueint;
2645+
if ((j_p = iperf_cJSON_GetObjectItemType(j, "gro_bf_size", cJSON_Number)) != NULL)
2646+
test->settings->gro_bf_size = j_p->valueint;
26162647
#endif
26172648
if ((j_p = iperf_cJSON_GetObjectItemType(j, "bandwidth", cJSON_Number)) != NULL)
26182649
test->settings->rate = j_p->valueint;

0 commit comments

Comments
 (0)