Skip to content

Commit 779ada5

Browse files
committed
[nrf fromlist] net: zperf: Improve UDP multicast upload
UDP multicast uploads did not produce zperf-compatible server stats, so the client waited for and tried to decode a non-existent reply, causing “Unexpected response flags” and misleading “LAST PACKET NOT RECEIVED!!!” output. This change treats multicast as client-only: after sending the negative-id FIN it does not wait for or decode server stats, Instead transmits the FIN a few times to help receivers detect test end. The shell prints a clear “Statistics (client only)” summary for multicast and suppresses the error when client stats are valid. Unicast behavior is unchanged. Upstream PR #: 94344 Signed-off-by: Kapil Bhatt <[email protected]>
1 parent 2cc69ef commit 779ada5

File tree

3 files changed

+59
-33
lines changed

3 files changed

+59
-33
lines changed

include/zephyr/net/zperf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ struct zperf_results {
9090
uint64_t client_time_in_us; /**< Client connection time in microseconds */
9191
uint32_t packet_size; /**< Packet size */
9292
uint32_t nb_packets_errors; /**< Number of packet errors */
93+
bool is_multicast; /**< True if this session used IP multicast */
9394
};
9495

9596
/**

subsys/net/lib/zperf/zperf_shell.c

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -516,41 +516,56 @@ static void shell_udp_upload_print_stats(const struct shell *sh,
516516
client_rate_in_kbps = 0U;
517517
}
518518

519-
if (!rate_in_kbps) {
519+
/* Print warning if no server stats in unicast case; for multicast,
520+
* server stats are not expected.
521+
*/
522+
if (!rate_in_kbps && !results->is_multicast) {
520523
shell_fprintf(sh, SHELL_ERROR,
521524
"LAST PACKET NOT RECEIVED!!!\n");
522525
}
523526

