3

my Linux skills are rudimentary at best, but I am trying to learn. So please be considerate of that fact, considering this question. I have a laptop that I have installed Debian Buster on. I need to bridge my ethernet and wifi adapters together.

I have read many tutorials, and they all say much the same thing as described in this post. How do I configure a network interface bridge from WiFi to Ethernet with Debian?, however, this post makes the point that

" The wlan0 interface also has to be configured to connect to your remote AP ",

so I have tried to improvise, below is my configuration, needless to say {ssid} and {password} are substituted for real values

auto enp0s31f6
allow-hotplug enp0s31f6
iface enp0s31f6 inet manual

auto wlp4s0
allow-hotplug wlp4s0
iface wlp4s0 inet manual
                wpa-ssid {ssid}
                wpa-psk  {password}

auto br0
iface br0 inet static
bridge_ports enp0s31f6 wlp4s0
address 10.0.10.8
netmask 255.255.255.0
gateway 10.0.10.1
dns-domain prox
dns-nameservers 8.8.8.8

So this kind of works!!! In that, the ethernet side works but not the Wifi, so if I lose Ethernet, I lose connection to the internet, defeating the purpose of this activity. Is there something obvious I am doing wrong here? Do I need to connect the wireless interface to the wireless network using some other method?

If I were to use this configuration for the wireless connection, I could connect to the wireless network, but this won't obviously work with a bridge.

allow-hotplug wlp4s0
iface wlp4s0 inet static
                wpa-ssid {ssid}
                wpa-psk  {password}
 address 10.0.10.8
 netmask 255.255.255.0
 gateway 10.0.10.1
 dns-domain prox
 dns-nameservers 8.8.8.8 

Your assistance is greatly appreciated; I have spent the best part of a week trying to get this to work, I'm almost at the point of giving up.

###UPDATE###

Thanks @dirkt for the response, that kind of makes sense, so perhaps I can explain the underlying issues a little more clearly; I am using an application that imposes a bridge on the network adapters before it will allow you to use it.

The application will then use the bridge to communicate with the network. I only really need one network adapter to work with the bridge. I would prefer it to be the wifi adapter as I don't have much in the way of Ethernet in my house (where I am using this setup).

