Linux – How to blindly forward all packets from one interface to another

gatewaylinux

I would like to forward all L3 packets received on eth0 to another interface lets call m0 (m0 is a custom interface tied into custom hardware with a distinct L2 framing mechanism) as well as the reverse m0->eth0. A sample implementation for m0 could be a SLIP interface for example. I want to achieve this using userspace tools preferably.

The tricky part is I don't want to route. I don't care what the source or destination ipv4 addresses are, and I don't care what the MAC addresses are either. I just want to blindly grab everything from interface 0 and shovel it over interface 1 (and vice versa) without modifying the L3 packets.

I know that everything (in this use case) coming in over eth0 is ipv4 UDP packets that fit in the Ethernet mtu 1500, no fragments. Additionally, it needs to work with multicast addressed packets.

I'm worried that the only way to achieve this is with custom software that is camping on the interface(s) in promiscuous mode. I would like to avoid this because it would be hard to avoid entering a scenario where I loop packets back to their origin.

For example,

  1. Poll eth0 and m0 to see if data is received
  2. packet A received at eth0
  3. packet A captured at eth0 and sent to m0
  4. packet A received at m0
    1. packet A has already been dealt with but how does the software know that? I would have to keep some sort of table of previously handled packets… nasty.

As far as setting it up in Linux, all the research I have done has led me to using combinations of the following, but I don't think they are appropriate in this use case:

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

Achievable with Static Routing

Verified the interfaces are all working and it isn't a hardware problem by setting static routes and confirming bidirectional messaging. I'm starting to think it simply isn't achievable.

PC0 can now directly connect to PC1; tested with:

    ping 192.168.2.110 -t 10

Received response from PC1 through the radios.

network map:

                              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

PC0:

        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

unit111:

        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

unit112:

        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

PC1:

        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

Application Context

This is for a radio that has its own L2/L1 used for RF transmission. It is guaranteed placement in a system at the edge of a network and the only packets it receives over its Ethernet interface are to go out over RF. The interface to the L2 used in the RF chain is a DMA that I built a network interface for (m0) because I thought it would simplify connecting it to the Ethernet interface. All of the L2/L1 used for M0 is an FPGA implementation shuffling packets over the m0 DMA.

From the point of view of systems sending/receiving packets from the radio, the radio is basically supposed to look like a wire; packet in, packet out.

Transmit Chain:

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

Receive chain:

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

The radio is full duplex, it should be able to perform the transmit and receive simultaneously. That is get packets from the Ethernet and transmits them over rf as well as receive packets over rf and send them back out to the Ethernet.

I can place and recover packets into the RF chain using normal socket code through m0 no problem. I just can't figure out how to forward all traffic between the interfaces without touching the packets or opening the interfaces in promiscuous and doing it manually in C code (which as described earlier has its own bag of worms).

Best Answer

Edit: Forgot that detail "no bridging", but the second article should do the trick as requested, providing the layer 3 solution that can connect different network types such as ethernet and wireless LANs.

Original Answer:

I've done a little search using the phrase "linux kernel interface passthrough", which led me to a few articles on debian.org that seem to provide exactly the answer that you are looking for, so no further fancy explanation here as I don't have anything sensible to add. Note that the second article especially deals with bridging a wired network to a wireless network, dealing with potential problems related to Access Point security.

The software related to in the articles would normally be available in the current Debian repositories.

Article 1: "Bridging Network Connections" at https://wiki.debian.org/BridgeNetworkConnections

Article 2: "Bridging Network Connections with Proxy ARP" at https://wiki.debian.org/BridgeNetworkConnectionsProxyArp (Layer 3 Bridge)

I hope this provides a sensible way forward as I might get a headache if rewriting the given advice (which wouldn't add any value anyway).

Related Question