Setting up a bridge with nmcli

I’ve decided to invest this weekend into making friend with KVM.
So far we like each other, I’m past OS installation (Win11).
Now I’m attempting to establish an internet connection. I’m following this guide; I found it more straightforward than netctl or brctl, but it could be the opposite.

Anyway, I went from 1 to 5 to add the bridge named (bridge-kvmbr) , slave interface and turned it on.

nmcli con up bridge-kvmbr 
Connection successfully activated (controller waiting for ports) (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/23)  
nmcli con show                                                                                                                                         1 ✘ 
NAME                 UUID                                  TYPE      DEVICE 
Gs2u                 b4cef3e4-5b6f-4976-8b1d-f5718e023db3  wifi      wlp5s0 
bridge-kvmbr         5ece3556-4590-46ee-988a-c4f5c204c170  bridge    kvmbr  
bridge-virbr0        8e372d58-ba08-4716-bc24-447efaa10a32  bridge    virbr0 
lo                   95009d48-7afe-4a82-a814-2f08e543fba6  loopback  lo     
bridge-slave-wlp5s0  adfaa1f2-b173-408c-b126-f76c9bcaa9ed  ethernet  -- 
ip link                                                                                                                                           ✔  3s  
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp7s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000
    link/ether 50:eb:f6:79:c3:98 brd ff:ff:ff:ff:ff:ff
    altname enx50ebf679c398
3: wlp5s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
    link/ether 2e:22:d9:f4:4d:48 brd ff:ff:ff:ff:ff:ff
    altname wlx44e51706dd5d
18: kvmbr: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000
    link/ether de:ee:fd:f3:7d:98 brd ff:ff:ff:ff:ff:ff

I then moved on How to use br0 with KVM section. Created the xml and got stuck here

net-start bridge-kvmbr
error: failed to get network 'bridge-kvmbr'
error: Network not found: no network with matching name 'bridge-kvmbr'

It seems I am missing something

The device to connect to is not called bridge-kvmbr — it’s simply kvmbr.

I’ve tried also with

virsh net-start kvmbr       
error: failed to get network 'kvmbr'
error: Network not found: no network with matching name 'kvmbr'
1 Like

What if you try connecting to the slave instead?

(Disclaimer: I don’t have any experience with bridging.)

Same.

I will investigate more in the coming days.
Alternatively I will try to follow this other guide with seemingly more information required to input in the setting up process. I would have followed it if nor for the confusing interface labels

eno1 tap0 br10

Thanks though

To configure KVM brigde, it’s easier using nmtui than nmcli. Take a look here:

I’ve been using bridges for decades, 5 years on this Manjaro install. (Mostly for virtualisation.)

The first guide seems more accurate..

I even saved the steps I used to bridge my enp8s0 (a 2.5 Gb Ethernet interface). br0 is the name I chose, and it’s what I pass to libvirt and everything else.

nmcli connection add type bridge ifname br0 stp no
nmcli connection add type bridge-slave ifname enp8s0 master br0
nmcli connection down "Wired connection 1"
nmcli connection up bridge-br0

bridge-br0 is the NetworkManager connection name for the br0 interface. I think NM assigned it, but I’m not 100%; just check nmcli conn show at that point.

I needed to keep my MAC address so I also did this, through the interactive nmcli ui:

nmcli connection edit
  nmcli> set 802-3-ethernet.cloned-mac-address 00:11:22:33:44:55
  nmcli> save persistent

Here’s a (culled) output of my ip a..

2: enp8s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP group default qlen 1000
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether d8:5e:d3:04:13:f7 brd ff:ff:ff:ff:ff:ff
    inet 10.2.4.10/24 brd 10.2.4.255 scope global dynamic noprefixroute br0
5: nat0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc htb state DOWN group default qlen 1000
    link/ether 52:54:00:93:41:bf brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global nat0
  • enp8s0 - As I said, host LAN interface
  • br0 - My bridged interface, with my DHCP assigned address (from my LAN)
  • nat0 - NAT VM network, nothing to do with this
2 Likes

My notes say this:

