-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bind to non-primary interface seems to not work #1099
Comments
I was referred to this new functionality from #865 (comment) |
Thanks for the bug report and hint. That behavior is...not what I would have expected. |
@bmah888 - Ha! Me neither, though I have to admit that I've already learned a lot about kernel networking in the past few weeks and I'm pretty far out of my element—though I promise I can try any patches or PRs and give as good of debugging information as possible :) |
I forgot to follow-up on this. I did some testing going from a Raspberry Pi 3 over its Ethernet and WiFi interfaces (on the same subnet) to a Mac Pro running Big Sur. I realize the problem is more generic than this, but the combination of a Raspberry Pi and a Mac is something that I happened to have available and could easily set up. The basic methodology was to set up the server on the Mac and run the client on the Pi, while doing an instance of tcpdump on the Pi's Ethernet interface. I varied the command-line arguments on the client, with different combinations of (none): See packets on eth0 (Ethernet), with local address 192.168.32.7 (Ethernet IPv4 address) Then I set (none): See packets on eth0 (Ethernet), with local address 192.168.32.7 (Ethernet IPv4 address) So far I haven't found a combination for this scenario where I can get all of the traffic to go over the WiFi interface (both directions). |
I can't seem to get this to work either unfortunately...
Don't have any firewalls set up yet, and eth0 is directly connected to eth1 (no switches, etc). Tried it in both directions. I tried arp_filter=1 as well as adding routes that point to the other interface's IP, but no luck. I do see the interface lights blink when it tries to connect to the server, but it just never connects. |
Looks like I found following patch worked on my Raspberry Pi 3: diff --git a/src/iperf_tcp.c b/src/iperf_tcp.c
index c78f4f5..98550f9 100644
--- a/src/iperf_tcp.c
+++ b/src/iperf_tcp.c
@@ -465,6 +465,21 @@ iperf_tcp_connect(struct iperf_test *test)
return -1;
}
}
+ if (test->bind_dev) {
+#if defined(HAVE_SO_BINDTODEVICE)
+ if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE,
+ test->bind_dev, IFNAMSIZ) < 0)
+#endif // HAVE_SO_BINDTODEVICE
+ {
+ saved_errno = errno;
+ close(s);
+ // freeaddrinfo(local_res);
+ freeaddrinfo(server_res);
+ errno = saved_errno;
+ i_errno = IESTREAMCONNECT; // XXX which error code should I use?
+ return -1;
+ }
+ }
/* Set socket options */
if (test->no_delay) { Do do mind test it yourself? Here's my test results, 10.0.0.110 is IP for wlan0, 10.0.0.130 is IP for eth0. 10.0.0.42 is a Linux host running Bind to $ ./iperf3 -c 10.0.0.42 --bind 10.0.0.110
Connecting to host 10.0.0.42, port 5201
[ 5] local 10.0.0.110 port 33989 connected to 10.0.0.42 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 11.2 MBytes 93.6 Mbits/sec 0 124 KBytes
[ 5] 1.00-2.00 sec 11.3 MBytes 94.9 Mbits/sec 0 156 KBytes
[ 5] 2.00-3.00 sec 11.4 MBytes 95.4 Mbits/sec 0 163 KBytes
[ 5] 3.00-4.00 sec 11.2 MBytes 93.8 Mbits/sec 0 171 KBytes
[ 5] 4.00-5.00 sec 11.2 MBytes 94.4 Mbits/sec 0 178 KBytes
[ 5] 5.00-6.00 sec 11.2 MBytes 94.4 Mbits/sec 0 178 KBytes
[ 5] 6.00-7.00 sec 11.2 MBytes 93.8 Mbits/sec 0 178 KBytes
[ 5] 7.00-8.00 sec 11.2 MBytes 94.4 Mbits/sec 0 178 KBytes
[ 5] 8.00-9.00 sec 11.2 MBytes 93.8 Mbits/sec 0 300 KBytes
[ 5] 9.00-10.00 sec 11.2 MBytes 93.8 Mbits/sec 0 300 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 112 MBytes 94.2 Mbits/sec 0 sender
[ 5] 0.00-10.02 sec 112 MBytes 93.6 Mbits/sec receiver
iperf Done. Also bind to
For the record, I also set $ ./iperf3 -c 10.0.0.42 --bind 10.0.0.110 -R
Connecting to host 10.0.0.42, port 5201
Reverse mode, remote host 10.0.0.42 is sending
[ 5] local 10.0.0.110 port 60643 connected to 10.0.0.42 port 5201
[ ID] Interval Transfer Bitrate
[ 5] 0.00-1.00 sec 6.82 MBytes 57.2 Mbits/sec
[ 5] 1.00-2.00 sec 6.75 MBytes 56.7 Mbits/sec
[ 5] 2.00-3.00 sec 6.99 MBytes 58.6 Mbits/sec
[ 5] 3.00-4.00 sec 6.96 MBytes 58.4 Mbits/sec
[ 5] 4.00-5.00 sec 6.80 MBytes 57.1 Mbits/sec
[ 5] 5.00-6.00 sec 6.92 MBytes 58.0 Mbits/sec
[ 5] 6.00-7.00 sec 6.92 MBytes 58.1 Mbits/sec
[ 5] 7.00-8.00 sec 6.81 MBytes 57.1 Mbits/sec
[ 5] 8.00-9.00 sec 6.68 MBytes 56.0 Mbits/sec
[ 5] 9.00-10.00 sec 6.61 MBytes 55.5 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.01 sec 71.8 MBytes 60.1 Mbits/sec 0 sender
[ 5] 0.00-10.00 sec 68.3 MBytes 57.3 Mbits/sec receiver
iperf Done. Bind to eth0's IP: $ ./iperf3 -c 10.0.0.42 --bind 10.0.0.130 -R
Connecting to host 10.0.0.42, port 5201
Reverse mode, remote host 10.0.0.42 is sending
[ 5] local 10.0.0.130 port 36959 connected to 10.0.0.42 port 5201
[ ID] Interval Transfer Bitrate
[ 5] 0.00-1.00 sec 11.3 MBytes 94.5 Mbits/sec
[ 5] 1.00-2.00 sec 11.2 MBytes 94.2 Mbits/sec
[ 5] 2.00-3.00 sec 11.2 MBytes 94.1 Mbits/sec
[ 5] 3.00-4.00 sec 11.2 MBytes 94.2 Mbits/sec
[ 5] 4.00-5.00 sec 11.2 MBytes 94.1 Mbits/sec
[ 5] 5.00-6.00 sec 11.2 MBytes 93.7 Mbits/sec
[ 5] 6.00-7.00 sec 11.3 MBytes 94.6 Mbits/sec
[ 5] 7.00-8.00 sec 11.2 MBytes 94.2 Mbits/sec
[ 5] 8.00-9.00 sec 11.2 MBytes 94.2 Mbits/sec
[ 5] 9.00-10.00 sec 11.2 MBytes 94.1 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.01 sec 113 MBytes 94.5 Mbits/sec 51 sender
[ 5] 0.00-10.00 sec 112 MBytes 94.2 Mbits/sec receiver
iperf Done. |
Thanks for the patch, I was able to get it to compile, but haven't had time to test it yet. Hopefully I should have some time to test on Friday. |
netdial() honors --bind-dev option but iperf_tcp_connect() doesn't, as a result, only the control socket is bound to the device, but not the data socket. Instead of duplicaing code from netdial to iperf_tcp_connect(), this fix extracts a common util function create_socket() from netdial() and let iperf_tcp_connect() call create_socket() to create a socket with optional bindings. Tested on Raspberry Pi 3 with eth0 and wlan0.
I send a better patch in #1153, which doesn't duplicate code. |
esnet#1153 From: Shuo Chen <chenshuo@chenshuo.com> Date: Thu, 27 May 2021 14:24:07 -0700 Subject: [PATCH] Fix --bind-dev options for TCP streams. (esnet#1099) netdial() honors --bind-dev option but iperf_tcp_connect() doesn't, as a result, only the control socket is bound to the device, but not the data socket. Instead of duplicaing code from netdial to iperf_tcp_connect(), this fix extracts a common util function create_socket() from netdial() and let iperf_tcp_connect() call create_socket() to create a socket with optional bindings. Tested on Raspberry Pi 3 with eth0 and wlan0. Signed-off-by: David Ahern <dsahern@gmail.com>
I built and tested this myself on a Jetson Nano with an Intel 8265NGW, and can confirm that binding works properly now |
esnet#1153 From: Shuo Chen <chenshuo@chenshuo.com> Date: Thu, 27 May 2021 14:24:07 -0700 Subject: [PATCH] Fix --bind-dev options for TCP streams. (esnet#1099) netdial() honors --bind-dev option but iperf_tcp_connect() doesn't, as a result, only the control socket is bound to the device, but not the data socket. Instead of duplicaing code from netdial to iperf_tcp_connect(), this fix extracts a common util function create_socket() from netdial() and let iperf_tcp_connect() call create_socket() to create a socket with optional bindings. Tested on Raspberry Pi 3 with eth0 and wlan0. Signed-off-by: David Ahern <dsahern@gmail.com>
Fix --bind-dev options for TCP streams. (#1099)
Context
Version of iperf3: master (2021-01-04 commit 21581a7).
Hardware: Raspberry Pi Compute Module 4 + IO Board + PCIe Intel AX200 interface
Operating system (and distribution, if any): Raspberry Pi OS 64-bit beta (Debian 10.3 base)
Other relevant information (for example, non-default compilers,
libraries, cross-compiling, etc.):
Compiled from source.
Bug Report
Background: My Pi has the following interfaces connected to the same network / subnet:
Basically,
eth0
at .120, andwlan0
at .169.eth0
is connected via wire to my 10 Gbps network (though it's a 1 Gbps device), and normally gets ~930 Mbps at the default packet size (1500 MTU).wlan0
is connected via WiFi to my WiFi 6 network, and normally gets 600-800 Mbps at the default packet size (1500 MTU). I can disable my onboard Ethernet port (either viasudo ip link set eth0 down
, or unplugging it) and get this benchmark result.My Mac is connected to my 10 Gbps network directly, and is not a limiting factor.
Using a command like:
I had expected this to bind the network traffic for the test to the
wlan0
interface/device directly, so the wired network connection would not affect my WiFi benchmarking.Running the above command results in the same performance as when testing via the wired connection:
See Background above
arp_filter=1
may be used to disable some of the Linux kernel's packet routing that seems to optimize for the fastest (or primary?) interface.Ideally it would be nice to make
iperf3
able to bind to a particular interface directly (e.g.--bind-dev wlan0
and it would take care of everything for me.The text was updated successfully, but these errors were encountered: