Question

Using linux KVM/QEMU, I have a virtual machine with two NICs presented at the host as tap interfaces:

 -net nic,macaddr=AA:AA:AA:AA:00:01,model=virtio \
 -net tap,ifname=tap0a,script=ifupbr0.sh \
 -net nic,macaddr=AA:AA:AA:AA:00:02,model=virtio \
 -net tap,ifname=tap0b,script=ifupbr1.sh \

In the guest (also running linux), these are configured with different subnets:

eth0      Link encap:Ethernet  HWaddr aa:aa:aa:aa:00:01  
          inet addr:10.0.0.10  Bcast:10.0.255.255  Mask:255.255.0.0
           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1


eth1      Link encap:Ethernet  HWaddr aa:aa:aa:aa:00:02  
          inet addr:192.168.0.10  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

Routes only go to the expected places:

ip route list
default via 10.0.0.1 dev eth0  metric 100 
10.0.0.0/16 dev eth0  proto kernel  scope link  src 10.0.0.10 
192.168.0.0/24 dev eth1  proto kernel  scope link  src 192.168.0.10 

But somehow don't seem to be treated by KVM as being connected to distinct networks. If I trace the individual interfaces, they both see the same traffic.

For example, if I ping on the 10.0.0.0/16 subnet, ping -I eth0 10.0.0.1

And simultaneously trace the two tap interfaces with tcpdump , I see the pings coming through on both tap interfaces:

sudo tcpdump -n -i tap0a
10:51:56.308190 IP 10.0.0.10 > 10.0.0.1: ICMP echo request, id 867, seq 1, length 64
10:51:56.308217 IP 10.0.0.1 > 10.0.0.10: ICMP echo reply, id 867, seq 1, length 64

sudo tcpdump -n -i tap0b
10:51:56.308190 IP 10.0.0.10 > 10.0.0.1: ICMP echo request, id 867, seq 1, length 64
10:51:56.308217 IP 10.0.0.1 > 10.0.0.10: ICMP echo reply, id 867, seq 1, length 64

That seems strange to me since it's pretty clear that the guest OS would have only actually sent this on the tap0a interface.

Is this expected behavior? Is there a way to keep the interfaces separate as I expected? Is this some misconfiguration issue on my part?


Additional info, here are the two ifupbr0.sh and ifupbr1.sh scripts:

% cat ifupbr1.sh

#!/bin/sh
set -x

switch=br0

echo args = $*

if [ -n "$1" ];then
        sudo tunctl -u `whoami` -t $1
        sudo ip link set $1 up
        sleep 0.5s
        sudo brctl addif $switch $1
        exit 0
else
        echo "Error: no interface specified"
        exit 1
fi

% cat ifupbr1.sh

#!/bin/sh
set -x

switch=br1

echo args = $*

if [ -n "$1" ];then
        sudo tunctl -u `whoami` -t $1
        sudo ip link set $1 up
        sleep 0.5s
        sudo brctl addif $switch $1
        exit 0
else
        echo "Error: no interface specified"
        exit 1
fi

I see this problem even if I detach the "tap0b" interface from the br1. It still shows the traffic that I'd expect only for tap0a. That is, even when:

% brctl show

bridge name     bridge id               STP enabled     interfaces
br0             8000.26a2d168234b       no              tap0a
br1             8000.000000000000       no
br2             8000.000000000000       no
Was it helpful?

Solution

It looks like I answered my own question eventually, but I'll document it for anyone else that hits this.

Evidently this really is the intended behavior of KVM for the options I was using.

At this URL: http://wiki.qemu.org/Documentation/Networking

I found:

QEMU previously used the -net nic option instead of -device DEVNAME and -net TYPE instead of -netdev TYPE. This is considered obsolete since QEMU 0.12, although it continues to work.

The legacy syntax to create virtual network devices is:

-net nic,model=MODEL

And sure enough, I'm using this legacy syntax. I thought the new syntax was just more flexible but it apparently actually has this intended behavior:

The obsolete -net syntax automatically created an emulated hub (called a QEMU "VLAN", for virtual LAN) that forwards traffic from any device connected to it to every other device on the "VLAN". It is not an 802.1q VLAN, just an isolated network segment.

The vlans it supports are also just emulated hubs, and don't forward out to the host at all as best I can tell.

Regardless, I reworked the QEMU options to use the "new" netdev syntax and obtained the behavior I wanted here.

OTHER TIPS

What do you have in the ifupbr0.sh and ifupbr1.sh scripts? What bridging tool are you using? That is the important piece which segregates your traffic to the interfaces desired.

I've used openvswitch to handle my bridging stuff. But before that I used bridge-utils in Debian.

I wrote some information about bridge-utils at http://blog.raymond.burkholder.net/index.php?/archives/31-QEMUKVM-BridgeTap-Network-Configuration.html. I have other posts regarding what I did with bridging on the OpenVSwitch side of things.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top