Create bridge called br0

sudo nmcli connection add type bridge con-name br0 ifname br0

sudo nmcli connection add type ethernet slave-type bridge con-name ‘bridge con 1’ ifname enp8s0 master br0

sudo nmcli connection modify br0 connection.autoconnect-slaves 1

sudo nmcli connection up br0

IIRC, con-name can be anything you want. And remember to change ifname on that line to your NIC. “ip r” or “ip a” to see what it could be. I like “ip r” because it is a shorter list when you have a bunch of Docker containers. dev(ice) enp8s0 in this case.

I reason I used ip a, is to be clear that br0 is essentially my old eth0. With no IP attached to my old network interface.

Thanks. Had seen it, I kept in store in case of WCS.

Thanks @Molski and @zhongsiu,

I think I got these first two steps right

nmcli con add type bridge ifname kvmbr 
nmcli con add type bridge-slave ifname wlp5s0  master bridge-kvmbr

@Molski if I have to follow your example when I add the bridge I should not have typed bridge before kvmbr, like this

nmcli con add type bridge-slave ifname wlp5s0  master kvmbr

but it seems not making any difference, regardless whether I type bridge-kvmbr or just kvmbr (I deleted and added it again, it does not change) the outcome is still

bridge-slave-wlp5s0  adfaa1f2-b173-408c-b126-f76c9bcaa9ed  ethernet  -- 

so

nmcli con show 
bridge-kvmbr         5ece3556-4590-46ee-988a-c4f5c204c170  bridge    kvmbr 
bridge-slave-wlp5s0  adfaa1f2-b173-408c-b126-f76c9bcaa9ed  ethernet  -- 

Now, my active internet interface is wlp5s0,

nmcli con show 
Gs2u                 b4cef3e4-5b6f-4976-8b1d-f5718e023db3  wifi      wlp5s0 

ip link
3: wlp5s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
    link/ether 2e:22:d9:f4:4d:48 brd ff:ff:ff:ff:ff:ff

next step would be sending the data from wlp5s0 to the bridge. Here is bit which is not clear.

@Molski and @zhongsiu your procedures end differently which one you suggest me to follow? I’d say mine is closer to @Molski

:right_arrow: wlp5s0

Nothing said that up to this point, I just assumed this one:

You are trying to bridge wifi? This only works for Ethernet. To make a “wifi bridge” there is some fancy firewall routing you have to do, though it’s not truly a “bridge”.

2 Likes

If they’re calling it a bridge to a wifi network, that’s misleading. True bridging happens at Layer 2, and standard wifi client mode generally doesn’t support that.

That said, there are ways to achieve similar results using routing, plus a few tricks to make it feel like a bridge (for most common use cases).

So it sounds like your options are:

  • ARP proxy – this was my go-to for years. Many older routers (like the classic Linksys WRT routers) used this approach to fake bridging to wifi.
  • macvtap – a more modern method designed for VMs. It lets a VM attach directly to a host interface (like wlp5s0) without using a bridge, but a virtual adapter piggybacking off another

The latter sounds perfect for what you want to do. (I did whole networks with the former.)

With Ethernet, both approaches work cleanly. On wifi, you’ll often see disclaimers because support depends on the adapter and driver; some work, some don’t.

I haven’t used VirtualBox in a long time, but from what I can tell, it uses its own in-house approach for MAC rewriting, ARP handling, and filtering.

So you can still get it done with qemu/libvirt, but you would (most likely) want to setup macvtap to work with your wifi adapter first.

2 Likes

Thanks @Molski, sounds I have to roll my sleeves.
Right now I am not able to get the NAT work either, that is why I chose to work on the bridge right away (since Virtual Box makes it so easy). But I will open a different thread on that.

No problem. I wire everything I can, for reasons like this, but so much more. Especially for a hypervisor. I would lay a throw rugs over cables (cringe) before using wireless! :laughing:

That makes a true bridge really easy to setup, and VMs love it. But you need Ethernet.

That must be a newer feature to Virtualbox, but nothing that will make me switch. :grin:

