1
1

Support setting the IPv6 flow label on Linux systems (only).

This functionality uses some setsockopt(2) calls that unfortunately
don't seem to have an analog on other platforms.

Slightly tweaked version of a patch that was...

Submitted by:	ssahani@redhat.com
Issue:		40 (Option for setting Flow Label field in IPv6
		header)
Этот коммит содержится в:
Bruce A. Mah 2013-12-12 09:21:36 -08:00
родитель c8a0a2229d
Коммит d04c7bd0a4
4 изменённых файлов: 42 добавлений и 10 удалений

Просмотреть файл

@ -109,9 +109,9 @@ only use IPv6
.TP
.BR -S ", " --tos " \fIn\fR"
set the IP 'type of service'
.\" .TP
.\" .BR -L ", " --flowlabel " \fIn\fR"
.\" set the IPv6 'flow label'
.TP
.BR -L ", " --flowlabel " \fIn\fR"
set the IPv6 flow label (currently only supported on Linux)
.TP
.BR -Z ", " --zerocopy " "
Use a "zero copy" method of sending data, such as sendfile(2),

Просмотреть файл

@ -655,17 +655,17 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
client_flag = 1;
break;
case 'L':
#ifdef notdef
#if defined(linux)
test->settings->flowlabel = strtol(optarg, NULL, 0);
if (test->settings->flowlabel < 1 || test->settings->flowlabel > 0xfffff) {
i_errno = IESETFLOW;
return -1;
}
client_flag = 1;
#else /* notdef */
i_errno = IEUNIMP;
return -1;
#endif /* notdef */
#else /* linux */
i_errno = IEUNIMP;
return -1;
#endif /* linux */
break;
case 'Z':
if (!has_sendfile()) {

Просмотреть файл

@ -25,6 +25,9 @@
#include "iperf_tcp.h"
#include "net.h"
#if defined(linux)
#include "flowlabel.h"
#endif
/* iperf_tcp_recv
*
@ -291,6 +294,7 @@ iperf_tcp_connect(struct iperf_test *test)
return -1;
}
}
#if defined(linux)
if (test->settings->flowlabel) {
if (server_res->ai_addr->sa_family != AF_INET6) {
close(s);
@ -299,9 +303,35 @@ iperf_tcp_connect(struct iperf_test *test)
return -1;
} else {
struct sockaddr_in6* sa6P = (struct sockaddr_in6*) server_res->ai_addr;
sa6P->sin6_flowinfo = htonl(test->settings->flowlabel);
char freq_buf[sizeof(struct in6_flowlabel_req)];
struct in6_flowlabel_req *freq = (struct in6_flowlabel_req *)freq_buf;
int freq_len = sizeof(*freq);
memset(freq, 0, sizeof(*freq));
freq->flr_label = htonl(test->settings->flowlabel & IPV6_FLOWINFO_FLOWLABEL);
freq->flr_action = IPV6_FL_A_GET;
freq->flr_flags = IPV6_FL_F_CREATE;
freq->flr_share = IPV6_FL_F_CREATE | IPV6_FL_S_EXCL;
memcpy(&freq->flr_dst, &sa6P->sin6_addr, 16);
if (setsockopt(s, IPPROTO_IPV6, IPV6_FLOWLABEL_MGR, freq, freq_len) < 0) {
close(s);
freeaddrinfo(server_res);
i_errno = IESETFLOW;
return -1;
}
sa6P->sin6_flowinfo = freq->flr_label;
opt = 1;
if (setsockopt(s, IPPROTO_IPV6, IPV6_FLOWINFO_SEND, &opt, sizeof(opt)) < 0) {
close(s);
freeaddrinfo(server_res);
i_errno = IESETFLOW;
return -1;
}
}
}
#endif
if (connect(s, (struct sockaddr *) server_res->ai_addr, server_res->ai_addrlen) < 0 && errno != EINPROGRESS) {
close(s);

Просмотреть файл

@ -99,7 +99,9 @@ const char usage_longstr[] = "Usage: iperf [-s|-c host] [options]\n"
" -4, --version4 only use IPv4\n"
" -6, --version6 only use IPv6\n"
" -S, --tos N set the IP 'type of service'\n"
/* " -L, --flowlabel N set the IPv6 'flow label'\n" */
#if defined(linux)
" -L, --flowlabel N set the IPv6 flow label (only supported on Linux)\n"
#endif
" -Z, --zerocopy use a 'zero copy' method of sending data\n"
" -O, --omit N omit the first n seconds\n"
" -T, --title str prefix every output line with this string\n"