My objective is to have all KVM guest VMs send and receive traffic on em2
with addresses on the 192.168.2.0/24
subnet.
I have a host Linux machine (CentOS 7) with several NICs, 2 of which are in use in this scenario, em1
and em2
.
The em1 interface has an IP of 192.168.0.131
. The em2
interface has been attached to br0
, so it doesn't have an IP itself, but br0
has been assigned an IP address of 192.168.2.1
.
I have created a route on my Netgear firewall to direct 192.168.2.0/24
traffic to 192.168.2.1
but this address doesn't show as an attached device the way 192.168.0.131
does, maybe because it's a virtual Linux bridge.
From the host VM, I can ping both the "bridge gateway", the VM guest, and the firewall gateway to the internet:
[root@boss ~]# ping -c1 192.168.2.1
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=0.085 ms
[root@boss ~]# ping -c1 192.168.2.10
64 bytes from 192.168.2.10: icmp_seq=1 ttl=64 time=0.476 ms
[root@boss ~]# ping -c1 192.168.0.254
64 bytes from 192.168.0.254: icmp_seq=1 ttl=64 time=4.17 ms
And from the guest VM, I can ping em1
, but not the internet gateway, 192.168.0.254
:
[root@localhost ~]# ping -c1 192.168.0.131
64 bytes from 192.168.0.131: icmp_seq=1 ttl=64 time=0.282 ms
[root@localhost ~]# ping -c1 192.168.0.254
PING 192.168.0.254 (192.168.0.254) 56(84) bytes of data.
--- 192.168.0.254 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
This is my config for em2
:
DEVICE=em2
TYPE=Ethernet
ONBOOT=yes
BRIDGE=br0
And br0
:
DEVICE=br0
BOOTPROTO=none
ONBOOT=yes
TYPE=Bridge
IPADDR=192.168.2.1
PREFIX=24
GATEWAY=192.168.0.254
ZONE=public
STP=no
My routing table on the VM host:
[root@boss ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.0.254 0.0.0.0 UG 0 0 0 em1
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 em1
192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 br0
The guest VM was started with virt-install
:
virt-install \
--name vm-guest-1 \
--network bridge=br0 \
--virt-type kvm \
Guest VM eth0
:
DEVICE="eth0"
BOOTPROTO="none"
ONBOOT="yes"
TYPE="Ethernet"
IPADDR="192.168.2.10"
NETMASK=255.255.255.0
And the guest VM routing table:
[root@localhost ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.2.1 0.0.0.0 UG 0 0 0 eth0
192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
As requested, my host bridge output:
[root@boss ~]# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.d4ae529de039 no em2
vnet0
Question/Problem:
How do I / why can't I route into my guest VM, or rather, why can't my guest VM get out to the internet?
Best Answer
You have basically two options:
vnet0
andem2
are bridged, so the VM can reach the Netgear device without routing. You just need to assign the VM an address in192.168.0.0/24
or use DHCP.If you need to route, remove the
em2
interface from the bridge and assign to it an address in192.168.0.0/24
. Then add a new routing table to/etc/iproute2/rt_tables
:Now add a routing table selection rule and a default route for your VMs:
In addition you need to modify the static route on the Netgear device to point to
em2
's address.Edit: In the second configuration Ethernet frames from the VMs do not leak on the physical network. The additional routing table is selected only when it needs to route something from the bridge
br0
(i.e. the virtual guests) and sends the traffic throughem2
instead ofem1
(the default route in the main table). You can see all routing tables at once with:You can read more about routing tables on the Guide to IP Layer Network Administration with Linux.