Bridging Wifi to Ethernet on Ubuntu not working

When running Windows I was able to bridge my wifi connect through my laptops Ethernet connection so a range of ethernet only devices could piggy back off my wifi (Raspberry Pi, Xbox etc etc). I am now trying to do the same within Ubuntu, i.e the set up would be:

Wireless Router ---> Wifi on laptop ---> bridge to Ethernet ---> Device that needs internet plugged into Ethernet port

Now I have been trying to get this working in Ubuntu using brctl

I used the below command:

sudo brctl addif br0 eth0 wlan0

And get the following error:

can't add wlan0 to bridge br0: Operation not supported

I am hoping someone can help as I refuse to believe something I can do in windows very easily can't be done in Linux.

If you need any more info do let me know. Thanks


Solution 1:

This cannot be done. You cannot bridge a WiFi client connection. If you could, we wouldn't need WDS, we'd just bridge.

The problem is very simple -- an access point is prohibited by the WiFi specifaction from broadcasting traffic over the WiFi network unless something authorizes that transmission. This is largely a relic from the days when WiFi networks were very slow and had poor, if any, security.

The bridge only has a client connection to the access point. This only authorizes the access point to transmit traffic bound for the bridge. Because any machines connected to the bridge are not clients of the access point, the access point has no reason to send traffic bound for them over the WiFi link. So it will not do so.

Unfortunately, WiFi is enough like Ethernet that it's easy to expect it to act like Ethernet. But it's just different enough to bite you.

WDS configuration is a specific authorization for an access point to send traffic not bound for any of its clients. When both ends support WDS, they include the address of the bridging endpoint as well as the address of the destination, authorizing the access point to send the traffic.

You have to use something other than bridging to do this. Routing with NAT, for example. You can also use four address mode, if both ends of the WiFi link support it.

Solution 2:

I had a similar problem with LXC, I worked around the bridging issue in wifi devices. First you need a spare ethernet device in the computer. The trick is to create a route from the ethernet device to the wifi.

In the server file, change /etc/network/interfaces, pick an unused network for your virtual hosts, i.e. 10.0.0.0. Assign one IP to your spare ethernet interface, here it is eth0, bridging it like this:

auto br0
iface br0 inet static
    address 10.0.0.1
    netmask 255.255.255.0
    bridge_ports eth0
    bridge_fd 0
    bridge_maxwait 0

Once it is done you can go the MASQUERADE way as answered by Kostyantyn here before. Those should be in rc.local or in a script that you must run on boot-up or before starting the virtual domains:

# iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
# echo "1" > /proc/sys/net/ipv4/ip_forward

In the virtual server configure static IPs in /etc/network/interfaces. I am using network 10.0.0.0, I will start using from .2 , when you create more virtual hosts you probably will use 3, and so on. If you have many you can consider installing a dhcp server for those. The .1 is the gateway, as configured before.

auto eth0
iface eth0 inet static
    address 10.0.0.2
    netmask 255.255.255.0
    broadcast 10.0.0.255
    gateway 10.0.0.1

Configure also a DNS server, mine was the network router, in /etc/resolv.conf:

nameserver 192.168.1.1

Hope this helps