VLAN for virtual machines

Aus Ingos Wiki
Version vom 22. September 2017, 23:05 Uhr von Ingo (Diskussion | Beiträge) (describe linux bridge as hub)
Wechseln zu: Navigation, Suche

Introduction

I wanted to update VLAN connections for virtual machines to newer technologies and put a question on unix.stackexchange. But I do not get any answer. It seems there is very little knowledge for this out there. So I decided to work on it by myself and document it here.

In gerneral I will look at four methods:

  1. oldstyle linux bridge as hub
  2. linux bridge as hub
  3. linux bridge with libvirt hook scripts
  4. Open vSwitch

Preparation

I have Debian GNU/Linux 9.1 (stretch) on the host and on virtual machines for testing as described here: Setup KVM with console. I'm sitting on harley as host, my all day workstation. Now I start the virtual machine, login and show its interface setting:

harley$ virsh start --console deb9-test

login

deb9-test$ cat /etc/systemd/network/08-vlan10.netdev
[NetDev]
Name=vlan10
Kind=vlan
[VLAN]
Id=10
deb9-test$ cat /etc/systemd/network/12-vlan10_attach-to-if.network
[Match]
Name=ens2
[Network]
VLAN=vlan10
deb9-test$ cat /etc/systemd/network/16-vlan10_up.network
[Match]
Name=vlan10
[Network]
Address=192.168.10.57/24
Gateway=192.168.10.1

To test if we have connection direct after startup I append this to .bashrc:

deb9-test$ echo ping -c3 192.168.10.1 >> .bashrc

Because I have to start the test virtual machine many times I setup autologin. It's no problem. There is nothing on the guest.

deb9-test$ grep ^ExecStart= /lib/systemd/system/serial-getty@.service
ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM

modify to

ExecStart=-/sbin/agetty --autologin yourloginname --keep-baud 115200,38400,9600 %I $TERM

oldstyle linux bridge as hub

This works always with the old linux bridge that do not know anything about VLAN. The trick is to set it to a complete transparent state for all connected interfaces like a hub. But you have to know that the bridge will then forward all packets to all interfaces simultanously. You can do it by setting the ageing time to 0.

Disable systemd-networkd and start networking with ifupdown:

harley$ sudo systemctl stop systemd-networkd
Warning: Stopping systemd-networkd.service, but it can still be activated by:
  systemd-networkd.socket
harley$ sudo systemctl disable systemd-networkd
Removed /etc/systemd/system/multi-user.target.wants/systemd-networkd.service.
Removed /etc/systemd/system/sockets.target.wants/systemd-networkd.socket.
harley$ sudo ip link set dev br0 down && sudo ip link del dev br0
harley$ sudo systemctl enable networking.service
Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable networking
harley$ sudo systemctl start networking.service
harley$

Setup the bridge and start it:

harley$ cat /etc/network/interfaces
auto br0
iface br0 inet manual
    bridge_ports enp1s0
    bridge_ageing 0
    bridge_stp off
harley$ sudo ifup br0
Waiting for br0 to get ready (MAXWAIT is 32 seconds).
harley$

It's all in place now:

harley$ cat /sys/class/net/br0/bridge/ageing_time 
0
harley$ cat /sys/class/net/br0/bridge/stp_state 
0
harley$ cat /sys/class/net/br0/bridge/vlan_filtering 
0

Yes, there is no VLAN filtering, means VLAN on the bridge is disabled but the guest sees the VLAN-tagged packets. To list all settings of the bridge you can use:

harley$ find /sys/class/net/br0/bridge/ -type f -readable -printf '%f = ' -exec cat {} \; | sort

References

linux bridge as hub

Now I try to setup #oldstyle linux bridge as hub just with systemd-networkd.

Disable networking with ifupdown and start systemd-networkd:

harley$ sudo systemctl stop networking.service
harley$ sudo systemctl disable networking.service
Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable networking
harley$ sudo ip link set dev br0 down && sudo ip link del dev br0
harley$ sudo systemctl enable systemd-networkd
Created symlink /etc/systemd/system/multi-user.target.wants/systemd-networkd.service → /lib/systemd/system/systemd-networkd.service.
Created symlink /etc/systemd/system/sockets.target.wants/systemd-networkd.socket → /lib/systemd/system/systemd-networkd.socket.
harley$ sudo systemctl start systemd-networkd
harley$

Setup the bridge and start it:

harley$ cat /etc/systemd/network/08-br0.netdev
[NetDev]
Name=br0
Kind=bridge
[Bridge]
AgeingTimeSec=0
STP=false
harley$ cat /etc/systemd/network/12-br0_add-enp1s0.network
[Match]
Name=enp1s0
[Network]
Bridge=br0
harley$ cat /etc/systemd/network/16-br0_up.network 
[Match]
Name=br0
harley$ sudo systemctl restart systemd-networkd
harley$

But AgeingTimeSec=0 is not acepted:

harley$ cat /sys/class/net/br0/bridge/ageing_time 
30000   (means 300 sec)
harley$ cat /sys/class/net/br0/bridge/stp_state 
0
harley$ cat /sys/class/net/br0/bridge/vlan_filtering 
0
harley$

References

linux bridge with libvirt hook scripts

References

Open vSwitch

References