524-
shell_fprintf(sh, SHELL_NORMAL,
525-
"Statistics:\t\tserver\t(client)\n");
526-
shell_fprintf(sh, SHELL_NORMAL, "Duration:\t\t");
527-
print_number_64(sh, results->time_in_us, TIME_US,
528-
TIME_US_UNIT);
529-
shell_fprintf(sh, SHELL_NORMAL, "\t(");
530-
print_number_64(sh, results->client_time_in_us, TIME_US,
531-
TIME_US_UNIT);
532-
shell_fprintf(sh, SHELL_NORMAL, ")\n");
533-
534-
shell_fprintf(sh, SHELL_NORMAL, "Num packets:\t\t%u\t(%u)\n",
535-
results->nb_packets_rcvd,
536-
results->nb_packets_sent);
537-
538-
shell_fprintf(sh, SHELL_NORMAL,
539-
"Num packets out order:\t%u\n",
540-
results->nb_packets_outorder);
541-
shell_fprintf(sh, SHELL_NORMAL, "Num packets lost:\t%u\n",
542-
results->nb_packets_lost);
543-
544-
shell_fprintf(sh, SHELL_NORMAL, "Jitter:\t\t\t");
545-
print_number(sh, results->jitter_in_us, TIME_US,
546-
TIME_US_UNIT);
547-
shell_fprintf(sh, SHELL_NORMAL, "\n");
527+
if (results->is_multicast) {
528+
shell_fprintf(sh, SHELL_NORMAL, "Statistics (client only)\n");
529+
shell_fprintf(sh, SHELL_NORMAL, "Duration:\t\t");
530+
print_number_64(sh, results->client_time_in_us, TIME_US, TIME_US_UNIT);
531+
shell_fprintf(sh, SHELL_NORMAL, "\n");
532+
shell_fprintf(sh, SHELL_NORMAL, "Num packets:\t\t%u\n",
533+
results->nb_packets_sent);
534+
shell_fprintf(sh, SHELL_NORMAL, "Rate:\t\t\t");
535+
print_number(sh, client_rate_in_kbps, KBPS, KBPS_UNIT);
536+
shell_fprintf(sh, SHELL_NORMAL, "\n");
537+
} else {
538+
shell_fprintf(sh, SHELL_NORMAL,
539+
"Statistics:\t\tserver\t(client)\n");
540+
shell_fprintf(sh, SHELL_NORMAL, "Duration:\t\t");
541+
print_number_64(sh, results->time_in_us, TIME_US,
542+
TIME_US_UNIT);
543+
shell_fprintf(sh, SHELL_NORMAL, "\t(");
544+
print_number_64(sh, results->client_time_in_us, TIME_US,
545+
TIME_US_UNIT);
546+
shell_fprintf(sh, SHELL_NORMAL, ")\n");
547+
548+
shell_fprintf(sh, SHELL_NORMAL, "Num packets:\t\t%u\t(%u)\n",
549+
results->nb_packets_rcvd,
550+
results->nb_packets_sent);
548551

549-
shell_fprintf(sh, SHELL_NORMAL, "Rate:\t\t\t");
550-
print_number(sh, rate_in_kbps, KBPS, KBPS_UNIT);
551-
shell_fprintf(sh, SHELL_NORMAL, "\t(");
552-
print_number(sh, client_rate_in_kbps, KBPS, KBPS_UNIT);
553-
shell_fprintf(sh, SHELL_NORMAL, ")\n");
552+
shell_fprintf(sh, SHELL_NORMAL,
553+
"Num packets out order:\t%u\n",
554+
results->nb_packets_outorder);
555+
shell_fprintf(sh, SHELL_NORMAL, "Num packets lost:\t%u\n",
556+
results->nb_packets_lost);
557+
558+
shell_fprintf(sh, SHELL_NORMAL, "Jitter:\t\t\t");
559+
print_number(sh, results->jitter_in_us, TIME_US,
560+
TIME_US_UNIT);
561+
shell_fprintf(sh, SHELL_NORMAL, "\n");
562+
563+
shell_fprintf(sh, SHELL_NORMAL, "Rate:\t\t\t");
564+
print_number(sh, rate_in_kbps, KBPS, KBPS_UNIT);
565+
shell_fprintf(sh, SHELL_NORMAL, "\t(");
566+
print_number(sh, client_rate_in_kbps, KBPS, KBPS_UNIT);
567+
shell_fprintf(sh, SHELL_NORMAL, ")\n");
568+
}
554569

555570
#ifdef CONFIG_ZPERF_SESSION_PER_THREAD
556571
if (is_async) {

subsys/net/lib/zperf/zperf_udp_uploader.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,14 @@ static inline int zperf_upload_fin(int sock,
105105
continue;
106106
}
107107

108-
/* Multicast only send the negative sequence number packet
109-
* and doesn't wait for a server ack
108+
/* For multicast, do not wait for a server ack. Keep resending FIN
109+
* for the configured number of attempts by forcing another loop
110+
* iteration.
110111
*/
111-
if (!is_mcast_pkt) {
112+
if (is_mcast_pkt) {
113+
ret = 0;
114+
continue;
115+
} else {
112116
/* Receive statistics */
113117
ret = zsock_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &rcvtimeo,
114118
sizeof(rcvtimeo));
@@ -126,6 +130,11 @@ static inline int zperf_upload_fin(int sock,
126130
}
127131
}
128132

133+
/* In multicast, we never expect a stats reply. Stop here. */
134+
if (is_mcast_pkt) {
135+
return 0;
136+
}
137+
129138
/* Decode statistics */
130139
if (ret > 0) {
131140
zperf_upload_decode_stat(stats, ret, results);
@@ -299,6 +308,7 @@ static int udp_upload(int sock, int port,
299308
results->client_time_in_us =
300309
k_ticks_to_us_ceil64(end_time - start_time);
301310
results->packet_size = packet_size;
311+
results->is_multicast = is_mcast_pkt;
302312

303313
return 0;
304314
}

0 commit comments

Comments
 (0)