So even if I attempt to just bridge the wifi adapter and not worry about the Ethernet side, it will not work. It tries to work (i.e I'm not getting any errors), but it will not issue an IP address to the bridge.

Before you ask, the application is a proprietary audio application for the professional audio industry. I don't know why the manufacturer decided that this was the best way of doing things, but it doesn't seem all that uncommon from my reading. I believe some virtualisation platforms do the same thing, as this software is in part virtualisation. Perhaps that's the reason.

So given the above, if I am only using the wifi adapter as a one-sided bridge. Will this still not work? Will this resolve the cannot bridge a Wifi client and Ethernet issue? Or am I misunderstanding what you mean by that?

Fitzs Tech
  • 31
  • 4
  • It may be wifi driver issue. Did you restart your network "service networking restart" and install the bridge utilities "apt install bridge-utils"? – Cinaed Simson Jun 21 '21 at 04:26
  • In case of doubt just compare `ip -br link` before running the application and while the application is running and communicating over the network. – A.B Jun 25 '21 at 16:42
  • @A.B i have done as you sugested, in fact I have gone one step further. I had a spare machine so I installed Debian on that as well and without installing the app on i tried to bridge the Ethernet and the Wlan.. it dosnt work. so this dosnt apear to be anything to do with the app, its a Debian issue. – Fitzs Tech Jul 02 '21 at 04:50
  • @A.B, my humble apologies, I was about to go on a much needed vacation, I did do as you asked, but forgot to provide the results, so sorry for that. here are the results. When I issues the command ip -br link without the app running I get the following result lo UNKNOWN 00:00:00:00:00:00 enp0s25 UP 68:f7:28:ab:94:3c wlp3s0 DOWN 10:02:b5:e5:fa:0b When I issue ip -br link show type bridge_slave without the app running I get no results. – Fitzs Tech Jul 12 '21 at 00:20
  • @A.B When I issues ip -br link WITH the application running I get lo UNKNOWN 00:00:00:00:00:00 enp0s25 UP 68:f7:28:ab:94:3c wlp3s0 DOWN 10:02:b5:e5:fa:0b vmbr0 UP 68:f7:28:ab:94:3c When I issues ip -br link show type bridge_slave WITH the application running I get enp0s25 UP 68:f7:28:ab:94:3c – Fitzs Tech Jul 12 '21 at 00:21

2 Answers2

3

I need to bridge my ethernet and wifi adapters together.

That's a FAQ: Wifi uses something called 3-address-mode by default, and a consequence of that is that you cannot bridge a Wifi client and Ethernet.

(Well, technically, you can, but it will not work: Packets from the Wifi network will not reach destinations on the Ethernet, even though they are bridged and in the same subnet. If you write "it kind of works", you probably have not tested this case).

However, you can bridge a Wifi Access Point (AP) and Ethernet.

So, this is an XY question: Your Y is "I need to bridge Wifi and LAN on Debian Buster", but we do not know what your X is (maybe: I have Wifi and LAN at home, and I'd like them to be in the same subnet?).

And depending on what your X is, there are other ways to achieve this, for example, you can bridge the Wifi AP and LAN in your router.

dirkt
  • 31,679
  • 3
  • 40
  • 73
2

Preliminary explanations

As @dirkt already wrote, the bridging limitation is here to enforce that the network stack won't attempt (and fail) to send frames with different source MAC addresses through the wireless interface. The details about this limitation can be found in this NE SE Q/A: Four layer-2 addresses in 802.11 frame header. Despite the link's title only 3 MACs are used by default and that's the Access Point ("AP") that gets the use of the 3rd one to act as a bridge, not the Station Client ("STA") considered as simple endpoint without the absent 4th. Switching to 4-addr mode ("4A") allowing to bridge the STA too requires reconfiguring the AP to support 4A. For example hostapd can support serving both normal STAs as usual and 4A mode STAs differently by creating an additional local cloned wireless interface in 4A mode for each such STA, which must be configured adequately with its bridge. Most public customer APs don't support this (unless running a reconfigurable hostapd under the hood and adequate Wifi hardware/firmware).

In OP's specific case, an additional condition exists: the bridge uses a single bridge port, so one could arguably suppose only one source MAC address will come from the bridge. The limitation inherent to the protocol doesn't apply in this case if the bridge is configured with the MAC address of the wireless card, but there's no way to tell the network stack to allow to set the wireless interface as bridge port for such specific case. If one just wanted an other interface (not bridge port) behaving like this, then IPVLAN would be the easiest option to choose instead.

So using Traffic Control features, a work-around functionally equivalent to a hub will be used:

  • take all frames incoming to the wireless interface and move them to appear incoming to a mirrored interface
  • take all frames outgoing from this mirrored interface and move them on the wireless interface, ready to be outgoing (as radio waves).
  • configure the network stack to use the mirrored interface instead of the wireless interface, or here use this mirrored interface('s veth peer) as a bridge port to reproduce having the wireless interface set as bridge port.

This virtual "hub"'s other port will then be connected to the actual bridge as bridge port in OP's case. The kernel won't have have to forbid this since technically it's not the wireless interface that is set as bridge port and there's thus no specific restriction.

Note: I used a veth pair of interfaces. Using a dummy interface works too but I chose instead a veth pair of interfaces for two reasons and a bonus reason:

  • older iproute2/kernel versions of tc ... action mirred were not able to redirect to ingress but only to egress. A veth pair of interfaces acts as a direction inverter: egress on one side becomes ingress on the other side, so this answer can also work on older systems.

  • the way the network stack works (schematic there), this would make AF_PACKET (tcpdump) captures asymmetrical: as ingress happens after AF_PACKET cloning, tcpdump wouldn't see ingress traffic redirected as ingress on the mirror interface while it would see on both interfaces egress which happens before AF_PACKET. This answer preserves the usual behavior: both directions are seen, both on the wireless interface and on its mirror interface (as well as its veth peer interface which isn't actually involved).

  • bonus reason: nftables only got egress support in kernels 5.16/5.17 which might still not be available. Likewise it can't choose freely the direction of the moved frame. With veth acting as direction inverter all conditions are met: requires only from ingress to egress making it also possible to replace Traffic Control with nftables.

The mirror interface (or for the veth implementation here, the other side of the mirror interface) could receive directly an IP address (including using DHCP), but it will be used instead as bridge port to (hopefully) solve OP's problem: the application wants a bridge.

Preparation

I'll waive some details that will have to be addressed by OP:

  • setup shouldn't be done remotely, because temporary loss of network connectivity is to be expected.

  • OP will have to reconfigure Wifi to only connect to the SSID and not request any IP address (no IPv4 nor IPv6), DNS or other custom setting: this part is now for the bridge interface. The configuration should always keep the same MAC address on the wireless interface be it the original permanent or an other one like 12:34:56:78:9a:bc in this answer (no random mode).

  • integration into system configuration will have to be done by OP: only manual setup is provided here. Bridge will have actual connectivity only after wireless gets connectivity so should probably not be brought up uselessly too early. Usual configuration is now set on the bridge (including for example running a DHCP client) instead of the wireless interface.

  • the kernel module br_netfilter should not be loaded. If it's currently loaded, to avoid any side effects do rmmod br_netfilter (because Docker breaks libvirt bridge network and many bridge setups).

So let's define the example configuration before changes. The only relevant information is the wireless interface name wlp3s0and its MAC address, in this example: 12:34:56:78:9a:bc.

# ip link show dev wlp3s0
3: wlp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
    link/ether 12:34:56:78:9a:bc brd ff:ff:ff:ff:ff:ff

Steps

  • reconfigure Wifi with one's preferred network configuration tool to connect and not request any address for IPv4 or IPv6.

    Up to OP for doing this

  • create a bridge interface vmbr0 with the same MAC address as wlp3s0 and disable special features (to avoid generating unexpected traffic)

    ip link add name vmbr0 address 12:34:56:78:9a:bc type bridge stp_state 0 forward_delay 0 mcast_snooping 0 mcast_router 0
    

    or if it was already created change its settings with:

    ip link set dev vmbr0 down
    ip link set dev vmbr0 address 12:34:56:78:9a:bc type bridge stp_state 0 forward_delay 0 mcast_snooping 0 mcast_router 0
    
  • create a veth interface vmbr0p1 set as the unique bridge port of vmbr0 and have the same MAC address too with its peer link named wlp3s0mirred (whose MAC address doesn't matter).

    ip link add name vmbr0p1 address 12:34:56:78:9a:bc master vmbr0 type veth peer name wlp3s0mirred
    
  • reconfigure wlp3s0 and vmbr0p1/wlp3s0mirred to not generate their own traffic like IPv6 SLAAC: those 3 interfaces are now bridge ports (or functionally equivalent to bridge ports).

    sysctl -w net.ipv6.conf.vmbr0p1.disable_ipv6=1
    sysctl -w net.ipv6.conf.wlp3s0mirred.disable_ipv6=1
    sysctl -w net.ipv6.conf.wlp3s0.disable_ipv6=1 #1st bullet should already have done this one
    

    Just to be thorough (optional):

    ip link set dev wlp3s0 arp off
    ip link set dev wlp3s0mirred arp off
    ip link set dev vmbr0p1 arp off # this one is probably already forced by being a bridge port.
    

Interfaces must already exist before the next batch of commands.

  • Redirect traffic

    • redirect wlp3s0mirred's ingress to wlp3s0's egress

      • using TC

        tc qdisc add dev wlp3s0mirred ingress
        tc filter add dev wlp3s0mirred ingress matchall action mirred egress redirect dev wlp3s0
        
      • instead of above, using nftables

        nft add table netdev hijack
        nft add chain netdev hijack towireless '{ type filter hook ingress device wlp3s0mirred priority 0; policy accept; }'
        nft add rule netdev hijack towireless fwd to wlp3s0  
        
    • redirect wlp3s0's ingress to wlp3s0mirred's egress

      ⚠️ There's a catch: WPA relies on EAPOL Ethernet frames type 0x888E. As we are hijacking frames and the authentication daemon (wpa_supplicant) can't be told to read them on the bridge since it can't be told to use successfully a bridge, it's still looking for the EAPOL frames on wlp3s0. An exception has to be added first to leave these frames on wlp3s0 for wpa_supplicant's consumption. Else even if there was an initial successful association, the next rekeying done with only the last filter in place without the exception below would fail (and then no further reassociation would be successful). It would look like the wireless interface constantly connects and disconnects.

      • using TC

        tc qdisc add dev wlp3s0 ingress
        tc filter add dev wlp3s0 ingress pref 1 protocol 0x888e matchall action pass
        tc filter add dev wlp3s0 ingress pref 2 matchall action mirred egress redirect dev wlp3s0mirred
        
      • instead of above, using nftables

        nft add table netdev hijack # already done but doesn't fail to write it again
        nft add chain netdev hijack fromwireless '{ type filter hook ingress device wlp3s0 priority 0; policy accept; }'
        nft add rule netdev hijack fromwireless ether type 0x888e accept
        nft add rule netdev hijack fromwireless fwd to wlp3s0mirred
        
  • set all interfaces up

    ip link set dev vmbr0p1 up
    ip link set dev wlp3s0mirred up
    ip link set dev vmbr0 up
    

This answer allows one thing: that the bridge can be the main interface on the system and can be used to exchange normal traffic over Wifi connectivity the same way it would be used over Ethernet connectivity.

What it doesn't guarantee is that it will make a proprietary application requiring a bridge to work, to actually work: it really depends on why it requires a bridge. If generating any abnormal traffic (that would use a different source MAC address) is the reason, chances are this still won't work.

A.B
  • 31,762
  • 2
  • 62
  • 101
  • 1
    Wow man.. this is a lot of detail thank you so very very much.. I have just tried this and all the commands are successful but there are two issues (minor ones I’m sure), the first issue is that it doesn’t appear that in all of these commands that there is a process to set the IP address. Or do I do that in the /etc/network/interfaces file? Second, how do I make these changes persistent? I completed the process and then when I rebooted the machine, all the settings went back to how they where originally. Thanks again for you help. I really do appreciate this – Fitzs Tech Jul 16 '21 at 16:32
  • easiest to set the IP address in an usual environment, manually: `dhclient -v vmbr0`. – A.B Jul 16 '21 at 21:34
  • You should add these commands as pre-up and up commands in the interfaces file. Some of them might require a ` || :` to allow them to fail (usually because already done). And when possible they should be grouped in a script. For the IP either dhcp method, or as you did static method. On the vmbr0 bridge interface. Use bridge options (probably bridge_port none + up ip link set ... master ...) – A.B Jul 16 '21 at 21:36
  • thank you, I will see if I can figure out how to do that, my linux skills are at best redimentary. but I apreciate you have done the heavy lifting and I will try walk the last mile. thanks again – Fitzs Tech Jul 18 '21 at 00:04
  • This sorta tries to work but really doesn’t. I’m fumbling in the dark here, so I could be doing something really daft when you look at it. So what’s happening is, it’s building everything but not bringing vmbr0p1, wlp3s0mirred or vmbr0. The machine is able to be reached by the IP address on vmbr0 but only if the interface enp0s25 also is configured with an IP address. It like as if Deb is deciding on its own to rout traffic to the ethernet port. here is my configurations (the names and dates have been changed to protect the innocent) https://github.com/tonyfitzs/debian-bridge.git – Fitzs Tech Jul 19 '21 at 04:03
  • Why are you involving enp0s25? It should not appear at all in any configuration anymore: no address either. – A.B Jul 19 '21 at 07:59
  • You set an address (using dhcp) in the same LAN on enp0s25 this makes everything else fail. – A.B Jul 19 '21 at 08:05
  • Again: forget ALL configuration files. Have it working *once* by hand as a preliminary condition. You are supposed to know how to assign an IP address on an interface and add a default route, or run dhclient on an interface. – A.B Jul 19 '21 at 08:07
  • thanks @A.B, as I have stated a number of times, I am not very familure with Linux, the only way I know how to set an IP address on a device is in the Interfaces file. and I did ask before, how to set the IP address without using the interfaces file, i should not the test machine I am using to see if I can get this working is bare Debian with no gui. so if you can share with me the command line to set an ip before setting up a configuration, I am more than happy to use it.... Oh and by the way, if I coment out the ethernet port or removed it completly, I am not able to connect to the PC. – Fitzs Tech Jul 23 '21 at 01:37