macvtap does seem fairly straightforward to set up.

I haven’t tested it myself yet, but the basic idea is:

ip link add link wlp5s0 name macvtap0 type macvtap mode bridge
ip link set macvtap0 up

From there, you don’t use macvtap0 directly; instead, qemu uses the character device under /dev/tapX. You can find it with:

ls -l /dev/tap*

Then pass the correct /dev/tapX device to your VM.


Your NAT will should almost certainly be easy to fix. It’s often this one thing.

And there are no wifi woes there! :partying_face:

But yes, best start another post.

1 Like

I agree with you. Unfortunately the place I am now in I have only mobile hotspot access via wifi.

I’ve been checking a few online resources and all have very different ways to set up macvtap a few tackle the configuration via a .xml file. Is it another way of doing what you suggest via terminal? Very confusing :slightly_smiling_face:

As for your indications, I lost you already at

ls -l /dev/tap*

gives

ls -l /dev/tap*                                                                                                                                        2 ✘ 
crw------- 1 root root 510, 1 31 mar 13.50 /dev/tap6

Which means somehow here?

I noticed the libvirt support for macvtap, but I wasn’t entirely clear on how it worked in conjunction. (I have no use for macvtap myself.)

I was mainly trying to point out that it looks fairly simple, even when doing it manually.

I did forget you would have to give qemu rw permissions to /dev/tapX. But ignore that!


After reading a bit more, that part isn’t really something you need to worry about. The libvirt way (or going through Virtual Machine Manager), does make this much easier.

Just fill in wlp5s0 for Device name:

It should all just work as expected. Just as easy as your Virtualbox. :smile:

In the background a macvtap0@wlp5s0 (or whatever prefix it picks) interface should be created, and it will handle the permissions to the /dev/tunX device for you.

But you noticed the warning/disclaimer. It was in my reading about it as well. That no guest to host communication over this interface is possible! That is a pretty awful stipulation. :confused:

The good news is having NAT connected to this as well, is one workaround.

Which I see you started another post on.

1 Like

Not working, but I really like your optimism, makes me think I am a step away from making it work which probably is :rofl:

How about the field Device model?
The three options are:

  • e1000e - seen by Windows as Intel(R) 82574L Gigabit Network Connection
  • Hypervisor default - seen by Realtek RTL8139C+ Fast Ethernet NIC
  • virtio - seen by Red Hat VirtIO Ethernet Adapter

Could it be I need the Windows drivers for any of these?
These three options are the same even by selecting NAT and same is Windows response to any of them: it takes some time on identifying the network and after a while it gives up.

Use virtio almost always. If running a Linux guest, the driver (modules) needed comes with modern kernels. Other OSs, like Windows, you would need to install virtio drivers to make it work. These come in ISO format as well, so you can mount them as a CD device to install them. (As you have no network.)

You can find them linked here:

The other choices just emulate those chipsets for compatibility, virtio should be better performing..

I would have to break out a laptop and install qemu to test this myself, as I don’t have wifi on my desktop, where I run my VMs.

Are there any logs where it’s stopping you? Is it when you try to set the value, or launch the VM? Or it launches, but no network?


The second most common problem is dnsmasq not installed or correctly configured. It’s how your guests get IPs and resolve hostnames.

To my knowledge, it comes pre-configured and working. I just remember a couple old posts fixing it.

(And this would all be easier to troubleshoot in Linux. :smile: )

Okay, I had installed it previously as is needed also for sharing folders. It explains why it sees it correctly (Red Hat VirtIO Ethernet Adapter)

It launches just fine. It stats with identifying... the first minute and than it gives no internet
Mac address is the same as that given by in virt-manager.
It seems the traffic is somehow being interrupted somewhere.

Now that the NAT issue is sorted let’s see if I can figure out this too.
So, I set up again the interface

and

But it seems not working

Now gives

ls -l /dev/tap*                                                                                                                                          ✔ 
crw------- 1 root root 510, 1  2 apr 18.57 /dev/tap12
crw------- 1 root root 510, 2  2 apr 18.58 /dev/tap13