在 tun 接口上注入的 IPv6 数据包将进入 IPv4 堆栈

在 tun 接口上注入的 IPv6 数据包将进入 IPv4 堆栈

我对 tun 接口和内核处理 IPv6 有疑问。

我正在尝试通过纯 IPv4 网络向网络的最终用户提供 IPv6。总结一下(只是隧道背景理论)所有 IPv6 数据包都放入 IPv4 数据包中并通过隧道发送,当出去时,此 IPv4 标头将被删除并传递到系统。

我模拟这一切的场景如下:

  • 我只有一台机器,有两个 IPv4 虚拟接口,用于在两者之间发送隧道流量。我们称它们为“if4a”和“if4b”。这些接口是管理接口的子接口。
  • 该机器还有两个 IPv6 tun 接口,用于屏蔽最终用户的 IPv6 地址。我们称它们为“if6a”和“if6b”。每个 tun 接口都附加了一个手工程序,用于在将数据包写入隧道或从隧道读取数据包之前放置/删除我需要的标头(GTP)(带有 fd00:fea:2001::1 地址的 if4a 和带有 fd00:fea:2002 地址的 if4b: :1 地址)。
  • 我有两个未在任何地方定义的 IPv6 地址,实际上是最终用户地址(fd00:cafe:2001::1 代表 if6a 的用户,fd00:cafe:2002::1 代表 if6b 网络的用户)。
  • 路由表配置为将最终用户流量发送到“if6a”或“if6b”(tun 接口)。
  • 有一个 NAT 配置,它通过“cafe”地址更改“fea”IPv6 地址,以避免数据包直接传递到目标 if6x 接口,并强制 IPv6 流量通过 tun 接口,因此我的 GTP 处理程序。

问题是:

  • 我通过 if6a 从 fd00:fea:2001::1 向 fd00:cafe:2002::1 发送 ICMPv6。
  • NAT 后路由链通过 fd00:cafe:2001::1 更改源地址
  • 监听 if6a 的程序读取 ICMPv6,添加 GTP 标头并将其发送到 if4b(使用 IPv4)
  • 封装到 GTP 中的 IPv6 数据包具有以下地址:从 fd00:cafe:2001::1 到 fd00:cafe:2002::1
  • 服务器接收数据包,删除 GTP 标头并将其(IPv6 数据包)注入到 if6b 接口上。
  • 这是 tshark 嗅探数据包并打印跟踪的地方
  • NAT 预路由链通过 fd00:fea:2002::1 更改目标地址并向上访问堆栈 IP。
  • 该数据包被丢弃,因为它进入的是 IPv4 堆栈而不是 IPv6 堆栈。

一些痕迹:

  • 沙克:

 

[root@vm062 ~]# tshark -i if6b`
 Running as user "root" and group "root". This could be dangerous
 Capturing on 'if6b'
 1   0.000000 fd00:cafe:2001::1 -> fd00:cafe:2002::1 ICMPv6 104 Echo
 (ping) request id=0x7383, seq=1, hop limit=0
 1   2   0.785373 fd00:cafe:2001::1 -> fd00:cafe:2002::1 ICMPv6 104
 Echo (ping) request id=0x7383, seq=2, hop limit=0
 2   3   1.782000 fd00:cafe:2001::1 -> fd00:cafe:2002::1 ICMPv6 104
 Echo (ping) request id=0x7383, seq=3, hop limit=0
 3   4   2.781968 fd00:cafe:2001::1 -> fd00:cafe:2002::1 ICMPv6 104
 Echo (ping) request id=0x7383, seq=4, hop limit=0...
  • 丢弃的数据包,如 dropwatch 显示:

 

 [ipv6test@vm062 ssh]$ echo start | dropwatch -l kas
 Initalizing kallsyms db
 dropwatch> start
 Enabling monitoring...
 Kernel monitoring activated.
 Issue Ctrl-C to stop monitoring
 1 drops at ip_rcv+c0 (0xffffffff81536450)
 2 drops at ip_rcv+c0 (0xffffffff81536450)
 1 drops at ip_rcv+c0 (0xffffffff81536450)
 2 drops at ip_rcv+c0 (0xffffffff81536450)
 2 drops at ip_rcv+c0 (0xffffffff81536450)
 2 drops at ip_rcv+c0 (0xffffffff81536450)
 2 drops at ip_rcv+c0 (0xffffffff81536450)
 ...

如果我停止 ping6,则 ping6 也会停止。

我一直在研究ip_rcv 函数并且仅适用于 IPv4 数据包,因此我认为我的 IPv6 数据包是通过 IPv4 堆栈而不是 IPv6 堆栈进入的。内核为什么要这样做?

有一个类似的问题这里

相关内容