communication between two hosts using socktap and UDP
razr opened this issue · 9 comments
I'd like to establish a UDP
connection between docker and host both running socktap
This works
# Docker
sudo ./socktap -i eth0 --print-tx-cam
# Host
sudo ./socktap -i docker0 --print-rx-cam
This does not work
# Docker
./socktap -l udp -i eth0 --print-tx
# Host
./socktap -l udp -i docker0 --print-rx
However, I see on the receiver side the messages coming from the transmitter:
# Host
sudo tcpdump -nvvvXi docker0 net 239.118.122.97
tcpdump: listening on docker0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
17:46:01.890966 IP (tos 0x0, ttl 1, id 9917, offset 0, flags [DF], proto UDP (17), length 215)
172.17.0.2.52764 > 239.118.122.97.8947: [bad udp cksum 0x16c0 -> 0x6c56!] UDP, length 187
0x0000: 4500 00d7 26bd 4000 0111 3c6e ac11 0002 E...&.@...<n....
0x0010: ef76 7a61 ce1c 22f3 00c3 16c0 ffff ffff .vza..".........
0x0020: ffff 0242 ac11 0002 8947 1200 1a01 0210 ...B.....G......
0x0030: 0000 0235 8409 5436 ff02 0000 0024 8000 ...5..T6.....$..
0x0040: 0151 2050 0080 002d 0100 8000 0242 ac11 .Q.P...-.....B..
0x0050: 0002 c5a4 2e22 1d11 3b88 06d0 6527 8000 ....."..;...e'..
0x0060: 0000 0000 0000 07d1 0000 0202 0000 0001 ................
0x0070: 2e22 005a 56c4 918e 4346 e4ff ffff fc23 .".ZV...CF.....#
0x0080: b774 3e00 0001 2000 003f e1ed 0403 ffe3 .t>......?......
0x0090: fff4 0043 0100 0000 0000 0000 0000 0000 ...C............
0x00a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x00b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x00c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x00d0: 0000 0000 0000 00 .......
I suppose the low-level Ethernet frames in the former case are not filtered and thus receivable by the host. For the UDP-based link layer, we use IP multicast. Possibly some further configuration is required to forward multicast traffic from/to Docker containers?
Maybe binding UDP multicast to the specific IP helps
Hi @riebl
I got on the receiver side the multicast packages from 172.17.0.2
to 239.118.122.97.8947
and wondering whether the command I'm using for the UDP communication on the receiver side (./socktap -l udp -i docker0 --print-rx
) is correct.
I couldn't find any example apart for the lo
interface
./socktap -l udp --mac-address 00:00:00:00:00:01 --print-rx
Hi @razr,
socktap has no --print-rx
flag but only --print-rx-cam
. Apart from that, your invocation of socktap looks sane.
The IP address 239.118.122.97 is the multicast IP address used for the UDP link layer (see
vanetza/tools/socktap/link_layer.cpp
Line 66 in fc6d69e
I have no experience with multicast and docker, but these modifications in udp_link.cpp should work, when more network interaces are present. IP address of the device specified with -i parameter is stored in std::string ip.
You can give it a try if you want.
tx_socket_.open(multicast_endpoint_.protocol());
if(ip.size() != 0){
//select proper tx interface for udp in case there are more
boost::asio::ip::address_v4 local_interface = boost::asio::ip::address_v4::from_string(ip);
boost::asio::ip::multicast::outbound_interface option(local_interface);
tx_socket_.set_option(option);
}
rx_socket_.open(multicast_endpoint_.protocol());
rx_socket_.set_option(ip::udp::socket::reuse_address(true));
rx_socket_.bind(multicast_endpoint_);
rx_socket_.set_option(ip::multicast::enable_loopback(false));
if(ip.size() != 0){
//select rx interface for udp in case there are more
boost::asio::ip::address_v4 local_interface = boost::asio::ip::address_v4::from_string(ip);
rx_socket_.set_option(ip::multicast::join_group(multicast_endpoint_.address().to_v4(), local_interface));
}else{
rx_socket_.set_option(ip::multicast::join_group(multicast_endpoint_.address()));
}
do_receive();
@riebl it looks like that socktap
accepts (allow_guessing) partial command line arguments, e.g.
./socktap --print-t
I'm not sure whether it is an expected behavior, this extra line forces strict options:
diff --git a/tools/socktap/main.cpp b/tools/socktap/main.cpp
index de61b871..40c3a4f6 100644
--- a/tools/socktap/main.cpp
+++ b/tools/socktap/main.cpp
@@ -48,6 +48,7 @@ int main(int argc, const char** argv)
po::command_line_parser(argc, argv)
.options(options)
.positional(positional_options)
+ .style(po::command_line_style::default_style & ~po::command_line_style::allow_guessing)
.run(),
vm
);
@valt2017 Thanks much for your reply. It is not docker-related, as you have mentioned it is about multiple network interfaces in the system. I have added a route on the host side:
sudo ip route add 239.118.122.97 dev docker0
After that socktap
works properly. However, I still do not understand why I need to pass -i
on the receiver side
# Docker
./bin/socktap -l udp --print-tx-cam
# Host
./bin/socktap -l udp -i docker0 --print-rx-cam
It looks like the interface
is used for the raw sockets only.
OK, I can try it during the weekend.