Skip to content

Commit

Permalink
enh: Add support for SO_PRIORITY socket option.
Browse files Browse the repository at this point in the history
This functionality is needed to test mutliqueue support of Ethernet
drivers.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
  • Loading branch information
olerem committed Feb 27, 2023
1 parent 8aaa205 commit dc82c5e
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 2 deletions.
10 changes: 9 additions & 1 deletion docs/invoking.rst
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,15 @@ the executable.
-S, --tos n
set the IP type of service. The usual prefixes for octal and hex
can be used, i.e. 52, 064 and 0x34 all specify the same value.

-sock-prio n
Set the protocol-defined priority for all packets to be sent
on this socket. Linux uses this value to order the networking
queues: packets with a higher priority may be processed first
depending on the selected device queueing discipline. Setting
a priority outside the range 0 to 6 requires the CAP_NET_ADMIN
capability

--dscp dscp
set the IP DSCP bits. Both numeric and symbolic values are
accepted. Numeric values can be specified in decimal, octal and
Expand Down
1 change: 1 addition & 0 deletions src/iperf.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ struct iperf_settings
int mss; /* for TCP MSS */
int ttl; /* IP TTL option */
int tos; /* type of service bit */
int sock_prio; /* protocol-defined priority */
int flowlabel; /* IPv6 flow label */
iperf_size_t bytes; /* number of bytes to send */
iperf_size_t blocks; /* number of blocks (packets) to send */
Expand Down
26 changes: 25 additions & 1 deletion src/iperf_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,7 @@ void
iperf_on_test_start(struct iperf_test *test)
{
if (test->json_output) {
cJSON_AddItemToObject(test->json_start, "test_start", iperf_json_printf("protocol: %s num_streams: %d blksize: %d omit: %d duration: %d bytes: %d blocks: %d reverse: %d tos: %d target_bitrate: %d bidir: %d fqrate: %d", test->protocol->name, (int64_t) test->num_streams, (int64_t) test->settings->blksize, (int64_t) test->omit, (int64_t) test->duration, (int64_t) test->settings->bytes, (int64_t) test->settings->blocks, test->reverse?(int64_t)1:(int64_t)0, (int64_t) test->settings->tos, (int64_t) test->settings->rate, (int64_t) test->bidirectional, (uint64_t) test->settings->fqrate));
cJSON_AddItemToObject(test->json_start, "test_start", iperf_json_printf("protocol: %s num_streams: %d blksize: %d omit: %d duration: %d bytes: %d blocks: %d reverse: %d tos: %d target_bitrate: %d bidir: %d fqrate: %d sock_prio: %d", test->protocol->name, (int64_t) test->num_streams, (int64_t) test->settings->blksize, (int64_t) test->omit, (int64_t) test->duration, (int64_t) test->settings->bytes, (int64_t) test->settings->blocks, test->reverse?(int64_t)1:(int64_t)0, (int64_t) test->settings->tos, (int64_t) test->settings->rate, (int64_t) test->bidirectional, (uint64_t) test->settings->fqrate, (int64_t) test->settings->sock_prio));
} else {
if (test->verbose) {
if (test->settings->bytes)
Expand Down Expand Up @@ -1059,6 +1059,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
{"version4", no_argument, NULL, '4'},
{"version6", no_argument, NULL, '6'},
{"tos", required_argument, NULL, 'S'},
{"sock-prio", required_argument, NULL, OPT_SOCK_PRIO},
{"dscp", required_argument, NULL, OPT_DSCP},
{"extra-data", required_argument, NULL, OPT_EXTRA_DATA},
#if defined(HAVE_FLOWLABEL)
Expand Down Expand Up @@ -1380,6 +1381,16 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
}
client_flag = 1;
break;
case OPT_SOCK_PRIO:
test->settings->sock_prio = strtol(optarg, &endptr, 0);
if (endptr == optarg ||
test->settings->sock_prio < 0 ||
test->settings->sock_prio > 15) {
i_errno = IEBADSOPRIO;
return -1;
}
client_flag = 1;
break;
case OPT_DSCP:
test->settings->tos = parse_qos(optarg);
if(test->settings->tos < 0) {
Expand Down Expand Up @@ -2178,6 +2189,8 @@ send_parameters(struct iperf_test *test)
cJSON_AddNumberToObject(j, "burst", test->settings->burst);
if (test->settings->tos)
cJSON_AddNumberToObject(j, "TOS", test->settings->tos);
if (test->settings->sock_prio)
cJSON_AddNumberToObject(j, "SOCK_PRIO", test->settings->sock_prio);
if (test->settings->flowlabel)
cJSON_AddNumberToObject(j, "flowlabel", test->settings->flowlabel);
if (test->title)
Expand Down Expand Up @@ -2294,6 +2307,8 @@ get_parameters(struct iperf_test *test)
test->settings->burst = j_p->valueint;
if ((j_p = cJSON_GetObjectItem(j, "TOS")) != NULL)
test->settings->tos = j_p->valueint;
if ((j_p = cJSON_GetObjectItem(j, "SOCK_PRIO")) != NULL)
test->settings->sock_prio = j_p->valueint;
if ((j_p = cJSON_GetObjectItem(j, "flowlabel")) != NULL)
test->settings->flowlabel = j_p->valueint;
if ((j_p = cJSON_GetObjectItem(j, "title")) != NULL)
Expand Down Expand Up @@ -3117,6 +3132,7 @@ iperf_reset_test(struct iperf_test *test)
test->settings->burst = 0;
test->settings->mss = 0;
test->settings->tos = 0;
test->settings->sock_prio = 0;
test->settings->dont_fragment = 0;
test->zerocopy = 0;

Expand Down Expand Up @@ -4352,6 +4368,14 @@ iperf_common_sockopts(struct iperf_test *test, int s)
}
}
}

if ((opt = test->settings->sock_prio)) {
if (setsockopt(s, SOL_SOCKET, SO_PRIORITY, &opt, sizeof(opt)) < 0) {
i_errno = IESETSOPRIO;
return -1;
}
}

return 0;
}

Expand Down
3 changes: 3 additions & 0 deletions src/iperf_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ typedef uint64_t iperf_size_t;
#define OPT_DONT_FRAGMENT 26
#define OPT_RCV_TIMEOUT 27
#define OPT_SND_TIMEOUT 28
#define OPT_SOCK_PRIO 29

/* states */
#define TEST_START 1
Expand Down Expand Up @@ -401,6 +402,7 @@ enum {
IERCVTIMEOUT = 31, // Illegal message receive timeout
IERVRSONLYRCVTIMEOUT = 32, // Client receive timeout is valid only in reverse mode
IESNDTIMEOUT = 33, // Illegal message send timeout
IEBADSOPRIO = 34, // Bad socket priority value
/* Test errors */
IENEWTEST = 100, // Unable to create a new test (check perror)
IEINITTEST = 101, // Test initialization failed (check perror)
Expand Down Expand Up @@ -451,6 +453,7 @@ enum {
IEBINDDEVNOSUPPORT = 146, // `ip%%dev` is not supported as system does not support bind to device
IEHOSTDEV = 147, // host device name (ip%%<dev>) is supported (and required) only for IPv6 link-local address
IESETUSERTIMEOUT = 148, // Unable to set TCP USER_TIMEOUT (check perror)
IESETSOPRIO = 149, // Unable to set socket priority (check perror)
/* Stream errors */
IECREATESTREAM = 200, // Unable to create a new stream (check herror/perror)
IEINITSTREAM = 201, // Unable to initialize stream (check herror/perror)
Expand Down

0 comments on commit dc82c5e

Please sign in to comment.