Had to do this for some advanced networking with KVM, and couldn't figure out how to do it using the Nework Manager gui. Did find an article later that showed how to do it with nmtui, but it's so much easier to record what you did when using the cli.
In the examples below "eth0" is the name of my physical interface. By default on Ubuntu and most distributions that will almost certainly be different, for example: "eno1", "ens1", or "enp2s0".
To see what everything looks like before starting:
$ nmcli con show
I renamed "Wired Connection 1' to the name of my physical interface:
$ sudo nmcli con mod 'Wired Connection 1' con-name eth0
So let's start out by creating the bridge itself:
$ nmcli con add ifname br0 type bridge con-name br0
Now add the physical interface as its slave:
$ nmcli con add type bridge-slave ifname eth0 master br0
Disable STP:
$ nmcli con mod br0 bridge.stp no
Now down the physical interface:
$ nmcli con down eth0
For this machine I want a static address:
$ nmcli con mod br0 ipv4.addresses 10.1.1.16/24
$ nmcli con mod br0 ipv4.gateway 10.1.1.1
$ nmcli con mod br0 ipv4.dns '10.1.1.1,8.8.8.8,8.8.4.4'
Don't forget to set your search domain:
$ nmcli con mod br0 ipv4.dns-search 'example.com'
Then tell Network Manager this will be a manual connection:
$ nmcli con mod br0 ipv4.method manual
Finally, bring up the new bridge interface:
$ nmcli con up br0
Run nmcli device show
to confirm your changes, and then restart NetworkManager (sudo systemctl restart NetworkManager.service
)
to make sure the configuration sticks.
I wrote a variant of the above script where I replace machine-specific names with environment variables in order to make it clear what needs to be changed. I also tried to write code to automagically infer what the variables should be given a default ethernet connection, but that code could be improve to be more robust:
I will edit the above code if anyone points out corrections or how to make things better.