1

I've got a libvirt KVM VM (named netstuff) running through a bridge (br0) which has two slaves: (em2) a host physical interface and (vnet0) the virtual NIC. dnsmasq-dhcp is on the host, supplying IP addresses to the VM and other physical hosts.

I can route anywhere on the 192.168.1.0/24, including between VM and hardware, but the VM cannot route to the other network or to the Internet. When traffic from the guest exits to the host, it doesn't seem to route from the bridge to interface em1, which has the default route.

Help?

Host libvirt XML:

# virsh dumpxml netstuff

... snip ...
<interface type='bridge'>
  <mac address='52:54:00:27:c4:22'/>
  <source bridge='br0'/>
  <target dev='vnet0'/>
  <model type='virtio'/>
  <alias name='net0'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
... snip ...

Host IP routes:

# ip r
default via XXX.99.126.1 dev em1
169.254.0.0/16 dev em1  scope link  metric 1002
169.254.0.0/16 dev br0  scope link  metric 1004
192.168.1.0/24 dev br0  proto kernel  scope link  src 192.168.1.1
XXX.99.126.0/27 dev em1  proto kernel  scope link  src XXX.99.126.4

Host NICs:

# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: em1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
    link/ether d4:ae:52:9d:73:c2 brd ff:ff:ff:ff:ff:ff
    inet XXX.99.126.4/27 brd XXX.99.126.31 scope global em1
       valid_lft forever preferred_lft forever
    inet6 fe80::d6ae:52ff:fe9d:73c2/64 scope link
       valid_lft forever preferred_lft forever
3: em2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP qlen 1000
    link/ether d4:ae:52:9d:73:c3 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::d6ae:52ff:fe9d:73c3/64 scope link
       valid_lft forever preferred_lft forever
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether d4:ae:52:9d:73:c3 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 brd 192.168.1.255 scope global br0
       valid_lft forever preferred_lft forever
    inet6 fe80::d6ae:52ff:fe9d:73c3/64 scope link
       valid_lft forever preferred_lft forever
5: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UNKNOWN qlen 1000
    link/ether fe:54:00:27:c4:22 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::fc54:ff:fe27:c422/64 scope link
       valid_lft forever preferred_lft forever

Host iptables:

# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere
INPUT_direct  all  --  anywhere             anywhere
INPUT_ZONES_SOURCE  all  --  anywhere             anywhere
INPUT_ZONES  all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere             ctstate INVALID
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             PHYSDEV match --physdev-is-bridged
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere
FORWARD_direct  all  --  anywhere             anywhere
FORWARD_IN_ZONES_SOURCE  all  --  anywhere             anywhere
FORWARD_IN_ZONES  all  --  anywhere             anywhere
FORWARD_OUT_ZONES_SOURCE  all  --  anywhere             anywhere
FORWARD_OUT_ZONES  all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere             ctstate INVALID
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
OUTPUT_direct  all  --  anywhere             anywhere

Chain FORWARD_IN_ZONES (1 references)
target     prot opt source               destination
FWDI_public  all  --  anywhere             anywhere            [goto]
FWDI_public  all  --  anywhere             anywhere            [goto]
FWDI_public  all  --  anywhere             anywhere            [goto]

Chain FORWARD_IN_ZONES_SOURCE (1 references)
target     prot opt source               destination

Chain FORWARD_OUT_ZONES (1 references)
target     prot opt source               destination
FWDO_public  all  --  anywhere             anywhere            [goto]
FWDO_public  all  --  anywhere             anywhere            [goto]
FWDO_public  all  --  anywhere             anywhere            [goto]

Chain FORWARD_OUT_ZONES_SOURCE (1 references)
target     prot opt source               destination

Chain FORWARD_direct (1 references)
target     prot opt source               destination

Chain FWDI_public (3 references)
target     prot opt source               destination
FWDI_public_log  all  --  anywhere             anywhere
FWDI_public_deny  all  --  anywhere             anywhere
FWDI_public_allow  all  --  anywhere             anywhere
ACCEPT     icmp --  anywhere             anywhere

Chain FWDI_public_allow (1 references)
target     prot opt source               destination

Chain FWDI_public_deny (1 references)
target     prot opt source               destination

Chain FWDI_public_log (1 references)
target     prot opt source               destination

Chain FWDO_public (3 references)
target     prot opt source               destination
FWDO_public_log  all  --  anywhere             anywhere
FWDO_public_deny  all  --  anywhere             anywhere
FWDO_public_allow  all  --  anywhere             anywhere

Chain FWDO_public_allow (1 references)
target     prot opt source               destination

Chain FWDO_public_deny (1 references)
target     prot opt source               destination

Chain FWDO_public_log (1 references)
target     prot opt source               destination

Chain INPUT_ZONES (1 references)
target     prot opt source               destination
IN_public  all  --  anywhere             anywhere            [goto]
IN_public  all  --  anywhere             anywhere            [goto]
IN_public  all  --  anywhere             anywhere            [goto]

Chain INPUT_ZONES_SOURCE (1 references)
target     prot opt source               destination

Chain INPUT_direct (1 references)
target     prot opt source               destination
REJECT     tcp  --  anywhere             anywhere             multiport dports ssh match-set fail2ban-sshd src reject-with icmp-port-unreachable

Chain IN_public (3 references)
target     prot opt source               destination
IN_public_log  all  --  anywhere             anywhere
IN_public_deny  all  --  anywhere             anywhere
IN_public_allow  all  --  anywhere             anywhere
ACCEPT     icmp --  anywhere             anywhere

Chain IN_public_allow (1 references)
target     prot opt source               destination
ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootps ctstate NEW
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh ctstate NEW

Chain IN_public_deny (1 references)
target     prot opt source               destination

Chain IN_public_log (1 references)
target     prot opt source               destination

Chain OUTPUT_direct (1 references)
target     prot opt source               destination

Guest ip routes:

ssh centos@192.168.1.76
Last login: Sat Apr  8 05:29:55 2017 from 192.168.1.1
[centos@netstuff ~]$ ip r
default via 192.168.1.1 dev eth0
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.76
[centos@netstuff ~]$

Guest NICs:

[centos@netstuff ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:27:c4:22 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.76/24 brd 192.168.1.255 scope global dynamic eth0
       valid_lft 2978sec preferred_lft 2978sec
    inet6 fe80::5054:ff:fe27:c422/64 scope link
       valid_lft forever preferred_lft forever
1

Turns out this is impossible without NAT, so I re-enabled the default NAT network with virsh net-start default. libvirt use of dnsmasq is careful to have that DHCP server running only on the interface it creates. So I simply ensured that the dnsmasq that I setup on the host would not interfere with the dnsmasq created by libvirt. To do so, in /etc/dnsmasq.conf I set dnsmasq into bind-interfaces mode, and forced it to listen on the bridge that I made (br0) by indicating the static IP I gave it: 192.168.1.1

listen-address=192.168.1.1
bind-interfaces

And of course:

systemctl restart dnsmasq

See here for dnsmasq FAQ and the "bind-interface" and "bind-dynamic" settings. http://www.thekelleys.org.uk/dnsmasq/docs/FAQ

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.