为什么 Linux TAP 设备不处理 ARP 或 ICMPv6 数据包

发布于 2024-12-15 03:38:54 字数 2496 浏览 2 评论 0原文

我正在使用TAP设备打开

p->fd = open("/dev/net/tun", O_RDWR);

// skipping error handling code

ifr.ifr_flags = IFF_TAP | IFF_ONE_QUEUE | IFF_NO_PI;
strncpy(ifr.ifr_name, p->name, IFNAMSIZ-1);
result = ioctl(p->fd, TUNSETIFF, &ifr);

// skipping error handling and setting ipv4 address & netmask code

ifr.ifr_flags = (IFF_UP | IFF_RUNNING);
result = ioctl(dummySock, SIOCSIFFLAGS, &ifr);

我面临的问题是当应用程序(例如mozilla)想要通过tap设备发送数据包时,它需要获取dst mac地址。于是内核发出了一个ARP请求。我正在编写的应用程序转发 arp 请求(通过物理 eth 设备上的原始套接字)并获取 arp 回复。这个arp回复被转发回tap设备,但是内核拒绝接受这个。如果我手动添加 arp 条目,则不会生成 arp 请求,并且有两种方式的 ip 数据包交换(mozilla 很高兴)。

Wireshark 能够接收数据包并且没有发现任何错误。 ICMPv6 数据包(邻居请求和通告)的情况也是如此。设备上侦听的任何应用程序都会完整地获取数据包。但内核不对其进行 ARP/ICMP 处理。

我的问题是,为什么内核不接受 arp 回复/ICMPv6 消息?我们需要调用一些 ioctl 调用吗?

编辑:

这是在tap设备“ethgress”捕获的数据包的详细信息(tshark输出)

  9  16.548328    fc00:1::2 -> ff02::1:ff00:1 ICMPv6 86 Neighbor Solicitation
 10  17.243247  fc00:1::100 -> fc00:1::2    ICMPv6 86 Neighbor Advertisement
 11  17.548652    fc00:1::2 -> ff02::1:ff00:1 ICMPv6 86 Neighbor Solicitation
 12  17.668736  fc00:1::100 -> fc00:1::2    ICMPv6 86 Neighbor Advertisement

这是“ethgress”的ifconfig输出

ethgress  Link encap:Ethernet  HWaddr 00:01:02:03:04:05
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:83 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10000
          RX bytes:0 (0.0 b)  TX bytes:7062 (6.8 KiB)

可以看出,内核拒绝接受ICMPv6数据包收到时。但 tx 数据包会增加。

Tap 设备“ethgress”配置有 IPv6 地址 fc00:1::2,应用程序希望与 fc00:1::1 进行通信。 fc00:1::1 与 fc00:1:100 位于同一接口,后者使用正确的 MAC 地址响应邻居通告(目标 IP 是该数据包中的 fc00:1::1)。 Tcpdump 能够捕获它,wireshark/tshark 能够解码它,并表示它是一个正确形成的数据包。但 Rx 计数器不会由内核递增,也不会更新其 arp 缓存。 ARP 数据包的情况也是如此。

编辑 2:

网络如下所示。有两个外部盒被配置为冗余。只有其中之一会处于活动状态。它们分别通过物理网卡连接到一台电脑。我正在编写的应用程序在这台电脑上运行,并在每个网卡上打开一个原始套接字。它还会打开 TAP 设备。 NIC 未配置 IP 地址。 TAP 设备配置有 IPv4 和 IPv6 地址。一个标准应用程序,比如 mozilla,通过 Tap 设备打开一个套接字,并希望连接到活动盒。为此,内核在 Tap 设备上生成 ARP 请求/邻居请求消息。应用程序读取此消息并将其转发到两个 NIC。活动框使用 ARP 回复来响应 ARP 请求,应用程序将其读取并将其写入 TAP 设备。这个arp回复数据包被tcpdump捕获,但内核不会更新其arp缓存。两个 NIC 和 TAP 设备的 MAC 地址相同。

要求的其他参数。

cat /proc/sys/net/ipv4/conf/all/log_martians
0
cat /proc/sys/net/ipv4/conf/all/rp_filter
1
cat /proc/sys/net/ipv4/conf/all/arp_filter
0

I am opening a TAP device using

p->fd = open("/dev/net/tun", O_RDWR);

// skipping error handling code

ifr.ifr_flags = IFF_TAP | IFF_ONE_QUEUE | IFF_NO_PI;
strncpy(ifr.ifr_name, p->name, IFNAMSIZ-1);
result = ioctl(p->fd, TUNSETIFF, &ifr);

// skipping error handling and setting ipv4 address & netmask code

ifr.ifr_flags = (IFF_UP | IFF_RUNNING);
result = ioctl(dummySock, SIOCSIFFLAGS, &ifr);

The problem I am facing is when an application (say mozilla) wants to send out a packet via the tap device, it needs to get the dst mac address. So the kernel sends out an ARP request. The application I am writing forwards the arp request (via a raw socket on a physical eth device) and gets an arp reply. This arp reply is forwarded back to the tap device, but the kernel refuses to accept this. If I add an arp entry manually, no arp request is generated and there is two way ip packet exchange (mozilla is happy).

Wireshark is able to receive the packet and finds no errors. Same is the case with ICMPv6 packets (neighbor solicitation & advertisement). Any application listening on the device gets the packet intact. But the kernel does not process it for ARP/ICMP.

My question is, why doesn't the kernel accept the arp reply/ICMPv6 msgs? Is there some ioctl call that we need to call?

Edit:

Here is the details of packet captured (tshark output) at the tap device "ethgress"

  9  16.548328    fc00:1::2 -> ff02::1:ff00:1 ICMPv6 86 Neighbor Solicitation
 10  17.243247  fc00:1::100 -> fc00:1::2    ICMPv6 86 Neighbor Advertisement
 11  17.548652    fc00:1::2 -> ff02::1:ff00:1 ICMPv6 86 Neighbor Solicitation
 12  17.668736  fc00:1::100 -> fc00:1::2    ICMPv6 86 Neighbor Advertisement

This is the ifconfig output for "ethgress"

ethgress  Link encap:Ethernet  HWaddr 00:01:02:03:04:05
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:83 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10000
          RX bytes:0 (0.0 b)  TX bytes:7062 (6.8 KiB)

As can be seen, the kernel is refusing the accept the ICMPv6 packets as received. But the tx packets are incremented.

The tap device "ethgress" is configured with IPv6 address fc00:1::2 and it an application wants to communicate to fc00:1::1. fc00:1::1 is at the same interface as fc00:1:100 which is responding with the neighbor advertisement (the target ip is fc00:1::1 in that packet) with proper mac address. Tcpdump is able to capture it and wireshark/tshark is able to decode it without and says its a properly formed packet. But Rx counters are not incremented by the kernel, nor does it update its arp cache. Same is the case with ARP packets.

Edit 2:

The network looks like this. There are two external boxes which are configured to be redundant. Only one of them will be active. They are connected to a pc via a physical NIC each. The application I am writing runs on this pc and opens a raw socket on each of the NICs. It also opens a TAP device. The NICs are not configured with an IP address. The TAP device is configured with both IPv4 and IPv6 address. A standard application, say mozilla, opens a socket via the tap device and wants to connect to the active box. For that the kernel generates an ARP request/Neighbor solicitation message on the tap device. The application reads this message and forwards it to both the NICs. The active box responds to the ARP request with an ARP reply which the application reads and writes it to the TAP device. This arp reply packet is captured by tcpdump, but the kernel doesn't update its arp cache. The mac address of both NICs and the TAP device are the same.

Other parameters asked for.

cat /proc/sys/net/ipv4/conf/all/log_martians
0
cat /proc/sys/net/ipv4/conf/all/rp_filter
1
cat /proc/sys/net/ipv4/conf/all/arp_filter
0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花开浅夏 2024-12-22 03:38:54

这个问题现在已经很老了。

(您还可以了解 TUN 和 TAP 设备之间的区别 https://security.stackexchange.com /questions/46442/openvpn-tap-vs-tun-mode

如果您的设备确实是包含 ARP、硬件寻址等的 TAP 设备:
您的流量转储不包括以太网帧。这些 ARP 和 ICMPv6 数据包的两个重要详细信息是 HW dst 和 src 地址。 RP 过滤器是其中的一部分,但可能不允许所有可能的组合通过。

对于TUN设备:应该不需要ARP等,该设备是“盲”IP设备

This question is very old now.

(You also have the difference between TUN and TAP devices https://security.stackexchange.com/questions/46442/openvpn-tap-vs-tun-mode )

If your device is indeed a TAP device that includes ARP, hardware addressing etc:
Your traffic-dump does not include the ethernet frame. Two important details for these ARP and ICMPv6 packets are the HW dst and src addresses. The RP filter is a part of this, but probably does not allow ALL possible combinations to pass.

For a TUN device: there should be no need for ARP etc, this device is "blind" IP device

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文