I've never tried to do what you are trying to do (forward two interfaces to one) until just now, but while I'd presume this isn't very unusual searching for an example proved mostly fruitless -- the few I did find simply did what you would do when routing one to another twice, using IP forwarding and masquerading. I'll describe that first, then another (IMO, probably better) method using a virtual bridge.
I'm not taking into account NetworkManager
or whatever master networking service you are using because I don't use them; you may want to delist all involved interfaces and just use the wpa_supplicant
service to initialize the wifi.
Using IP Forwarding
sysctl -w net.ipv4.ip_forward=1
iptables -D FORWARD -i iface1 -o iface0 -j ACCEPT
iptables -D FORWARD -i iface0 -o iface1 -j ACCEPT
iptables -D FORWARD -i iface2 -o iface0 -j ACCEPT
iptables -D FORWARD -i iface0 -o iface2 -j ACCEPT
iptables -t nat -I POSTROUTING -o iface0 -j MASQUERADE
Mapping that to your context, iface0
would be the uplink modem and iface[1,2]
would be the wifi and ethernet. I did not try this, but believe it will work (if not it should be immediately obvious).
It's important that the wifi and ethernet have two separate private address ranges assigned to them, which probably means you'll need two separate instance of dhcpd
running. This is different from the next approach. To do that manually:
ip link set iface1 up
ip addr add 10.10.1.1/24 dev iface1
ip link set iface2 up
ip addr add 10.10.2.1/24 dev iface2
Using a Software Bridge
The bonding driver looks similar to bridging, but while I haven't used the former I suspect the latter is more appropriate. I also think bridging is tidier than a pure iptables
method (eg., it should be do-able with only one dhcpd
instance). The approach would be to bridge the ethernet and the wifi:
brctl addbr inpbr
brctl addif inpbr iface1
brctl addif inpbr iface2
Assign inpbr
an address which will serve as the router for connecting clients:
ip addr add 10.100.0.1/24 dev inpbr
Use that to run dhcpd
on inpbr
, and forward/masquerade it to the modem as in the first method (but there will only be two FORWARD
rules, to connect inpbr
and iface0
).
I did try this with two Pi's I have connected via separate ethernet ports to my desktop, sans dhcpd
since they just use static addresses. These were already bridged, but normally they both use their own wifi for the internet (since they stay on 24/7 when I shut down the big box). I turned wifi off on one and set the default route to go through the desktop and viola, it worked, the Pi had internet access.
The potential complication I see here is hostapd
, which I presume you are using for the WLAN. With the first iptables
based approach, that shouldn't matter since it is just about IP addresses and hostapd
is a layer 2 beast. However, interfaces represent the whole stack and bridging them may (or may not) cause a problem there.
Note that before they are bridged the interfaces should not have any address assigned, they should just be raised (ip link set ___ up
). There will be only one subnet, the range assigned to inpbr
(meaning clients should be able to reach each other across the bridge, which I do not think will work with pure IP forwarding unless you add more masquerading).