Creating a network bridge to allow virtual machines direct access to the network, rather than using network address translation (NAT), is not a new concept. It is however a task that has become more complex since most popular Linux distributions switched to using NetworkManager for, you guessed it, network management.
NetworkManager, unlike the old network management tools, does not currently support the creation of network bridges. As a result of this oversight most articles I have seen on the web which discuss creation of network bridges on Linux recommend turning NetworkManager off. While this is indeed a valid way to handle the problem, it means that you must either manage all network interfaces using the old network management tools or switch NetworkManager on and off as needed.
Personally while I do have a need to create network bridges on a regular basis for my virtual machines I also prefer using the userland tools built on top of NetworkManager to manage my wireless connections.
To this end today I will be illustrating how to create a network bridge on a physical Ethernet interface managed by the old network service while continuing to run NetworkManager for my other connections. As usual my weapon of choice is Fedora, in this case version 16 which has just been released. Let’s get started!
Before getting started make sure your existing network configuration is working by running ifconfig. In particular take note of the device name for your Ethernet device, if you have just moved to Fedora you may find it has changed from what you are used to.
p5p1 Link encap:Ethernet HWaddr 78:84:3C:E0:C8:6D
inet addr:192.168.1.120 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::7a84:3cff:fee0:c86d/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:911 errors:0 dropped:0 overruns:0 frame:0
TX packets:127 errors:0 dropped:0 overruns:0 carrier:0
RX bytes:108021 (105.4 KiB) TX bytes:10874 (10.6 KiB)
wlan0 Link encap:Ethernet HWaddr 90:00:4E:C0:5A:0D
inet addr:192.168.1.135 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::9200:4eff:fec0:5a0d/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1300699 errors:0 dropped:0 overruns:0 frame:0
TX packets:860018 errors:0 dropped:0 overruns:0 carrier:0
RX bytes:1695740220 (1.5 GiB) TX bytes:102433188 (97.6 MiB)
From the output we can see that my onboard Ethernet card, which used to be referred to as eth0, is now referred to as p5p1. Importantly we can also see that both devices are up and working.
Before changing the network configuration files it is important to ensure that both the NetworkManager and network services are stopped. You must be root, or have root permissions via sudo, to perform this action.
# systemctl stop NetworkManager.service
# systemctl stop network.service
Stopping the network services can take some time. Note that usually only NetworkManager will be running, after all being able to run both at the same time is what we are out to achieve! Check that both services have actually stopped before continuing.
# systemctl status NetworkManager.service
# systemctl status network.service
The service’s current state will be listed in the ‘Active:’ field in the readout from each command.
Prepare to be Bridged
Change into the directory where the network configuration scripts live.
# cd /etc/sysconfig/network-scripts/
The configuration scripts for your network interfaces live in this folder. The script for each interface is named ifcfg-. So in my case the configuration for the wireless interface is ifcfg-wlan0 and the configuration for the physical Ethernet interface is ifcfg-p5p1.
As the wireless interface is to continue to be managed by NetworkManager no changes are required to its configuration. We do however need to make changes to the configuration of the physical Ethernet interface so that it is ready to be bridged.
Open the configuration for the physical Ethernet interface in your favourite text editor:
# vim ifcfg-p5p1
The exact contents will vary depending on your exact installation. Mine looks like this:
In particular note that the interface is brought up on boot, uses DHCP to obtain a network address, and is currently controlled my NetworkManager. The HWADDR listed is just the MAC address of the device, generally it should be left as is.
To prepare the device to be bridged we need to make two changes:
- Set NM_CONTROLLED to “no”, telling NetworkManager not to manage this interface.
- Add the line BRIDGE=”br0″ to indicate that the device is to be used by a bridge called br0.
The resultant file is as follows:
At this point only half the configuration is complete. We now need to define the bridge itself.
Define the Bridge
Unlike the Ethernet interface configuration the configuration for the bridge will not exist yet. You will need to create it, usually the first bridge is called br0 and defined in the configuration file ifcfg-br0.
Create the file and add the following contents to it:
This sets up the bridge as an interface that uses DHCP to obtain a network address, starts on boot, and most importantly is not controlled by NetworkManager (not that NetworkManager knows how to control it anyway, but I digress).
Bringing it Up
Now that we’ve configured the bridge, it’s time to bring network services back up. The order in which you start the two services should not matter as the configurations explicitly say which devices should not be controlled by NetworkManager.
# systemctl start NetworkManager.service
# systemctl start network.service
If the services do not come up as expected check the output of systemctl status for the service(s) that fail(s). Other hints may also be present in /var/log/messages. One particular thing to look out for which I have encountered is SELinux issues affecting the DHCP client started by the network service.
Check ifconfig again to verify that both your wireless interface and your new bridge interface have been brought up successfully and have an IP address. Note that the physical Ethernet device will not have an IP address listed, it is instead assigned to the bridge.
Making it Stick
Once both services are running side by side it is necessary to ensure that both will start on reboot.
# systemctl enable NetworkManager.service
# systemctl enable network.service
You have now successfully setup a network bridge while keeping your other network interfaces managed using NetworkManager. In particular this means you can continue to use the userland tools to manager your wireless connections while having a bridge which can be used by your Virtual Machines.
Here is the way the bridge appears in Virtual Machine Manager’s network interface view: