如何盲目地将所有数据包从一个接口转发到另一个接口?

gut*_*ead 7 linux gateway

我想将在 eth0 上接收到的所有 L3 数据包转发到另一个接口,让我们调用 m0(m0 是一个自定义接口,绑定到具有独特 L2 帧机制的自定义硬件)以及反向 m0->eth0。例如,m0 的示例实现可以是 SLIP 接口。我想最好使用用户空间工具来实现这一点。

棘手的部分是我不想路由。我不在乎源或目标 ipv4 地址是什么,也不在乎 MAC 地址是什么。我只想盲目地从接口 0 中抓取所有内容并将其铲到接口 1 上(反之亦然),而无需修改 L3 数据包。

我知道通过 eth0 传入的所有内容(在本用例中)都是适合以太网 mtu 1500 的 ipv4 UDP 数据包,没有碎片。此外,它需要处理多播寻址的数据包。

我担心实现这一目标的唯一方法是使用以混杂模式驻扎在界面上的自定义软件。我想避免这种情况,因为很难避免进入我将数据包循环回其来源的场景。

例如,

  1. 轮询 eth0 和 m0 以查看是否收到数据
  2. 在 eth0 收到的数据包 A
  3. 在 eth0 捕获并发送到 m0 的数据包 A
  4. 在 m0 接收到的数据包 A
    1. 数据包 A 已经被处理了,但是软件怎么知道呢?我将不得不保留某种以前处理过的数据包的表格......讨厌。

至于在 Linux 中的设置,我所做的所有研究都使我使用以下组合,但我认为它们不适合这个用例:

echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -A FORWARD -i eth0 -o m0 -j ACCEPT
iptables -A FORWARD -i m0 -o eth0 -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

可通过静态路由实现

通过设置静态路由和确认双向消息来验证接口都正常工作并且这不是硬件问题。我开始认为这根本无法实现。

PC0 现在可以直接连接到 PC1;测试:

    ping 192.168.2.110 -t 10
Run Code Online (Sandbox Code Playgroud)

通过无线电接收到来自 PC1 的响应。

网络图:

                              eth0               eth0
                          192.168.0.111      192.168.2.112
              PC0 --- eth --- unit111 --- rf --- unit112 --- eth --- PC1
        192.168.0.110     192.168.1.111      192.168.1.112       192.168.2.110
                               m0                 m0
Run Code Online (Sandbox Code Playgroud)

电脑0:

        IFPC=enx4865ee1495b5
        ip link set $IFPC up
        ip addr flush $IFPC
        ip addr add 192.168.0.110/24 dev $IFPC
        ip route add 192.168.1.0/24 via 192.168.0.111
        ip route add 192.168.2.0/24 via 192.168.0.111
Run Code Online (Sandbox Code Playgroud)

单元 111:

        ip link set eth0 up
        ip addr flush eth0
        ip addr add 192.168.0.111/24 dev eth0
        ip link set m0 up
        ip addr flush m0
        ip addr add 192.168.1.111/24 dev m0
        ip route add 192.168.2.0/24 via 192.168.1.111
        echo 1 > /proc/sys/net/ipv4/ip_forward
Run Code Online (Sandbox Code Playgroud)

单元112:

        ip link set eth0 up
        ip addr flush eth0
        ip addr add 192.168.2.112/24 dev eth0
        ip link set m0 up
        ip addr flush m0
        ip addr add 192.168.1.112/24 dev m0
        ip route add 192.168.0.0/24 via 192.168.1.112
        echo 1 > /proc/sys/net/ipv4/ip_forward
Run Code Online (Sandbox Code Playgroud)

电脑1:

        IFPC=enp0s31f6
        ip link set $IFPC up
        ip addr flush $IFPC
        ip addr add 192.168.2.110/24 dev $IFPC
        ip route add 192.168.1.0/24 via 192.168.2.112
        ip route add 192.168.0.0/24 via 192.168.2.112
Run Code Online (Sandbox Code Playgroud)

应用上下文

这适用于具有用于 RF 传输的自己的 L2/L1 的无线电。它被保证放置在网络边缘的系统中,并且它通过其以太网接口接收的唯一数据包是通过 RF 发出的。RF 链中使用的 L2 接口是一个 DMA,我为 (m0) 构建了一个网络接口,因为我认为它可以简化将其连接到以太网接口的过程。用于 M0 的所有 L2/L1 都是通过 m0 DMA 对数据包进行混洗的 FPGA 实现。

从系统发送/接收来自无线电的数据包的角度来看,无线电基本上应该看起来像一根电线;包进,包出。

传输链:

[eth rx frame]->[??forward to m0??]->[m0 places pkt in dma for l2 chain]->[frame (L2),mod,out to rf]

接收链:

[rf,demod,deframe(L2)]->[m0 rx pkt creates skb]->[??forward to eth0??]->[eth0 rx skb transmits ethernet frame]

无线电是全双工的,它应该能够同时进行发送和接收。即从以太网获取数据包并通过 rf 传输它们以及通过 rf 接收数据包并将它们发送回以太网。

我可以通过 m0 使用普通套接字代码将数据包放入和恢复到 RF 链中,没问题。我只是不知道如何在不接触数据包或混杂打开接口并在 C 代码中手动执行的情况下在接口之间转发所有流量(如前所述,它有自己的蠕虫包)。

小智 -2

echo 1 > /proc/sys/net/ipv4/ip_forward

iptables -A FORWARD -i wlan1 -o wlan0 -j ACCEPT
iptables -A FORWARD -i wlan0 -o wlan1 -m state --state ESTABLISHED,RELATED \
         -j ACCEPT
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
Run Code Online (Sandbox Code Playgroud)