<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
		<id>http://wiki.hoeft-online.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ingo</id>
		<title>Ingos Wiki - Benutzerbeiträge [de]</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.hoeft-online.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ingo"/>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/Spezial:Beitr%C3%A4ge/Ingo"/>
		<updated>2026-04-12T13:58:05Z</updated>
		<subtitle>Benutzerbeiträge</subtitle>
		<generator>MediaWiki 1.28.2</generator>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=29</id>
		<title>VLAN for virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=29"/>
				<updated>2018-08-09T19:26:06Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: Änderung 28 von 86.62.117.180 (Diskussion) rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
I wanted to update VLAN connections for virtual&lt;br /&gt;
machines to newer technologies and put a question on&lt;br /&gt;
[https://unix.stackexchange.com/questions/392758/setup-vlan-on-linux-bridge-for-virtual-machines-with-systemd unix.stackexchange]. But I do not get any answer. It seems there is very&lt;br /&gt;
little knowledge for this out there. So I decided to work on it by myself&lt;br /&gt;
and document it here.&lt;br /&gt;
&lt;br /&gt;
In gerneral I will look at three methods:&lt;br /&gt;
# [[#oldstyle linux bridge as hub|oldstyle linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge as hub|linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge with libvirt hook scripts|linux bridge with libvirt hook scripts]]&lt;br /&gt;
&lt;br /&gt;
== Preparation ==&lt;br /&gt;
I have Debian GNU/Linux 9.1 (stretch) on the host and on virtual machines for testing. Setup is described here: [[Setup KVM with console]]. I'm sitting on harley as host, my all day workstation.&lt;br /&gt;
Now I start the virtual machine, login and show its interface setting:&lt;br /&gt;
 '''harley$''' virsh start --console deb9-test&lt;br /&gt;
login&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/08-vlan10.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 Kind=vlan&lt;br /&gt;
 [VLAN]&lt;br /&gt;
 Id=10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/12-vlan10_attach-to-if.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=ens2&lt;br /&gt;
 [Network]&lt;br /&gt;
 VLAN=vlan10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/16-vlan10_up.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 [Network]&lt;br /&gt;
 DHCP=ipv4&lt;br /&gt;
 IPv6AcceptRA=no&lt;br /&gt;
 LinkLocalAddressing=no&lt;br /&gt;
To test if the virtual machine has connection I use:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:34:20 CEST. --&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: Enumeration completed&lt;br /&gt;
 Sep 23 20:34:05 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: DHCPv4 address 192.168.10.89/24 via 192.168.10.1&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: Configured&lt;br /&gt;
 Sep 23 20:34:19 systemd-networkd[204]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
4 sec after Started Network Service it gets an IP-Address and 14 sec later interface ens2 was Configured. If ens2 is Configured and the guest hasn't got an IP-Address the connection failed. It looks like this:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:45:13 CEST. --&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: Enumeration completed&lt;br /&gt;
 Sep 23 20:44:59 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:13 systemd-networkd[197]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
&lt;br /&gt;
Because I have to start the test virtual machine many times I setup autologin. It's no problem. There is nothing on the guest.&lt;br /&gt;
 '''deb9-test$''' grep ^ExecStart= /lib/systemd/system/serial-getty@.service&lt;br /&gt;
 ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
modify to&lt;br /&gt;
 ExecStart=-/sbin/agetty --autologin ''yourloginname'' --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
&amp;lt;span id=&amp;quot;bridge-settings&amp;quot;&amp;gt;To list all settings of the bridge&amp;lt;/span&amp;gt; you can use:&lt;br /&gt;
 '''harley$''' find /sys/class/net/br0/bridge/ -type f -readable -printf '%f = ' -exec cat {} \; | sort&lt;br /&gt;
&lt;br /&gt;
== oldstyle linux bridge as hub ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Disable systemd-networkd and start networking with ifupdown:&lt;br /&gt;
 '''harley$''' sudo systemctl stop systemd-networkd&lt;br /&gt;
 Warning: Stopping systemd-networkd.service, but it can still be activated by:&lt;br /&gt;
   systemd-networkd.socket&lt;br /&gt;
 '''harley$''' sudo systemctl disable systemd-networkd&lt;br /&gt;
 Removed /etc/systemd/system/multi-user.target.wants/systemd-networkd.service.&lt;br /&gt;
 Removed /etc/systemd/system/sockets.target.wants/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install enable networking&lt;br /&gt;
 '''harley$''' sudo systemctl start networking.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/network/interfaces&lt;br /&gt;
 auto br0&lt;br /&gt;
 iface br0 inet manual&lt;br /&gt;
     bridge_ports enp1s0&lt;br /&gt;
     bridge_ageing 0&lt;br /&gt;
     bridge_stp off&lt;br /&gt;
 '''harley$''' sudo ifup br0&lt;br /&gt;
 Waiting for br0 to get ready (MAXWAIT is 32 seconds).&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
It's all in place now:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
Yes, there is no VLAN filtering, means VLAN on the bridge is disabled but the guest sees the VLAN-tagged packets.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://wiki.debian.org/NetworkConfiguration#Bridging_without_Switching&lt;br /&gt;
&lt;br /&gt;
== linux bridge as hub ==&lt;br /&gt;
Now I try to setup [[#oldstyle linux bridge as hub]] just with systemd-networkd.&lt;br /&gt;
&lt;br /&gt;
Disable networking with ifupdown and start systemd-networkd:&lt;br /&gt;
 '''harley$''' sudo systemctl stop networking.service&lt;br /&gt;
 '''harley$''' sudo systemctl disable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install disable networking&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable systemd-networkd&lt;br /&gt;
 Created symlink /etc/systemd/system/multi-user.target.wants/systemd-networkd.service → /lib/systemd/system/systemd-networkd.service.&lt;br /&gt;
 Created symlink /etc/systemd/system/sockets.target.wants/systemd-networkd.socket → /lib/systemd/system/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo systemctl start systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/08-br0.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 AgeingTimeSec=0&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/12-br0_add-enp1s0.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl restart systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
AgeingTimeSec=0 is not acepted but should:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 30000   (means 300 sec)&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
But I've found a workaround. Useing a number between '''.'''01 and '''.'''000001 (there are dots) will set ageing_time to 0.&lt;br /&gt;
So set AgeingTimeSec='''.'''000001 in /etc/systemd/network/08-br0.netdev. I suppose it's a bug. Then we&lt;br /&gt;
will get:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets now an IP-Address on boot and is connected to VLAN 10.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
This works because of [[#References|three conditions]].&lt;br /&gt;
# ageing time is 0: ageing time specifies the number of seconds a MAC Address will be kept in the forwarding database after having a packet received from this MAC Address. Setting it to 0 means there is never a MAC Address stored in the FDB.&lt;br /&gt;
# unicast flood on interfaces is on: this controls whether the bridge should flood traffic for which an FDB entry is missing and the destination is unknown through this port. Defaults to on.&lt;br /&gt;
# spanning tree protocol (stp) is disabled: we don't have a forward_delay at startup for the learning phase of spanning tree.&lt;br /&gt;
I have a running and connected virtual machine:&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   1 PVID Egress Untagged&lt;br /&gt;
 br0      1 PVID Egress Untagged&lt;br /&gt;
 vnet0    1 PVID Egress Untagged&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time&lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/forward_delay&lt;br /&gt;
 1500&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state&lt;br /&gt;
 0&lt;br /&gt;
Indeed we have forward_delay 1500 (means 15 sec) but it doesn't matter. stp_state is 0 (disabled), no spanning tree. Flood (means unicast flood) is on as I can see:&lt;br /&gt;
 '''harley$''' sudo bridge -d link show&lt;br /&gt;
 ''3: enp1s0'' state UP : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 4&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on &lt;br /&gt;
 ''95: vnet0'' state UNKNOWN : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 100&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let's have a look at flooding on the interfaces. I disable it on the physical interface enp1s0 of the bridge and reboot the guest:&lt;br /&gt;
 '''harley$''' sudo bridge link set dev enp1s0 flood off&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets an IP-Address from the DHCP-Server but then can't ping its gateway. DHCP-REQUEST is broadcast and goes thru enp1s0. DHCP-ANSWER comes back thru it to any other (here only vnet0) interface which has flood on. Ping is unicast and isn't forwareded on enp1s0. If I set  enp1s0 flood on and vnet0 flood off and &amp;lt;code&amp;gt;'''deb9-test$ '''sudo systemctl restart systemd-networkd&amp;lt;/code&amp;gt;, I get no IP-Address from DHCP-Server and can't ping the interface. Incoming DHCP-ANSWER isn't broadcast and vnet0 doesn't forward it to the guest.&lt;br /&gt;
&lt;br /&gt;
Btw. this method has bad performance as we can see with monitor. We insert MAC-Addresses into FDB for just deleting it immediately, all for nothing.&lt;br /&gt;
 '''harley$''' sudo bridge monitor fdb&lt;br /&gt;
 52:54:00:01:76:20 dev enp1s0 master br0 &lt;br /&gt;
 52:54:00:b0:ca:63 dev vnet0 master br0 &lt;br /&gt;
 f4:f2:6d:2c:87:f7 dev enp1s0 master br0 &lt;br /&gt;
 00:80:3f:2a:31:1a dev enp1s0 master br0 &lt;br /&gt;
 Deleted 52:54:00:01:76:20 dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted 52:54:00:b0:ca:63 dev vnet0 master br0 stale&lt;br /&gt;
 Deleted 00:80:3f:2a:31:1a dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted f4:f2:6d:2c:87:f7 dev enp1s0 master br0 stale&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.netdev.html&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.network.html&lt;br /&gt;
&lt;br /&gt;
== linux bridge with libvirt hook scripts ==&lt;br /&gt;
We setup a bridge with VLAN enabled:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/08-br0.netdev &lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 DefaultPVID=none&lt;br /&gt;
 VLANFiltering=true&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/12-br0_add-enp1s0.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=10&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=20&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=30&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
With this I get:&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   1 PVID Egress Untagged&lt;br /&gt;
          10&lt;br /&gt;
          20&lt;br /&gt;
          30  &lt;br /&gt;
 br0      1 PVID Egress Untagged&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
But what is this? We have default VLAN &amp;lt;code&amp;gt;1 PVID Egress Untagged&amp;lt;/code&amp;gt;. I don't want this. Seems setting &amp;lt;code&amp;gt;DefaultPVID=none&amp;lt;/code&amp;gt; in 08-br0.netdev doesn't work. I've made a [[#Workaround for setting DefaultPVID=none|Workaround for setting DefaultPVID=none]]. Looking at this behavior I found that we can set &amp;lt;code&amp;gt;default_pvid&amp;lt;/code&amp;gt; in the kernel only if &amp;lt;code&amp;gt;vlan_filtering = 0&amp;lt;/code&amp;gt;. By hand I have to do:&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/default_pvid'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 1 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
If I start a guest I will get now:&lt;br /&gt;
 '''harley$''' virsh start deb9-test&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   10&lt;br /&gt;
          20&lt;br /&gt;
          30&lt;br /&gt;
 br0     None&lt;br /&gt;
 vnet0   None&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The virtual network interface vnet0 for deb9-test has no VLAN ID. Libvirt does not know something about this so we have to tell it. Libvirt provides [https://www.libvirt.org/hooks.html hook scripts] that we can use for this. We have to:&lt;br /&gt;
# [[#define VLAN-ID the virtual machine belongs to]]&lt;br /&gt;
# [[#get information on startup from the runtime XML-config of the domain]]&lt;br /&gt;
# [[#set VLAN-ID to the dynamic virtual network interface vnet*]]&lt;br /&gt;
&amp;lt;span id=&amp;quot;debug.sh&amp;quot;&amp;gt;For debugging the hook-scripts&amp;lt;/span&amp;gt; I've made a small script:&lt;br /&gt;
 '''harley$''' cat /etc/libvirt/hooks/debug.sh&lt;br /&gt;
 #!/bin/bash -e&lt;br /&gt;
 # https://www.libvirt.org/hooks.html&lt;br /&gt;
 # If you make a new hook script then 'sudo systemctl restart libvirtd'.&lt;br /&gt;
 # For debug set symlink to hook-script daemon, qemu, lxc, libxl and/or network,&lt;br /&gt;
 # e.g. 'sudo ln -s debug.sh qemu' and restart libvirtd.&lt;br /&gt;
 &lt;br /&gt;
 logfile='/var/log/libvirt/hooks.log'&lt;br /&gt;
 &lt;br /&gt;
 echo &amp;quot;$0&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 date -Iseconds &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 echo &amp;quot;\$1=$1, \$2=$2, \$3=$3, \$4=$4&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 cat - &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 echo -e &amp;quot;\n---------------------------------------------&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== define VLAN-ID the virtual machine belongs to ===&lt;br /&gt;
For this we have an extra [https://libvirt.org/formatdomain.html#elementsMetadata element &amp;lt;metadata&amp;gt; in Domain XML format] for custom metadata. We can simply add the information to the static configuration with &amp;lt;code&amp;gt;'''harley$''' virsh edit deb9-test&amp;lt;/code&amp;gt; like this (look only at the &amp;lt;metadata&amp;gt; element):&lt;br /&gt;
 '''harley$''' virsh dumpxml deb9-test | head -n9&lt;br /&gt;
 &amp;lt;domain type='kvm' id='1'&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;deb9-test&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;uuid&amp;gt;70d56a28-795d-4010-9403-513a4bd6b66a&amp;lt;/uuid&amp;gt;&lt;br /&gt;
   &amp;lt;metadata&amp;gt;&lt;br /&gt;
     &amp;lt;my:home xmlns:my=&amp;quot;http://hoeft-online.de/my/&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;my:vlan&amp;gt;10&amp;lt;/my:vlan&amp;gt;&lt;br /&gt;
     &amp;lt;/my:home&amp;gt;&lt;br /&gt;
   &amp;lt;/metadata&amp;gt;&lt;br /&gt;
   &amp;lt;memory unit='KiB'&amp;gt;1048576&amp;lt;/memory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get information on startup from the runtime XML-config of the domain ===&lt;br /&gt;
It seems a little bit difficult to get needed information out of the big XML-config but it's no problem with XSLT. I've made a XSL-stylesheet for this and use xmlstarlet. Start a virtual machine and then its runtime configuration is available with &amp;lt;code&amp;gt;'''harley$''' virsh dumpxml deb9-test | xmlstarlet tr qemu.xsl&amp;lt;/code&amp;gt;. With this I can test my stylesheet. Here is it:&lt;br /&gt;
 '''harley$''' cat /etc/libvirt/hooks/qemu.xsl &lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;amp;lt;!-- This stylesheet extracts the VLAN-ID and the target device of the&lt;br /&gt;
      bridge from the domain-xml given to the libvirt hook-script &amp;quot;qemu&amp;quot;.&lt;br /&gt;
      Example output: &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;&lt;br /&gt;
 --&amp;amp;gt;&lt;br /&gt;
 &amp;lt;xsl:stylesheet version=&amp;quot;1.0&amp;quot; xmlns:xsl=&amp;quot;http://www.w3.org/1999/XSL/Transform&amp;quot;&lt;br /&gt;
      xmlns:my=&amp;quot;http://hoeft-online.de/my/&amp;quot; exclude-result-prefixes=&amp;quot;my&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:output omit-xml-declaration=&amp;quot;yes&amp;quot; indent=&amp;quot;no&amp;quot;&lt;br /&gt;
        encoding=&amp;quot;utf-8&amp;quot; media-type=&amp;quot;text/xml&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:strip-space elements=&amp;quot;*&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;text()|@*&amp;quot;/&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;/domain&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;meta&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:apply-templates/&amp;gt;&lt;br /&gt;
     &amp;lt;/meta&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;metadata/my:home/my:vlan&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;vlan&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:value-of select=&amp;quot;.&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;/vlan&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match='interface[@type=&amp;quot;bridge&amp;quot;]/target'&amp;gt;&lt;br /&gt;
     &amp;lt;dev&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:value-of select=&amp;quot;@dev&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;/dev&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;/xsl:stylesheet&amp;gt;&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
 '''harley$''' virsh dumpxml deb9-test | xmlstarlet tr /etc/libvirt/hooks/qemu.xsl &lt;br /&gt;
 &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;'''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== set VLAN-ID to the dynamic virtual network interface vnet* ===&lt;br /&gt;
Putting it all together here is the executable hook-script:&lt;br /&gt;
 '''harley$''' cat /etc/libvirt/hooks/qemu&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #/etc/libvirt/hooks/qemu&lt;br /&gt;
 # Docs: https://www.libvirt.org/hooks.html&lt;br /&gt;
 # If you make a new hook script then 'sudo systemctl restart libvirtd'.&lt;br /&gt;
 &lt;br /&gt;
 # On startup of the domain (guest) This script does:&lt;br /&gt;
 # Get Metadata VLAN-ID of the guest and target device of the bridge from&lt;br /&gt;
     # the domain-xml available on standard input. It is the runtime&lt;br /&gt;
     # version from 'virsh dumpxml domainname'. For extracting the&lt;br /&gt;
     # information we use a XSL-stylesheet. Example input into $META:&lt;br /&gt;
     # &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;&lt;br /&gt;
 # Select $DEV  from $META&lt;br /&gt;
 # Select $VLAN from $META&lt;br /&gt;
 # Set $VLAN to $DEV on the bridge&lt;br /&gt;
 &lt;br /&gt;
 case &amp;quot;$2&amp;quot; in&lt;br /&gt;
   prepare)&lt;br /&gt;
     ;;&lt;br /&gt;
   start)&lt;br /&gt;
     META=$(/usr/bin/xmlstarlet tr /etc/libvirt/hooks/qemu.xsl -)&lt;br /&gt;
     DEV=$(echo &amp;quot;$META&amp;quot; | /usr/bin/xmlstarlet sel -t -v '/meta/dev')&lt;br /&gt;
     VLAN=$(echo &amp;quot;$META&amp;quot; | /usr/bin/xmlstarlet sel -t -v '/meta/vlan')&lt;br /&gt;
     if &amp;amp;#91;[ -n $DEV &amp;amp;&amp;amp; -n $VLAN ]&amp;amp;#93;; then&lt;br /&gt;
       /sbin/bridge vlan add vid &amp;quot;$VLAN&amp;quot; dev &amp;quot;$DEV&amp;quot;&lt;br /&gt;
     fi&lt;br /&gt;
     ;;&lt;br /&gt;
   started)&lt;br /&gt;
     ;;&lt;br /&gt;
   stopped)&lt;br /&gt;
     ;;&lt;br /&gt;
   release)&lt;br /&gt;
     ;;&lt;br /&gt;
   migrate)&lt;br /&gt;
     ;;&lt;br /&gt;
   restore)&lt;br /&gt;
     ;;&lt;br /&gt;
   reconnect)&lt;br /&gt;
     ;;&lt;br /&gt;
   attach)&lt;br /&gt;
     ;;&lt;br /&gt;
   *)&lt;br /&gt;
     echo &amp;quot;qemu hook called with unexpected options $*&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
     exit 1&lt;br /&gt;
     ;;&lt;br /&gt;
 esac&lt;br /&gt;
 '''harley$''' sudo chmod 744 /etc/libvirt/hooks/qemu&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.libvirt.org/hooks.html&lt;br /&gt;
* https://serverfault.com/questions/696011/libvirt-hook-qemu-suse12&lt;br /&gt;
&lt;br /&gt;
== Workaround for setting DefaultPVID=none ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;We do not need it anymore. This bug is fixed in systemd 234.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Setting [https://www.freedesktop.org/software/systemd/man/systemd.netdev.html#DefaultPVID= DefaultPVID] in a&amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt; configuration file to &amp;quot;none&amp;quot; does not work. Until this bug is fixed I've made a workaround. The kernel accepts setting &amp;lt;code&amp;gt;default_pvid&amp;lt;/code&amp;gt; to 0 (means &amp;quot;none&amp;quot;) only if &amp;lt;code&amp;gt;vlan_filtering=0&amp;lt;/code&amp;gt;, so we have to do:&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/default_pvid'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 1 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Check with listing of [[#bridge-settings|bridge-settings]].&lt;br /&gt;
Theese commands must run with &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt; so we need a service for this. First I make a script and make it executable for root:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/DefaultPVID.sh &lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #echo &amp;quot;entering DefaultPVID.sh&amp;quot; &amp;gt;&amp;gt;/tmp/debug.log&lt;br /&gt;
 &lt;br /&gt;
 BRDIR=&amp;quot;/sys/class/net/br0/bridge/&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 if &amp;amp;#91;[ -f $BRDIR/vlan_filtering &amp;amp;&amp;amp; -f $BRDIR/default_pvid ]&amp;amp;#93;; then&lt;br /&gt;
   #echo &amp;quot;setting DefaultPVID&amp;quot; &amp;gt;&amp;gt;/tmp/debug.log&lt;br /&gt;
   VLAN_FILTERING=&amp;quot;$(cat &amp;quot;$BRDIR&amp;quot;/vlan_filtering)&amp;quot;&lt;br /&gt;
   echo 0 &amp;gt;&amp;quot;$BRDIR&amp;quot;/vlan_filtering&lt;br /&gt;
   echo 0 &amp;gt;&amp;quot;$BRDIR&amp;quot;/default_pvid&lt;br /&gt;
   echo &amp;quot;$VLAN_FILTERING&amp;quot; &amp;gt;&amp;quot;$BRDIR&amp;quot;/vlan_filtering&lt;br /&gt;
 fi&lt;br /&gt;
 exit 0&lt;br /&gt;
 '''harley$''' sudo chmod 744 /etc/systemd/network/DefaultPVID.sh&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Test with &amp;lt;code&amp;gt;'''harley$''' sudo /etc/systemd/network/DefaultPVID.sh&amp;lt;/code&amp;gt;. Next I create a service to execute this script:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/system/DefaultPVID.service &lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=set DefaultPVID on a bridge as workaround&lt;br /&gt;
 Wants=network.target&lt;br /&gt;
 After=network.target&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 Type=oneshot&lt;br /&gt;
 ExecStart=/etc/systemd/network/DefaultPVID.sh&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Test with &amp;lt;code&amp;gt;'''harley$''' sudo systemctl start DefaultPVID.service &amp;amp;&amp;amp; systemctl status DefaultPVID.service&amp;lt;/code&amp;gt;. After this I create a [https://www.freedesktop.org/software/systemd/man/systemd.unit.html#id-1.11.3 drop-in file for overriding vendor settings] so this service will be executed together with &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt;:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/system/systemd-networkd.service.d/DefaultPVID.conf &lt;br /&gt;
 [Unit]&lt;br /&gt;
 # This is only a workaround. DefaultPVID cannot be set in&lt;br /&gt;
 # /etc/systemd/network/br0.netdev. It seems buggy.&lt;br /&gt;
 Wants=DefaultPVID.service&lt;br /&gt;
 Before=DefaultPVID.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Test with &amp;lt;code&amp;gt;'''harley$''' sudo systemctl restart systemd-networkd&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=Raspberry_Pi_as_UPnP_renderer&amp;diff=27</id>
		<title>Raspberry Pi as UPnP renderer</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=Raspberry_Pi_as_UPnP_renderer&amp;diff=27"/>
				<updated>2017-10-25T14:25:04Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: add description for starting gmediarender&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Date: 2017-10-25&amp;lt;br/&amp;gt;&lt;br /&gt;
lsb_release Description: Raspbian GNU/Linux 9.1 (stretch)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I setup a multiroom music playing environment. For this I use Raspberry Pis for renderer in a room. Here I found a [https://joachim-wilke.de/blog/2016/07/10/UPNP-Renderer-auf-dem-Raspberry-Pi/ somewhat outdated howto] but it points me in the right direction. Here is howto install it.&lt;br /&gt;
&lt;br /&gt;
At least the default audio output should do. You can download this small file [http://hoeft-online.de/working.wav working.wav] and test it with&lt;br /&gt;
 '''pi@raspberrypi:~ $''' aplay working.wav&lt;br /&gt;
 '''pi@raspberrypi:~ $'''&lt;br /&gt;
&lt;br /&gt;
We use [https://github.com/hzeller/gmrender-resurrect gmrender-resurrect] which is available in the repository. Install it on a RasPi with needed plugins.&lt;br /&gt;
&lt;br /&gt;
 '''pi@raspberrypi:~ $''' sudo apt install gmediarender gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-alsa&lt;br /&gt;
 '''pi@raspberrypi:~ $'''&lt;br /&gt;
&lt;br /&gt;
Test installation with&lt;br /&gt;
 '''pi@raspberrypi:~ $''' /usr/bin/gmediarender -f Test -u 42 --logfile /dev/stdout&lt;br /&gt;
&lt;br /&gt;
Configure in &amp;lt;code&amp;gt;/etc/default/gmediarender&amp;lt;/code&amp;gt;, set &amp;lt;code&amp;gt;ENABLED=1&amp;lt;/code&amp;gt; and maybe your &amp;lt;code&amp;gt;UPNP_DEVICE_NAME&amp;lt;/code&amp;gt;. Don't use &amp;quot;special&amp;quot; characters like umlaut. Startup will quit with an error message. Seems gmediarender still not understand UTF-8 :-(&lt;br /&gt;
&lt;br /&gt;
Start gmediarender as service:&lt;br /&gt;
 '''pi@raspberrypi:~ $''' sudo systemctl enable gmediarender.service&lt;br /&gt;
 '''pi@raspberrypi:~ $''' sudo systemctl start gmediarender.service&lt;br /&gt;
 '''pi@raspberrypi:~ $''' sudo systemctl status gmediarender.service&lt;br /&gt;
&lt;br /&gt;
The output of the last command should contain a line like:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;Active: active (running) since Wed 2017-10-25 14:17:09 UTC; 2s ago&amp;lt;/code&amp;gt;&lt;br /&gt;
[[Category:Raspberry Pi]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=Raspberry_Pi_as_UPnP_renderer&amp;diff=26</id>
		<title>Raspberry Pi as UPnP renderer</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=Raspberry_Pi_as_UPnP_renderer&amp;diff=26"/>
				<updated>2017-10-25T10:57:07Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: add audio testfile&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Date: 2017-10-24&amp;lt;br/&amp;gt;&lt;br /&gt;
lsb_release Description: Raspbian GNU/Linux 9.1 (stretch)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I setup a multiroom music playing environment. For this I use Raspberry Pis for renderer in a room. Here I found a [https://joachim-wilke.de/blog/2016/07/10/UPNP-Renderer-auf-dem-Raspberry-Pi/ somewhat outdated howto] but it points me in the right direction. Here is howto install it.&lt;br /&gt;
&lt;br /&gt;
At least the default audio output should do. You can download this small file [http://hoeft-online.de/working.wav working.wav] and test it with&lt;br /&gt;
 '''pi@raspberrypi:~ $''' aplay working.wav&lt;br /&gt;
 '''pi@raspberrypi:~ $'''&lt;br /&gt;
&lt;br /&gt;
We use [https://github.com/hzeller/gmrender-resurrect gmrender-resurrect] which is available in the repository. Install it on a RasPi with needed plugins.&lt;br /&gt;
&lt;br /&gt;
 '''pi@raspberrypi:~ $''' sudo apt install gmediarender gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-alsa&lt;br /&gt;
 '''pi@raspberrypi:~ $'''&lt;br /&gt;
&lt;br /&gt;
Test installation with&lt;br /&gt;
 '''pi@raspberrypi:~ $''' /usr/bin/gmediarender -f Test -u 42 --logfile /dev/stdout&lt;br /&gt;
&lt;br /&gt;
Configure in /etc/default/gmediarender. Don't use &amp;quot;special&amp;quot; characters like umlaut. Startup will quit with an error message. Seems gmediarender still not understand UTF-8 :-(&lt;br /&gt;
&lt;br /&gt;
Start gmediarender as service:&lt;br /&gt;
 '''pi@raspberrypi:~ $''' sudo systemctl enable gmediarender.service&lt;br /&gt;
 '''pi@raspberrypi:~ $''' sudo systemctl start gmediarender.service&lt;br /&gt;
 '''pi@raspberrypi:~ $''' &lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry Pi]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=Raspberry_Pi_as_UPnP_renderer&amp;diff=25</id>
		<title>Raspberry Pi as UPnP renderer</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=Raspberry_Pi_as_UPnP_renderer&amp;diff=25"/>
				<updated>2017-10-25T01:29:03Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: software version added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Date: 2017-10-24&amp;lt;br/&amp;gt;&lt;br /&gt;
lsb_release Description: Raspbian GNU/Linux 9.1 (stretch)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I setup a multiroom music playing environment. For this I use Raspberry Pis for renderer in a room. Here I found a [https://joachim-wilke.de/blog/2016/07/10/UPNP-Renderer-auf-dem-Raspberry-Pi/ somewhat outdated howto] but it points me in the right direction. Here is howto install it.&lt;br /&gt;
&lt;br /&gt;
At least the default audio output should do. Test it with &lt;br /&gt;
&lt;br /&gt;
We use [https://github.com/hzeller/gmrender-resurrect gmrender-resurrect] which is available in the repository. Install it on a RasPi with needed plugins.&lt;br /&gt;
&lt;br /&gt;
 '''pi@raspberrypi:~ $''' sudo apt install gmediarender gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-alsa&lt;br /&gt;
 '''pi@raspberrypi:~ $'''&lt;br /&gt;
&lt;br /&gt;
Test installation with&lt;br /&gt;
 '''pi@raspberrypi:~ $''' /usr/bin/gmediarender -f Test -u 42 --logfile /dev/stdout&lt;br /&gt;
&lt;br /&gt;
Configure in /etc/default/gmediarender. Don't use &amp;quot;special&amp;quot; characters like umlaut. Startup will quit with an error message. Seems gmediarender still not understand UTF-8 :-(&lt;br /&gt;
&lt;br /&gt;
Start gmediarender as service:&lt;br /&gt;
 '''pi@raspberrypi:~ $''' sudo systemctl enable gmediarender.service&lt;br /&gt;
 '''pi@raspberrypi:~ $''' sudo systemctl start gmediarender.service&lt;br /&gt;
 '''pi@raspberrypi:~ $''' &lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry Pi]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=Kategorie:Raspberry_Pi&amp;diff=24</id>
		<title>Kategorie:Raspberry Pi</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=Kategorie:Raspberry_Pi&amp;diff=24"/>
				<updated>2017-10-24T23:26:57Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: create page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Everything to Raspberry Pi&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=Raspberry_Pi_as_UPnP_renderer&amp;diff=23</id>
		<title>Raspberry Pi as UPnP renderer</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=Raspberry_Pi_as_UPnP_renderer&amp;diff=23"/>
				<updated>2017-10-24T22:32:23Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: create page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Date: 2017-10-24&lt;br /&gt;
&lt;br /&gt;
I setup a multiroom music playing environment. For this I use Raspberry Pis for renderer in a room. Here I found a [https://joachim-wilke.de/blog/2016/07/10/UPNP-Renderer-auf-dem-Raspberry-Pi/ somewhat outdated howto] but it points me in the right direction. Here is howto install it.&lt;br /&gt;
&lt;br /&gt;
We use [https://github.com/hzeller/gmrender-resurrect gmrender-resurrect] which is available in the repository. Install it on a RasPi with needed plugins.&lt;br /&gt;
&lt;br /&gt;
 '''pi@raspberrypi:~ $''' sudo apt install gmediarender gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-alsa&lt;br /&gt;
 '''pi@raspberrypi:~ $'''&lt;br /&gt;
&lt;br /&gt;
Test installation with&lt;br /&gt;
 '''pi@raspberrypi:~ $''' /usr/bin/gmediarender -f Test -u 42 --logfile /dev/stdout&lt;br /&gt;
&lt;br /&gt;
Configure in /etc/default/gmediasrender. Don't use &amp;quot;special&amp;quot; characters like umlaut. Startup will quit with an error message. Seems gmediarender still not understand UTF-8 :-(&lt;br /&gt;
&lt;br /&gt;
Start gmediarender as service:&lt;br /&gt;
 '''pi@raspberrypi:~ $''' sudo systemctl enable gmediarender.service&lt;br /&gt;
 '''pi@raspberrypi:~ $''' sudo systemctl start gmediarender.service&lt;br /&gt;
 '''pi@raspberrypi:~ $''' &lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry Pi]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=22</id>
		<title>VLAN for virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=22"/>
				<updated>2017-09-28T15:41:56Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: bug is fixed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
I wanted to update VLAN connections for virtual&lt;br /&gt;
machines to newer technologies and put a question on&lt;br /&gt;
[https://unix.stackexchange.com/questions/392758/setup-vlan-on-linux-bridge-for-virtual-machines-with-systemd unix.stackexchange]. But I do not get any answer. It seems there is very&lt;br /&gt;
little knowledge for this out there. So I decided to work on it by myself&lt;br /&gt;
and document it here.&lt;br /&gt;
&lt;br /&gt;
In gerneral I will look at three methods:&lt;br /&gt;
# [[#oldstyle linux bridge as hub|oldstyle linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge as hub|linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge with libvirt hook scripts|linux bridge with libvirt hook scripts]]&lt;br /&gt;
&lt;br /&gt;
== Preparation ==&lt;br /&gt;
I have Debian GNU/Linux 9.1 (stretch) on the host and on virtual machines for testing. Setup is described here: [[Setup KVM with console]]. I'm sitting on harley as host, my all day workstation.&lt;br /&gt;
Now I start the virtual machine, login and show its interface setting:&lt;br /&gt;
 '''harley$''' virsh start --console deb9-test&lt;br /&gt;
login&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/08-vlan10.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 Kind=vlan&lt;br /&gt;
 [VLAN]&lt;br /&gt;
 Id=10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/12-vlan10_attach-to-if.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=ens2&lt;br /&gt;
 [Network]&lt;br /&gt;
 VLAN=vlan10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/16-vlan10_up.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 [Network]&lt;br /&gt;
 DHCP=ipv4&lt;br /&gt;
 IPv6AcceptRA=no&lt;br /&gt;
 LinkLocalAddressing=no&lt;br /&gt;
To test if the virtual machine has connection I use:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:34:20 CEST. --&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: Enumeration completed&lt;br /&gt;
 Sep 23 20:34:05 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: DHCPv4 address 192.168.10.89/24 via 192.168.10.1&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: Configured&lt;br /&gt;
 Sep 23 20:34:19 systemd-networkd[204]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
4 sec after Started Network Service it gets an IP-Address and 14 sec later interface ens2 was Configured. If ens2 is Configured and the guest hasn't got an IP-Address the connection failed. It looks like this:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:45:13 CEST. --&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: Enumeration completed&lt;br /&gt;
 Sep 23 20:44:59 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:13 systemd-networkd[197]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
&lt;br /&gt;
Because I have to start the test virtual machine many times I setup autologin. It's no problem. There is nothing on the guest.&lt;br /&gt;
 '''deb9-test$''' grep ^ExecStart= /lib/systemd/system/serial-getty@.service&lt;br /&gt;
 ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
modify to&lt;br /&gt;
 ExecStart=-/sbin/agetty --autologin ''yourloginname'' --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
&amp;lt;span id=&amp;quot;bridge-settings&amp;quot;&amp;gt;To list all settings of the bridge&amp;lt;/span&amp;gt; you can use:&lt;br /&gt;
 '''harley$''' find /sys/class/net/br0/bridge/ -type f -readable -printf '%f = ' -exec cat {} \; | sort&lt;br /&gt;
&lt;br /&gt;
== oldstyle linux bridge as hub ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Disable systemd-networkd and start networking with ifupdown:&lt;br /&gt;
 '''harley$''' sudo systemctl stop systemd-networkd&lt;br /&gt;
 Warning: Stopping systemd-networkd.service, but it can still be activated by:&lt;br /&gt;
   systemd-networkd.socket&lt;br /&gt;
 '''harley$''' sudo systemctl disable systemd-networkd&lt;br /&gt;
 Removed /etc/systemd/system/multi-user.target.wants/systemd-networkd.service.&lt;br /&gt;
 Removed /etc/systemd/system/sockets.target.wants/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install enable networking&lt;br /&gt;
 '''harley$''' sudo systemctl start networking.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/network/interfaces&lt;br /&gt;
 auto br0&lt;br /&gt;
 iface br0 inet manual&lt;br /&gt;
     bridge_ports enp1s0&lt;br /&gt;
     bridge_ageing 0&lt;br /&gt;
     bridge_stp off&lt;br /&gt;
 '''harley$''' sudo ifup br0&lt;br /&gt;
 Waiting for br0 to get ready (MAXWAIT is 32 seconds).&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
It's all in place now:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
Yes, there is no VLAN filtering, means VLAN on the bridge is disabled but the guest sees the VLAN-tagged packets.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://wiki.debian.org/NetworkConfiguration#Bridging_without_Switching&lt;br /&gt;
&lt;br /&gt;
== linux bridge as hub ==&lt;br /&gt;
Now I try to setup [[#oldstyle linux bridge as hub]] just with systemd-networkd.&lt;br /&gt;
&lt;br /&gt;
Disable networking with ifupdown and start systemd-networkd:&lt;br /&gt;
 '''harley$''' sudo systemctl stop networking.service&lt;br /&gt;
 '''harley$''' sudo systemctl disable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install disable networking&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable systemd-networkd&lt;br /&gt;
 Created symlink /etc/systemd/system/multi-user.target.wants/systemd-networkd.service → /lib/systemd/system/systemd-networkd.service.&lt;br /&gt;
 Created symlink /etc/systemd/system/sockets.target.wants/systemd-networkd.socket → /lib/systemd/system/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo systemctl start systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/08-br0.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 AgeingTimeSec=0&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/12-br0_add-enp1s0.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl restart systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
AgeingTimeSec=0 is not acepted but should:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 30000   (means 300 sec)&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
But I've found a workaround. Useing a number between '''.'''01 and '''.'''000001 (there are dots) will set ageing_time to 0.&lt;br /&gt;
So set AgeingTimeSec='''.'''000001 in /etc/systemd/network/08-br0.netdev. I suppose it's a bug. Then we&lt;br /&gt;
will get:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets now an IP-Address on boot and is connected to VLAN 10.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
This works because of [[#References|three conditions]].&lt;br /&gt;
# ageing time is 0: ageing time specifies the number of seconds a MAC Address will be kept in the forwarding database after having a packet received from this MAC Address. Setting it to 0 means there is never a MAC Address stored in the FDB.&lt;br /&gt;
# unicast flood on interfaces is on: this controls whether the bridge should flood traffic for which an FDB entry is missing and the destination is unknown through this port. Defaults to on.&lt;br /&gt;
# spanning tree protocol (stp) is disabled: we don't have a forward_delay at startup for the learning phase of spanning tree.&lt;br /&gt;
I have a running and connected virtual machine:&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   1 PVID Egress Untagged&lt;br /&gt;
 br0      1 PVID Egress Untagged&lt;br /&gt;
 vnet0    1 PVID Egress Untagged&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time&lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/forward_delay&lt;br /&gt;
 1500&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state&lt;br /&gt;
 0&lt;br /&gt;
Indeed we have forward_delay 1500 (means 15 sec) but it doesn't matter. stp_state is 0 (disabled), no spanning tree. Flood (means unicast flood) is on as I can see:&lt;br /&gt;
 '''harley$''' sudo bridge -d link show&lt;br /&gt;
 ''3: enp1s0'' state UP : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 4&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on &lt;br /&gt;
 ''95: vnet0'' state UNKNOWN : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 100&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let's have a look at flooding on the interfaces. I disable it on the physical interface enp1s0 of the bridge and reboot the guest:&lt;br /&gt;
 '''harley$''' sudo bridge link set dev enp1s0 flood off&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets an IP-Address from the DHCP-Server but then can't ping its gateway. DHCP-REQUEST is broadcast and goes thru enp1s0. DHCP-ANSWER comes back thru it to any other (here only vnet0) interface which has flood on. Ping is unicast and isn't forwareded on enp1s0. If I set  enp1s0 flood on and vnet0 flood off and &amp;lt;code&amp;gt;'''deb9-test$ '''sudo systemctl restart systemd-networkd&amp;lt;/code&amp;gt;, I get no IP-Address from DHCP-Server and can't ping the interface. Incoming DHCP-ANSWER isn't broadcast and vnet0 doesn't forward it to the guest.&lt;br /&gt;
&lt;br /&gt;
Btw. this method has bad performance as we can see with monitor. We insert MAC-Addresses into FDB for just deleting it immediately, all for nothing.&lt;br /&gt;
 '''harley$''' sudo bridge monitor fdb&lt;br /&gt;
 52:54:00:01:76:20 dev enp1s0 master br0 &lt;br /&gt;
 52:54:00:b0:ca:63 dev vnet0 master br0 &lt;br /&gt;
 f4:f2:6d:2c:87:f7 dev enp1s0 master br0 &lt;br /&gt;
 00:80:3f:2a:31:1a dev enp1s0 master br0 &lt;br /&gt;
 Deleted 52:54:00:01:76:20 dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted 52:54:00:b0:ca:63 dev vnet0 master br0 stale&lt;br /&gt;
 Deleted 00:80:3f:2a:31:1a dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted f4:f2:6d:2c:87:f7 dev enp1s0 master br0 stale&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.netdev.html&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.network.html&lt;br /&gt;
&lt;br /&gt;
== linux bridge with libvirt hook scripts ==&lt;br /&gt;
We setup a bridge with VLAN enabled:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/08-br0.netdev &lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 DefaultPVID=none&lt;br /&gt;
 VLANFiltering=true&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/12-br0_add-enp1s0.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=10&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=20&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=30&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
With this I get:&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   1 PVID Egress Untagged&lt;br /&gt;
          10&lt;br /&gt;
          20&lt;br /&gt;
          30  &lt;br /&gt;
 br0      1 PVID Egress Untagged&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
But what is this? We have default VLAN &amp;lt;code&amp;gt;1 PVID Egress Untagged&amp;lt;/code&amp;gt;. I don't want this. Seems setting &amp;lt;code&amp;gt;DefaultPVID=none&amp;lt;/code&amp;gt; in 08-br0.netdev doesn't work. I've made a [[#Workaround for setting DefaultPVID=none|Workaround for setting DefaultPVID=none]]. Looking at this behavior I found that we can set &amp;lt;code&amp;gt;default_pvid&amp;lt;/code&amp;gt; in the kernel only if &amp;lt;code&amp;gt;vlan_filtering = 0&amp;lt;/code&amp;gt;. By hand I have to do:&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/default_pvid'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 1 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
If I start a guest I will get now:&lt;br /&gt;
 '''harley$''' virsh start deb9-test&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   10&lt;br /&gt;
          20&lt;br /&gt;
          30&lt;br /&gt;
 br0     None&lt;br /&gt;
 vnet0   None&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The virtual network interface vnet0 for deb9-test has no VLAN ID. Libvirt does not know something about this so we have to tell it. Libvirt provides [https://www.libvirt.org/hooks.html hook scripts] that we can use for this. We have to:&lt;br /&gt;
# [[#define VLAN-ID the virtual machine belongs to]]&lt;br /&gt;
# [[#get information on startup from the runtime XML-config of the domain]]&lt;br /&gt;
# [[#set VLAN-ID to the dynamic virtual network interface vnet*]]&lt;br /&gt;
&amp;lt;span id=&amp;quot;debug.sh&amp;quot;&amp;gt;For debugging the hook-scripts&amp;lt;/span&amp;gt; I've made a small script:&lt;br /&gt;
 '''harley$''' cat /etc/libvirt/hooks/debug.sh&lt;br /&gt;
 #!/bin/bash -e&lt;br /&gt;
 # https://www.libvirt.org/hooks.html&lt;br /&gt;
 # If you make a new hook script then 'sudo systemctl restart libvirtd'.&lt;br /&gt;
 # For debug set symlink to hook-script daemon, qemu, lxc, libxl and/or network,&lt;br /&gt;
 # e.g. 'sudo ln -s debug.sh qemu' and restart libvirtd.&lt;br /&gt;
 &lt;br /&gt;
 logfile='/var/log/libvirt/hooks.log'&lt;br /&gt;
 &lt;br /&gt;
 echo &amp;quot;$0&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 date -Iseconds &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 echo &amp;quot;\$1=$1, \$2=$2, \$3=$3, \$4=$4&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 cat - &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 echo -e &amp;quot;\n---------------------------------------------&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== define VLAN-ID the virtual machine belongs to ===&lt;br /&gt;
For this we have an extra [https://libvirt.org/formatdomain.html#elementsMetadata element &amp;lt;metadata&amp;gt; in Domain XML format] for custom metadata. We can simply add the information to the static configuration with &amp;lt;code&amp;gt;'''harley$''' virsh edit deb9-test&amp;lt;/code&amp;gt; like this (look only at the &amp;lt;metadata&amp;gt; element):&lt;br /&gt;
 '''harley$''' virsh dumpxml deb9-test | head -n9&lt;br /&gt;
 &amp;lt;domain type='kvm' id='1'&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;deb9-test&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;uuid&amp;gt;70d56a28-795d-4010-9403-513a4bd6b66a&amp;lt;/uuid&amp;gt;&lt;br /&gt;
   &amp;lt;metadata&amp;gt;&lt;br /&gt;
     &amp;lt;my:home xmlns:my=&amp;quot;http://hoeft-online.de/my/&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;my:vlan&amp;gt;10&amp;lt;/my:vlan&amp;gt;&lt;br /&gt;
     &amp;lt;/my:home&amp;gt;&lt;br /&gt;
   &amp;lt;/metadata&amp;gt;&lt;br /&gt;
   &amp;lt;memory unit='KiB'&amp;gt;1048576&amp;lt;/memory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get information on startup from the runtime XML-config of the domain ===&lt;br /&gt;
It seems a little bit difficult to get needed information out of the big XML-config but it's no problem with XSLT. I've made a XSL-stylesheet for this and use xmlstarlet. Start a virtual machine and then its runtime configuration is available with &amp;lt;code&amp;gt;'''harley$''' virsh dumpxml deb9-test | xmlstarlet tr qemu.xsl&amp;lt;/code&amp;gt;. With this I can test my stylesheet. Here is it:&lt;br /&gt;
 '''harley$''' cat /etc/libvirt/hooks/qemu.xsl &lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;amp;lt;!-- This stylesheet extracts the VLAN-ID and the target device of the&lt;br /&gt;
      bridge from the domain-xml given to the libvirt hook-script &amp;quot;qemu&amp;quot;.&lt;br /&gt;
      Example output: &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;&lt;br /&gt;
 --&amp;amp;gt;&lt;br /&gt;
 &amp;lt;xsl:stylesheet version=&amp;quot;1.0&amp;quot; xmlns:xsl=&amp;quot;http://www.w3.org/1999/XSL/Transform&amp;quot;&lt;br /&gt;
      xmlns:my=&amp;quot;http://hoeft-online.de/my/&amp;quot; exclude-result-prefixes=&amp;quot;my&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:output omit-xml-declaration=&amp;quot;yes&amp;quot; indent=&amp;quot;no&amp;quot;&lt;br /&gt;
        encoding=&amp;quot;utf-8&amp;quot; media-type=&amp;quot;text/xml&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:strip-space elements=&amp;quot;*&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;text()|@*&amp;quot;/&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;/domain&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;meta&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:apply-templates/&amp;gt;&lt;br /&gt;
     &amp;lt;/meta&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;metadata/my:home/my:vlan&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;vlan&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:value-of select=&amp;quot;.&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;/vlan&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match='interface[@type=&amp;quot;bridge&amp;quot;]/target'&amp;gt;&lt;br /&gt;
     &amp;lt;dev&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:value-of select=&amp;quot;@dev&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;/dev&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;/xsl:stylesheet&amp;gt;&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
 '''harley$''' virsh dumpxml deb9-test | xmlstarlet tr /etc/libvirt/hooks/qemu.xsl &lt;br /&gt;
 &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;'''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== set VLAN-ID to the dynamic virtual network interface vnet* ===&lt;br /&gt;
Putting it all together here is the executable hook-script:&lt;br /&gt;
 '''harley$''' cat /etc/libvirt/hooks/qemu&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #/etc/libvirt/hooks/qemu&lt;br /&gt;
 # Docs: https://www.libvirt.org/hooks.html&lt;br /&gt;
 # If you make a new hook script then 'sudo systemctl restart libvirtd'.&lt;br /&gt;
 &lt;br /&gt;
 # On startup of the domain (guest) This script does:&lt;br /&gt;
 # Get Metadata VLAN-ID of the guest and target device of the bridge from&lt;br /&gt;
     # the domain-xml available on standard input. It is the runtime&lt;br /&gt;
     # version from 'virsh dumpxml domainname'. For extracting the&lt;br /&gt;
     # information we use a XSL-stylesheet. Example input into $META:&lt;br /&gt;
     # &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;&lt;br /&gt;
 # Select $DEV  from $META&lt;br /&gt;
 # Select $VLAN from $META&lt;br /&gt;
 # Set $VLAN to $DEV on the bridge&lt;br /&gt;
 &lt;br /&gt;
 case &amp;quot;$2&amp;quot; in&lt;br /&gt;
   prepare)&lt;br /&gt;
     ;;&lt;br /&gt;
   start)&lt;br /&gt;
     META=$(/usr/bin/xmlstarlet tr /etc/libvirt/hooks/qemu.xsl -)&lt;br /&gt;
     DEV=$(echo &amp;quot;$META&amp;quot; | /usr/bin/xmlstarlet sel -t -v '/meta/dev')&lt;br /&gt;
     VLAN=$(echo &amp;quot;$META&amp;quot; | /usr/bin/xmlstarlet sel -t -v '/meta/vlan')&lt;br /&gt;
     if &amp;amp;#91;[ -n $DEV &amp;amp;&amp;amp; -n $VLAN ]&amp;amp;#93;; then&lt;br /&gt;
       /sbin/bridge vlan add vid &amp;quot;$VLAN&amp;quot; dev &amp;quot;$DEV&amp;quot;&lt;br /&gt;
     fi&lt;br /&gt;
     ;;&lt;br /&gt;
   started)&lt;br /&gt;
     ;;&lt;br /&gt;
   stopped)&lt;br /&gt;
     ;;&lt;br /&gt;
   release)&lt;br /&gt;
     ;;&lt;br /&gt;
   migrate)&lt;br /&gt;
     ;;&lt;br /&gt;
   restore)&lt;br /&gt;
     ;;&lt;br /&gt;
   reconnect)&lt;br /&gt;
     ;;&lt;br /&gt;
   attach)&lt;br /&gt;
     ;;&lt;br /&gt;
   *)&lt;br /&gt;
     echo &amp;quot;qemu hook called with unexpected options $*&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
     exit 1&lt;br /&gt;
     ;;&lt;br /&gt;
 esac&lt;br /&gt;
 '''harley$''' sudo chmod 744 /etc/libvirt/hooks/qemu&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.libvirt.org/hooks.html&lt;br /&gt;
* https://serverfault.com/questions/696011/libvirt-hook-qemu-suse12&lt;br /&gt;
&lt;br /&gt;
== Workaround for setting DefaultPVID=none ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;We do not need it anymore. This bug is fixed in systemd 234.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Setting [https://www.freedesktop.org/software/systemd/man/systemd.netdev.html#DefaultPVID= DefaultPVID] in a&amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt; configuration file to &amp;quot;none&amp;quot; does not work. Until this bug is fixed I've made a workaround. The kernel accepts setting &amp;lt;code&amp;gt;default_pvid&amp;lt;/code&amp;gt; to 0 (means &amp;quot;none&amp;quot;) only if &amp;lt;code&amp;gt;vlan_filtering=0&amp;lt;/code&amp;gt;, so we have to do:&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/default_pvid'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 1 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Check with listing of [[#bridge-settings|bridge-settings]].&lt;br /&gt;
Theese commands must run with &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt; so we need a service for this. First I make a script and make it executable for root:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/DefaultPVID.sh &lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #echo &amp;quot;entering DefaultPVID.sh&amp;quot; &amp;gt;&amp;gt;/tmp/debug.log&lt;br /&gt;
 &lt;br /&gt;
 BRDIR=&amp;quot;/sys/class/net/br0/bridge/&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 if &amp;amp;#91;[ -f $BRDIR/vlan_filtering &amp;amp;&amp;amp; -f $BRDIR/default_pvid ]&amp;amp;#93;; then&lt;br /&gt;
   #echo &amp;quot;setting DefaultPVID&amp;quot; &amp;gt;&amp;gt;/tmp/debug.log&lt;br /&gt;
   VLAN_FILTERING=&amp;quot;$(cat &amp;quot;$BRDIR&amp;quot;/vlan_filtering)&amp;quot;&lt;br /&gt;
   echo 0 &amp;gt;&amp;quot;$BRDIR&amp;quot;/vlan_filtering&lt;br /&gt;
   echo 0 &amp;gt;&amp;quot;$BRDIR&amp;quot;/default_pvid&lt;br /&gt;
   echo &amp;quot;$VLAN_FILTERING&amp;quot; &amp;gt;&amp;quot;$BRDIR&amp;quot;/vlan_filtering&lt;br /&gt;
 fi&lt;br /&gt;
 exit 0&lt;br /&gt;
 '''harley$''' sudo chmod 744 /etc/systemd/network/DefaultPVID.sh&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Test with &amp;lt;code&amp;gt;'''harley$''' sudo /etc/systemd/network/DefaultPVID.sh&amp;lt;/code&amp;gt;. Next I create a service to execute this script:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/system/DefaultPVID.service &lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=set DefaultPVID on a bridge as workaround&lt;br /&gt;
 Wants=network.target&lt;br /&gt;
 After=network.target&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 Type=oneshot&lt;br /&gt;
 ExecStart=/etc/systemd/network/DefaultPVID.sh&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Test with &amp;lt;code&amp;gt;'''harley$''' sudo systemctl start DefaultPVID.service &amp;amp;&amp;amp; systemctl status DefaultPVID.service&amp;lt;/code&amp;gt;. After this I create a [https://www.freedesktop.org/software/systemd/man/systemd.unit.html#id-1.11.3 drop-in file for overriding vendor settings] so this service will be executed together with &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt;:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/system/systemd-networkd.service.d/DefaultPVID.conf &lt;br /&gt;
 [Unit]&lt;br /&gt;
 # This is only a workaround. DefaultPVID cannot be set in&lt;br /&gt;
 # /etc/systemd/network/br0.netdev. It seems buggy.&lt;br /&gt;
 Wants=DefaultPVID.service&lt;br /&gt;
 Before=DefaultPVID.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Test with &amp;lt;code&amp;gt;'''harley$''' sudo systemctl restart systemd-networkd&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=21</id>
		<title>VLAN for virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=21"/>
				<updated>2017-09-28T08:23:49Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: state Workaround for DefaultPVID more precisely&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
I wanted to update VLAN connections for virtual&lt;br /&gt;
machines to newer technologies and put a question on&lt;br /&gt;
[https://unix.stackexchange.com/questions/392758/setup-vlan-on-linux-bridge-for-virtual-machines-with-systemd unix.stackexchange]. But I do not get any answer. It seems there is very&lt;br /&gt;
little knowledge for this out there. So I decided to work on it by myself&lt;br /&gt;
and document it here.&lt;br /&gt;
&lt;br /&gt;
In gerneral I will look at three methods:&lt;br /&gt;
# [[#oldstyle linux bridge as hub|oldstyle linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge as hub|linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge with libvirt hook scripts|linux bridge with libvirt hook scripts]]&lt;br /&gt;
&lt;br /&gt;
== Preparation ==&lt;br /&gt;
I have Debian GNU/Linux 9.1 (stretch) on the host and on virtual machines for testing. Setup is described here: [[Setup KVM with console]]. I'm sitting on harley as host, my all day workstation.&lt;br /&gt;
Now I start the virtual machine, login and show its interface setting:&lt;br /&gt;
 '''harley$''' virsh start --console deb9-test&lt;br /&gt;
login&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/08-vlan10.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 Kind=vlan&lt;br /&gt;
 [VLAN]&lt;br /&gt;
 Id=10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/12-vlan10_attach-to-if.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=ens2&lt;br /&gt;
 [Network]&lt;br /&gt;
 VLAN=vlan10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/16-vlan10_up.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 [Network]&lt;br /&gt;
 DHCP=ipv4&lt;br /&gt;
 IPv6AcceptRA=no&lt;br /&gt;
 LinkLocalAddressing=no&lt;br /&gt;
To test if the virtual machine has connection I use:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:34:20 CEST. --&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: Enumeration completed&lt;br /&gt;
 Sep 23 20:34:05 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: DHCPv4 address 192.168.10.89/24 via 192.168.10.1&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: Configured&lt;br /&gt;
 Sep 23 20:34:19 systemd-networkd[204]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
4 sec after Started Network Service it gets an IP-Address and 14 sec later interface ens2 was Configured. If ens2 is Configured and the guest hasn't got an IP-Address the connection failed. It looks like this:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:45:13 CEST. --&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: Enumeration completed&lt;br /&gt;
 Sep 23 20:44:59 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:13 systemd-networkd[197]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
&lt;br /&gt;
Because I have to start the test virtual machine many times I setup autologin. It's no problem. There is nothing on the guest.&lt;br /&gt;
 '''deb9-test$''' grep ^ExecStart= /lib/systemd/system/serial-getty@.service&lt;br /&gt;
 ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
modify to&lt;br /&gt;
 ExecStart=-/sbin/agetty --autologin ''yourloginname'' --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
&amp;lt;span id=&amp;quot;bridge-settings&amp;quot;&amp;gt;To list all settings of the bridge&amp;lt;/span&amp;gt; you can use:&lt;br /&gt;
 '''harley$''' find /sys/class/net/br0/bridge/ -type f -readable -printf '%f = ' -exec cat {} \; | sort&lt;br /&gt;
&lt;br /&gt;
== oldstyle linux bridge as hub ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Disable systemd-networkd and start networking with ifupdown:&lt;br /&gt;
 '''harley$''' sudo systemctl stop systemd-networkd&lt;br /&gt;
 Warning: Stopping systemd-networkd.service, but it can still be activated by:&lt;br /&gt;
   systemd-networkd.socket&lt;br /&gt;
 '''harley$''' sudo systemctl disable systemd-networkd&lt;br /&gt;
 Removed /etc/systemd/system/multi-user.target.wants/systemd-networkd.service.&lt;br /&gt;
 Removed /etc/systemd/system/sockets.target.wants/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install enable networking&lt;br /&gt;
 '''harley$''' sudo systemctl start networking.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/network/interfaces&lt;br /&gt;
 auto br0&lt;br /&gt;
 iface br0 inet manual&lt;br /&gt;
     bridge_ports enp1s0&lt;br /&gt;
     bridge_ageing 0&lt;br /&gt;
     bridge_stp off&lt;br /&gt;
 '''harley$''' sudo ifup br0&lt;br /&gt;
 Waiting for br0 to get ready (MAXWAIT is 32 seconds).&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
It's all in place now:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
Yes, there is no VLAN filtering, means VLAN on the bridge is disabled but the guest sees the VLAN-tagged packets.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://wiki.debian.org/NetworkConfiguration#Bridging_without_Switching&lt;br /&gt;
&lt;br /&gt;
== linux bridge as hub ==&lt;br /&gt;
Now I try to setup [[#oldstyle linux bridge as hub]] just with systemd-networkd.&lt;br /&gt;
&lt;br /&gt;
Disable networking with ifupdown and start systemd-networkd:&lt;br /&gt;
 '''harley$''' sudo systemctl stop networking.service&lt;br /&gt;
 '''harley$''' sudo systemctl disable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install disable networking&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable systemd-networkd&lt;br /&gt;
 Created symlink /etc/systemd/system/multi-user.target.wants/systemd-networkd.service → /lib/systemd/system/systemd-networkd.service.&lt;br /&gt;
 Created symlink /etc/systemd/system/sockets.target.wants/systemd-networkd.socket → /lib/systemd/system/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo systemctl start systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/08-br0.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 AgeingTimeSec=0&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/12-br0_add-enp1s0.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl restart systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
AgeingTimeSec=0 is not acepted but should:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 30000   (means 300 sec)&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
But I've found a workaround. Useing a number between '''.'''01 and '''.'''000001 (there are dots) will set ageing_time to 0.&lt;br /&gt;
So set AgeingTimeSec='''.'''000001 in /etc/systemd/network/08-br0.netdev. I suppose it's a bug. Then we&lt;br /&gt;
will get:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets now an IP-Address on boot and is connected to VLAN 10.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
This works because of [[#References|three conditions]].&lt;br /&gt;
# ageing time is 0: ageing time specifies the number of seconds a MAC Address will be kept in the forwarding database after having a packet received from this MAC Address. Setting it to 0 means there is never a MAC Address stored in the FDB.&lt;br /&gt;
# unicast flood on interfaces is on: this controls whether the bridge should flood traffic for which an FDB entry is missing and the destination is unknown through this port. Defaults to on.&lt;br /&gt;
# spanning tree protocol (stp) is disabled: we don't have a forward_delay at startup for the learning phase of spanning tree.&lt;br /&gt;
I have a running and connected virtual machine:&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   1 PVID Egress Untagged&lt;br /&gt;
 br0      1 PVID Egress Untagged&lt;br /&gt;
 vnet0    1 PVID Egress Untagged&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time&lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/forward_delay&lt;br /&gt;
 1500&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state&lt;br /&gt;
 0&lt;br /&gt;
Indeed we have forward_delay 1500 (means 15 sec) but it doesn't matter. stp_state is 0 (disabled), no spanning tree. Flood (means unicast flood) is on as I can see:&lt;br /&gt;
 '''harley$''' sudo bridge -d link show&lt;br /&gt;
 ''3: enp1s0'' state UP : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 4&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on &lt;br /&gt;
 ''95: vnet0'' state UNKNOWN : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 100&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let's have a look at flooding on the interfaces. I disable it on the physical interface enp1s0 of the bridge and reboot the guest:&lt;br /&gt;
 '''harley$''' sudo bridge link set dev enp1s0 flood off&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets an IP-Address from the DHCP-Server but then can't ping its gateway. DHCP-REQUEST is broadcast and goes thru enp1s0. DHCP-ANSWER comes back thru it to any other (here only vnet0) interface which has flood on. Ping is unicast and isn't forwareded on enp1s0. If I set  enp1s0 flood on and vnet0 flood off and &amp;lt;code&amp;gt;'''deb9-test$ '''sudo systemctl restart systemd-networkd&amp;lt;/code&amp;gt;, I get no IP-Address from DHCP-Server and can't ping the interface. Incoming DHCP-ANSWER isn't broadcast and vnet0 doesn't forward it to the guest.&lt;br /&gt;
&lt;br /&gt;
Btw. this method has bad performance as we can see with monitor. We insert MAC-Addresses into FDB for just deleting it immediately, all for nothing.&lt;br /&gt;
 '''harley$''' sudo bridge monitor fdb&lt;br /&gt;
 52:54:00:01:76:20 dev enp1s0 master br0 &lt;br /&gt;
 52:54:00:b0:ca:63 dev vnet0 master br0 &lt;br /&gt;
 f4:f2:6d:2c:87:f7 dev enp1s0 master br0 &lt;br /&gt;
 00:80:3f:2a:31:1a dev enp1s0 master br0 &lt;br /&gt;
 Deleted 52:54:00:01:76:20 dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted 52:54:00:b0:ca:63 dev vnet0 master br0 stale&lt;br /&gt;
 Deleted 00:80:3f:2a:31:1a dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted f4:f2:6d:2c:87:f7 dev enp1s0 master br0 stale&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.netdev.html&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.network.html&lt;br /&gt;
&lt;br /&gt;
== linux bridge with libvirt hook scripts ==&lt;br /&gt;
We setup a bridge with VLAN enabled:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/08-br0.netdev &lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 DefaultPVID=none&lt;br /&gt;
 VLANFiltering=true&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/12-br0_add-enp1s0.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=10&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=20&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=30&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
With this I get:&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   1 PVID Egress Untagged&lt;br /&gt;
          10&lt;br /&gt;
          20&lt;br /&gt;
          30  &lt;br /&gt;
 br0      1 PVID Egress Untagged&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
But what is this? We have default VLAN &amp;lt;code&amp;gt;1 PVID Egress Untagged&amp;lt;/code&amp;gt;. I don't want this. Seems setting &amp;lt;code&amp;gt;DefaultPVID=none&amp;lt;/code&amp;gt; in 08-br0.netdev doesn't work. I've made a [[#Workaround for setting DefaultPVID=none|Workaround for setting DefaultPVID=none]]. Looking at this behavior I found that we can set &amp;lt;code&amp;gt;default_pvid&amp;lt;/code&amp;gt; in the kernel only if &amp;lt;code&amp;gt;vlan_filtering = 0&amp;lt;/code&amp;gt;. By hand I have to do:&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/default_pvid'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 1 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
If I start a guest I will get now:&lt;br /&gt;
 '''harley$''' virsh start deb9-test&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   10&lt;br /&gt;
          20&lt;br /&gt;
          30&lt;br /&gt;
 br0     None&lt;br /&gt;
 vnet0   None&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The virtual network interface vnet0 for deb9-test has no VLAN ID. Libvirt does not know something about this so we have to tell it. Libvirt provides [https://www.libvirt.org/hooks.html hook scripts] that we can use for this. We have to:&lt;br /&gt;
# [[#define VLAN-ID the virtual machine belongs to]]&lt;br /&gt;
# [[#get information on startup from the runtime XML-config of the domain]]&lt;br /&gt;
# [[#set VLAN-ID to the dynamic virtual network interface vnet*]]&lt;br /&gt;
&amp;lt;span id=&amp;quot;debug.sh&amp;quot;&amp;gt;For debugging the hook-scripts&amp;lt;/span&amp;gt; I've made a small script:&lt;br /&gt;
 '''harley$''' cat /etc/libvirt/hooks/debug.sh&lt;br /&gt;
 #!/bin/bash -e&lt;br /&gt;
 # https://www.libvirt.org/hooks.html&lt;br /&gt;
 # If you make a new hook script then 'sudo systemctl restart libvirtd'.&lt;br /&gt;
 # For debug set symlink to hook-script daemon, qemu, lxc, libxl and/or network,&lt;br /&gt;
 # e.g. 'sudo ln -s debug.sh qemu' and restart libvirtd.&lt;br /&gt;
 &lt;br /&gt;
 logfile='/var/log/libvirt/hooks.log'&lt;br /&gt;
 &lt;br /&gt;
 echo &amp;quot;$0&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 date -Iseconds &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 echo &amp;quot;\$1=$1, \$2=$2, \$3=$3, \$4=$4&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 cat - &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 echo -e &amp;quot;\n---------------------------------------------&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== define VLAN-ID the virtual machine belongs to ===&lt;br /&gt;
For this we have an extra [https://libvirt.org/formatdomain.html#elementsMetadata element &amp;lt;metadata&amp;gt; in Domain XML format] for custom metadata. We can simply add the information to the static configuration with &amp;lt;code&amp;gt;'''harley$''' virsh edit deb9-test&amp;lt;/code&amp;gt; like this (look only at the &amp;lt;metadata&amp;gt; element):&lt;br /&gt;
 '''harley$''' virsh dumpxml deb9-test | head -n9&lt;br /&gt;
 &amp;lt;domain type='kvm' id='1'&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;deb9-test&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;uuid&amp;gt;70d56a28-795d-4010-9403-513a4bd6b66a&amp;lt;/uuid&amp;gt;&lt;br /&gt;
   &amp;lt;metadata&amp;gt;&lt;br /&gt;
     &amp;lt;my:home xmlns:my=&amp;quot;http://hoeft-online.de/my/&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;my:vlan&amp;gt;10&amp;lt;/my:vlan&amp;gt;&lt;br /&gt;
     &amp;lt;/my:home&amp;gt;&lt;br /&gt;
   &amp;lt;/metadata&amp;gt;&lt;br /&gt;
   &amp;lt;memory unit='KiB'&amp;gt;1048576&amp;lt;/memory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get information on startup from the runtime XML-config of the domain ===&lt;br /&gt;
It seems a little bit difficult to get needed information out of the big XML-config but it's no problem with XSLT. I've made a XSL-stylesheet for this and use xmlstarlet. Start a virtual machine and then its runtime configuration is available with &amp;lt;code&amp;gt;'''harley$''' virsh dumpxml deb9-test | xmlstarlet tr qemu.xsl&amp;lt;/code&amp;gt;. With this I can test my stylesheet. Here is it:&lt;br /&gt;
 '''harley$''' cat /etc/libvirt/hooks/qemu.xsl &lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;amp;lt;!-- This stylesheet extracts the VLAN-ID and the target device of the&lt;br /&gt;
      bridge from the domain-xml given to the libvirt hook-script &amp;quot;qemu&amp;quot;.&lt;br /&gt;
      Example output: &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;&lt;br /&gt;
 --&amp;amp;gt;&lt;br /&gt;
 &amp;lt;xsl:stylesheet version=&amp;quot;1.0&amp;quot; xmlns:xsl=&amp;quot;http://www.w3.org/1999/XSL/Transform&amp;quot;&lt;br /&gt;
      xmlns:my=&amp;quot;http://hoeft-online.de/my/&amp;quot; exclude-result-prefixes=&amp;quot;my&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:output omit-xml-declaration=&amp;quot;yes&amp;quot; indent=&amp;quot;no&amp;quot;&lt;br /&gt;
        encoding=&amp;quot;utf-8&amp;quot; media-type=&amp;quot;text/xml&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:strip-space elements=&amp;quot;*&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;text()|@*&amp;quot;/&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;/domain&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;meta&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:apply-templates/&amp;gt;&lt;br /&gt;
     &amp;lt;/meta&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;metadata/my:home/my:vlan&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;vlan&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:value-of select=&amp;quot;.&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;/vlan&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match='interface[@type=&amp;quot;bridge&amp;quot;]/target'&amp;gt;&lt;br /&gt;
     &amp;lt;dev&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:value-of select=&amp;quot;@dev&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;/dev&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;/xsl:stylesheet&amp;gt;&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
 '''harley$''' virsh dumpxml deb9-test | xmlstarlet tr /etc/libvirt/hooks/qemu.xsl &lt;br /&gt;
 &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;'''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== set VLAN-ID to the dynamic virtual network interface vnet* ===&lt;br /&gt;
Putting it all together here is the executable hook-script:&lt;br /&gt;
 '''harley$''' cat /etc/libvirt/hooks/qemu&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #/etc/libvirt/hooks/qemu&lt;br /&gt;
 # Docs: https://www.libvirt.org/hooks.html&lt;br /&gt;
 # If you make a new hook script then 'sudo systemctl restart libvirtd'.&lt;br /&gt;
 &lt;br /&gt;
 # On startup of the domain (guest) This script does:&lt;br /&gt;
 # Get Metadata VLAN-ID of the guest and target device of the bridge from&lt;br /&gt;
     # the domain-xml available on standard input. It is the runtime&lt;br /&gt;
     # version from 'virsh dumpxml domainname'. For extracting the&lt;br /&gt;
     # information we use a XSL-stylesheet. Example input into $META:&lt;br /&gt;
     # &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;&lt;br /&gt;
 # Select $DEV  from $META&lt;br /&gt;
 # Select $VLAN from $META&lt;br /&gt;
 # Set $VLAN to $DEV on the bridge&lt;br /&gt;
 &lt;br /&gt;
 case &amp;quot;$2&amp;quot; in&lt;br /&gt;
   prepare)&lt;br /&gt;
     ;;&lt;br /&gt;
   start)&lt;br /&gt;
     META=$(/usr/bin/xmlstarlet tr /etc/libvirt/hooks/qemu.xsl -)&lt;br /&gt;
     DEV=$(echo &amp;quot;$META&amp;quot; | /usr/bin/xmlstarlet sel -t -v '/meta/dev')&lt;br /&gt;
     VLAN=$(echo &amp;quot;$META&amp;quot; | /usr/bin/xmlstarlet sel -t -v '/meta/vlan')&lt;br /&gt;
     if &amp;amp;#91;[ -n $DEV &amp;amp;&amp;amp; -n $VLAN ]&amp;amp;#93;; then&lt;br /&gt;
       /sbin/bridge vlan add vid &amp;quot;$VLAN&amp;quot; dev &amp;quot;$DEV&amp;quot;&lt;br /&gt;
     fi&lt;br /&gt;
     ;;&lt;br /&gt;
   started)&lt;br /&gt;
     ;;&lt;br /&gt;
   stopped)&lt;br /&gt;
     ;;&lt;br /&gt;
   release)&lt;br /&gt;
     ;;&lt;br /&gt;
   migrate)&lt;br /&gt;
     ;;&lt;br /&gt;
   restore)&lt;br /&gt;
     ;;&lt;br /&gt;
   reconnect)&lt;br /&gt;
     ;;&lt;br /&gt;
   attach)&lt;br /&gt;
     ;;&lt;br /&gt;
   *)&lt;br /&gt;
     echo &amp;quot;qemu hook called with unexpected options $*&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
     exit 1&lt;br /&gt;
     ;;&lt;br /&gt;
 esac&lt;br /&gt;
 '''harley$''' sudo chmod 744 /etc/libvirt/hooks/qemu&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.libvirt.org/hooks.html&lt;br /&gt;
* https://serverfault.com/questions/696011/libvirt-hook-qemu-suse12&lt;br /&gt;
&lt;br /&gt;
== Workaround for setting DefaultPVID=none ==&lt;br /&gt;
Setting [https://www.freedesktop.org/software/systemd/man/systemd.netdev.html#DefaultPVID= DefaultPVID] in a&amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt; configuration file to &amp;quot;none&amp;quot; does not work. Until this bug is fixed I've made a workaround. The kernel accepts setting &amp;lt;code&amp;gt;default_pvid&amp;lt;/code&amp;gt; to 0 (means &amp;quot;none&amp;quot;) only if &amp;lt;code&amp;gt;vlan_filtering=0&amp;lt;/code&amp;gt;, so we have to do:&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/default_pvid'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 1 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Check with listing of [[#bridge-settings|bridge-settings]].&lt;br /&gt;
Theese commands must run with &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt; so we need a service for this. First I make a script and make it executable for root:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/DefaultPVID.sh &lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #echo &amp;quot;entering DefaultPVID.sh&amp;quot; &amp;gt;&amp;gt;/tmp/debug.log&lt;br /&gt;
 &lt;br /&gt;
 BRDIR=&amp;quot;/sys/class/net/br0/bridge/&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 if &amp;amp;#91;[ -f $BRDIR/vlan_filtering &amp;amp;&amp;amp; -f $BRDIR/default_pvid ]&amp;amp;#93;; then&lt;br /&gt;
   #echo &amp;quot;setting DefaultPVID&amp;quot; &amp;gt;&amp;gt;/tmp/debug.log&lt;br /&gt;
   VLAN_FILTERING=&amp;quot;$(cat &amp;quot;$BRDIR&amp;quot;/vlan_filtering)&amp;quot;&lt;br /&gt;
   echo 0 &amp;gt;&amp;quot;$BRDIR&amp;quot;/vlan_filtering&lt;br /&gt;
   echo 0 &amp;gt;&amp;quot;$BRDIR&amp;quot;/default_pvid&lt;br /&gt;
   echo &amp;quot;$VLAN_FILTERING&amp;quot; &amp;gt;&amp;quot;$BRDIR&amp;quot;/vlan_filtering&lt;br /&gt;
 fi&lt;br /&gt;
 exit 0&lt;br /&gt;
 '''harley$''' sudo chmod 744 /etc/systemd/network/DefaultPVID.sh&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Test with &amp;lt;code&amp;gt;'''harley$''' sudo /etc/systemd/network/DefaultPVID.sh&amp;lt;/code&amp;gt;. Next I create a service to execute this script:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/system/DefaultPVID.service &lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=set DefaultPVID on a bridge as workaround&lt;br /&gt;
 Wants=network.target&lt;br /&gt;
 After=network.target&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 Type=oneshot&lt;br /&gt;
 ExecStart=/etc/systemd/network/DefaultPVID.sh&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Test with &amp;lt;code&amp;gt;'''harley$''' sudo systemctl start DefaultPVID.service &amp;amp;&amp;amp; systemctl status DefaultPVID.service&amp;lt;/code&amp;gt;. After this I create a [https://www.freedesktop.org/software/systemd/man/systemd.unit.html#id-1.11.3 drop-in file for overriding vendor settings] so this service will be executed together with &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt;:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/system/systemd-networkd.service.d/DefaultPVID.conf &lt;br /&gt;
 [Unit]&lt;br /&gt;
 # This is only a workaround. DefaultPVID cannot be set in&lt;br /&gt;
 # /etc/systemd/network/br0.netdev. It seems buggy.&lt;br /&gt;
 Wants=DefaultPVID.service&lt;br /&gt;
 Before=DefaultPVID.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Test with &amp;lt;code&amp;gt;'''harley$''' sudo systemctl restart systemd-networkd&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=20</id>
		<title>VLAN for virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=20"/>
				<updated>2017-09-27T22:20:48Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: some minor corrections&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
I wanted to update VLAN connections for virtual&lt;br /&gt;
machines to newer technologies and put a question on&lt;br /&gt;
[https://unix.stackexchange.com/questions/392758/setup-vlan-on-linux-bridge-for-virtual-machines-with-systemd unix.stackexchange]. But I do not get any answer. It seems there is very&lt;br /&gt;
little knowledge for this out there. So I decided to work on it by myself&lt;br /&gt;
and document it here.&lt;br /&gt;
&lt;br /&gt;
In gerneral I will look at three methods:&lt;br /&gt;
# [[#oldstyle linux bridge as hub|oldstyle linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge as hub|linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge with libvirt hook scripts|linux bridge with libvirt hook scripts]]&lt;br /&gt;
&lt;br /&gt;
== Preparation ==&lt;br /&gt;
I have Debian GNU/Linux 9.1 (stretch) on the host and on virtual machines for testing. Setup is described here: [[Setup KVM with console]]. I'm sitting on harley as host, my all day workstation.&lt;br /&gt;
Now I start the virtual machine, login and show its interface setting:&lt;br /&gt;
 '''harley$''' virsh start --console deb9-test&lt;br /&gt;
login&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/08-vlan10.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 Kind=vlan&lt;br /&gt;
 [VLAN]&lt;br /&gt;
 Id=10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/12-vlan10_attach-to-if.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=ens2&lt;br /&gt;
 [Network]&lt;br /&gt;
 VLAN=vlan10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/16-vlan10_up.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 [Network]&lt;br /&gt;
 DHCP=ipv4&lt;br /&gt;
 IPv6AcceptRA=no&lt;br /&gt;
 LinkLocalAddressing=no&lt;br /&gt;
To test if the virtual machine has connection I use:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:34:20 CEST. --&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: Enumeration completed&lt;br /&gt;
 Sep 23 20:34:05 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: DHCPv4 address 192.168.10.89/24 via 192.168.10.1&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: Configured&lt;br /&gt;
 Sep 23 20:34:19 systemd-networkd[204]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
4 sec after Started Network Service it gets an IP-Address and 14 sec later interface ens2 was Configured. If ens2 is Configured and the guest hasn't got an IP-Address the connection failed. It looks like this:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:45:13 CEST. --&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: Enumeration completed&lt;br /&gt;
 Sep 23 20:44:59 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:13 systemd-networkd[197]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
&lt;br /&gt;
Because I have to start the test virtual machine many times I setup autologin. It's no problem. There is nothing on the guest.&lt;br /&gt;
 '''deb9-test$''' grep ^ExecStart= /lib/systemd/system/serial-getty@.service&lt;br /&gt;
 ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
modify to&lt;br /&gt;
 ExecStart=-/sbin/agetty --autologin ''yourloginname'' --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
&amp;lt;span id=&amp;quot;bridge-settings&amp;quot;&amp;gt;To list all settings of the bridge&amp;lt;/span&amp;gt; you can use:&lt;br /&gt;
 '''harley$''' find /sys/class/net/br0/bridge/ -type f -readable -printf '%f = ' -exec cat {} \; | sort&lt;br /&gt;
&lt;br /&gt;
== oldstyle linux bridge as hub ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Disable systemd-networkd and start networking with ifupdown:&lt;br /&gt;
 '''harley$''' sudo systemctl stop systemd-networkd&lt;br /&gt;
 Warning: Stopping systemd-networkd.service, but it can still be activated by:&lt;br /&gt;
   systemd-networkd.socket&lt;br /&gt;
 '''harley$''' sudo systemctl disable systemd-networkd&lt;br /&gt;
 Removed /etc/systemd/system/multi-user.target.wants/systemd-networkd.service.&lt;br /&gt;
 Removed /etc/systemd/system/sockets.target.wants/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install enable networking&lt;br /&gt;
 '''harley$''' sudo systemctl start networking.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/network/interfaces&lt;br /&gt;
 auto br0&lt;br /&gt;
 iface br0 inet manual&lt;br /&gt;
     bridge_ports enp1s0&lt;br /&gt;
     bridge_ageing 0&lt;br /&gt;
     bridge_stp off&lt;br /&gt;
 '''harley$''' sudo ifup br0&lt;br /&gt;
 Waiting for br0 to get ready (MAXWAIT is 32 seconds).&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
It's all in place now:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
Yes, there is no VLAN filtering, means VLAN on the bridge is disabled but the guest sees the VLAN-tagged packets.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://wiki.debian.org/NetworkConfiguration#Bridging_without_Switching&lt;br /&gt;
&lt;br /&gt;
== linux bridge as hub ==&lt;br /&gt;
Now I try to setup [[#oldstyle linux bridge as hub]] just with systemd-networkd.&lt;br /&gt;
&lt;br /&gt;
Disable networking with ifupdown and start systemd-networkd:&lt;br /&gt;
 '''harley$''' sudo systemctl stop networking.service&lt;br /&gt;
 '''harley$''' sudo systemctl disable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install disable networking&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable systemd-networkd&lt;br /&gt;
 Created symlink /etc/systemd/system/multi-user.target.wants/systemd-networkd.service → /lib/systemd/system/systemd-networkd.service.&lt;br /&gt;
 Created symlink /etc/systemd/system/sockets.target.wants/systemd-networkd.socket → /lib/systemd/system/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo systemctl start systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/08-br0.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 AgeingTimeSec=0&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/12-br0_add-enp1s0.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl restart systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
AgeingTimeSec=0 is not acepted but should:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 30000   (means 300 sec)&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
But I've found a workaround. Useing a number between '''.'''01 and '''.'''000001 (there are dots) will set ageing_time to 0.&lt;br /&gt;
So set AgeingTimeSec='''.'''000001 in /etc/systemd/network/08-br0.netdev. I suppose it's a bug. Then we&lt;br /&gt;
will get:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets now an IP-Address on boot and is connected to VLAN 10.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
This works because of [[#References|three conditions]].&lt;br /&gt;
# ageing time is 0: ageing time specifies the number of seconds a MAC Address will be kept in the forwarding database after having a packet received from this MAC Address. Setting it to 0 means there is never a MAC Address stored in the FDB.&lt;br /&gt;
# unicast flood on interfaces is on: this controls whether the bridge should flood traffic for which an FDB entry is missing and the destination is unknown through this port. Defaults to on.&lt;br /&gt;
# spanning tree protocol (stp) is disabled: we don't have a forward_delay at startup for the learning phase of spanning tree.&lt;br /&gt;
I have a running and connected virtual machine:&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   1 PVID Egress Untagged&lt;br /&gt;
 br0      1 PVID Egress Untagged&lt;br /&gt;
 vnet0    1 PVID Egress Untagged&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time&lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/forward_delay&lt;br /&gt;
 1500&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state&lt;br /&gt;
 0&lt;br /&gt;
Indeed we have forward_delay 1500 (means 15 sec) but it doesn't matter. stp_state is 0 (disabled), no spanning tree. Flood (means unicast flood) is on as I can see:&lt;br /&gt;
 '''harley$''' sudo bridge -d link show&lt;br /&gt;
 ''3: enp1s0'' state UP : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 4&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on &lt;br /&gt;
 ''95: vnet0'' state UNKNOWN : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 100&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let's have a look at flooding on the interfaces. I disable it on the physical interface enp1s0 of the bridge and reboot the guest:&lt;br /&gt;
 '''harley$''' sudo bridge link set dev enp1s0 flood off&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets an IP-Address from the DHCP-Server but then can't ping its gateway. DHCP-REQUEST is broadcast and goes thru enp1s0. DHCP-ANSWER comes back thru it to any other (here only vnet0) interface which has flood on. Ping is unicast and isn't forwareded on enp1s0. If I set  enp1s0 flood on and vnet0 flood off and &amp;lt;code&amp;gt;'''deb9-test$ '''sudo systemctl restart systemd-networkd&amp;lt;/code&amp;gt;, I get no IP-Address from DHCP-Server and can't ping the interface. Incoming DHCP-ANSWER isn't broadcast and vnet0 doesn't forward it to the guest.&lt;br /&gt;
&lt;br /&gt;
Btw. this method has bad performance as we can see with monitor. We insert MAC-Addresses into FDB for just deleting it immediately, all for nothing.&lt;br /&gt;
 '''harley$''' sudo bridge monitor fdb&lt;br /&gt;
 52:54:00:01:76:20 dev enp1s0 master br0 &lt;br /&gt;
 52:54:00:b0:ca:63 dev vnet0 master br0 &lt;br /&gt;
 f4:f2:6d:2c:87:f7 dev enp1s0 master br0 &lt;br /&gt;
 00:80:3f:2a:31:1a dev enp1s0 master br0 &lt;br /&gt;
 Deleted 52:54:00:01:76:20 dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted 52:54:00:b0:ca:63 dev vnet0 master br0 stale&lt;br /&gt;
 Deleted 00:80:3f:2a:31:1a dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted f4:f2:6d:2c:87:f7 dev enp1s0 master br0 stale&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.netdev.html&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.network.html&lt;br /&gt;
&lt;br /&gt;
== linux bridge with libvirt hook scripts ==&lt;br /&gt;
We setup a bridge with VLAN enabled:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/08-br0.netdev &lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 DefaultPVID=none&lt;br /&gt;
 VLANFiltering=true&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/12-br0_add-enp1s0.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=10&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=20&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=30&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
With this I get:&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   1 PVID Egress Untagged&lt;br /&gt;
          10&lt;br /&gt;
          20&lt;br /&gt;
          30  &lt;br /&gt;
 br0      1 PVID Egress Untagged&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
But what is this? We have default VLAN &amp;lt;code&amp;gt;1 PVID Egress Untagged&amp;lt;/code&amp;gt;. I don't want this. Seems setting &amp;lt;code&amp;gt;DefaultPVID=none&amp;lt;/code&amp;gt; in 08-br0.netdev doesn't work. I've made a [[#Workaround for setting DefaultPVID=none|Workaround for setting DefaultPVID=none]]. Looking at this behavior I found that we can set &amp;lt;code&amp;gt;default_pvid&amp;lt;/code&amp;gt; in the kernel only if &amp;lt;code&amp;gt;vlan_filtering = 0&amp;lt;/code&amp;gt;. By hand I have to do:&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/default_pvid'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 1 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
If I start a guest I will get now:&lt;br /&gt;
 '''harley$''' virsh start deb9-test&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   10&lt;br /&gt;
          20&lt;br /&gt;
          30&lt;br /&gt;
 br0     None&lt;br /&gt;
 vnet0   None&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The virtual network interface vnet0 for deb9-test has no VLAN ID. Libvirt does not know something about this so we have to tell it. Libvirt provides [https://www.libvirt.org/hooks.html hook scripts] that we can use for this. We have to:&lt;br /&gt;
# [[#define VLAN-ID the virtual machine belongs to]]&lt;br /&gt;
# [[#get information on startup from the runtime XML-config of the domain]]&lt;br /&gt;
# [[#set VLAN-ID to the dynamic virtual network interface vnet*]]&lt;br /&gt;
&amp;lt;span id=&amp;quot;debug.sh&amp;quot;&amp;gt;For debugging the hook-scripts&amp;lt;/span&amp;gt; I've made a small script:&lt;br /&gt;
 '''harley$''' cat /etc/libvirt/hooks/debug.sh&lt;br /&gt;
 #!/bin/bash -e&lt;br /&gt;
 # https://www.libvirt.org/hooks.html&lt;br /&gt;
 # If you make a new hook script then 'sudo systemctl restart libvirtd'.&lt;br /&gt;
 # For debug set symlink to hook-script daemon, qemu, lxc, libxl and/or network,&lt;br /&gt;
 # e.g. 'sudo ln -s debug.sh qemu' and restart libvirtd.&lt;br /&gt;
 &lt;br /&gt;
 logfile='/var/log/libvirt/hooks.log'&lt;br /&gt;
 &lt;br /&gt;
 echo &amp;quot;$0&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 date -Iseconds &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 echo &amp;quot;\$1=$1, \$2=$2, \$3=$3, \$4=$4&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 cat - &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 echo -e &amp;quot;\n---------------------------------------------&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== define VLAN-ID the virtual machine belongs to ===&lt;br /&gt;
For this we have an extra [https://libvirt.org/formatdomain.html#elementsMetadata element &amp;lt;metadata&amp;gt; in Domain XML format] for custom metadata. We can simply add the information to the static configuration with &amp;lt;code&amp;gt;'''harley$''' virsh edit deb9-test&amp;lt;/code&amp;gt; like this (look only at the &amp;lt;metadata&amp;gt; element):&lt;br /&gt;
 '''harley$''' virsh dumpxml deb9-test | head -n9&lt;br /&gt;
 &amp;lt;domain type='kvm' id='1'&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;deb9-test&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;uuid&amp;gt;70d56a28-795d-4010-9403-513a4bd6b66a&amp;lt;/uuid&amp;gt;&lt;br /&gt;
   &amp;lt;metadata&amp;gt;&lt;br /&gt;
     &amp;lt;my:home xmlns:my=&amp;quot;http://hoeft-online.de/my/&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;my:vlan&amp;gt;10&amp;lt;/my:vlan&amp;gt;&lt;br /&gt;
     &amp;lt;/my:home&amp;gt;&lt;br /&gt;
   &amp;lt;/metadata&amp;gt;&lt;br /&gt;
   &amp;lt;memory unit='KiB'&amp;gt;1048576&amp;lt;/memory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get information on startup from the runtime XML-config of the domain ===&lt;br /&gt;
It seems a little bit difficult to get needed information out of the big XML-config but it's no problem with XSLT. I've made a XSL-stylesheet for this and use xmlstarlet. Start a virtual machine and then its runtime configuration is available with &amp;lt;code&amp;gt;'''harley$''' virsh dumpxml deb9-test | xmlstarlet tr qemu.xsl&amp;lt;/code&amp;gt;. With this I can test my stylesheet. Here is it:&lt;br /&gt;
 '''harley$''' cat /etc/libvirt/hooks/qemu.xsl &lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;amp;lt;!-- This stylesheet extracts the VLAN-ID and the target device of the&lt;br /&gt;
      bridge from the domain-xml given to the libvirt hook-script &amp;quot;qemu&amp;quot;.&lt;br /&gt;
      Example output: &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;&lt;br /&gt;
 --&amp;amp;gt;&lt;br /&gt;
 &amp;lt;xsl:stylesheet version=&amp;quot;1.0&amp;quot; xmlns:xsl=&amp;quot;http://www.w3.org/1999/XSL/Transform&amp;quot;&lt;br /&gt;
      xmlns:my=&amp;quot;http://hoeft-online.de/my/&amp;quot; exclude-result-prefixes=&amp;quot;my&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:output omit-xml-declaration=&amp;quot;yes&amp;quot; indent=&amp;quot;no&amp;quot;&lt;br /&gt;
        encoding=&amp;quot;utf-8&amp;quot; media-type=&amp;quot;text/xml&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:strip-space elements=&amp;quot;*&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;text()|@*&amp;quot;/&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;/domain&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;meta&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:apply-templates/&amp;gt;&lt;br /&gt;
     &amp;lt;/meta&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;metadata/my:home/my:vlan&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;vlan&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:value-of select=&amp;quot;.&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;/vlan&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match='interface[@type=&amp;quot;bridge&amp;quot;]/target'&amp;gt;&lt;br /&gt;
     &amp;lt;dev&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:value-of select=&amp;quot;@dev&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;/dev&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;/xsl:stylesheet&amp;gt;&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
 '''harley$''' virsh dumpxml deb9-test | xmlstarlet tr /etc/libvirt/hooks/qemu.xsl &lt;br /&gt;
 &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;'''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== set VLAN-ID to the dynamic virtual network interface vnet* ===&lt;br /&gt;
Putting it all together here is the executable hook-script:&lt;br /&gt;
 '''harley$''' cat /etc/libvirt/hooks/qemu&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #/etc/libvirt/hooks/qemu&lt;br /&gt;
 # Docs: https://www.libvirt.org/hooks.html&lt;br /&gt;
 # If you make a new hook script then 'sudo systemctl restart libvirtd'.&lt;br /&gt;
 &lt;br /&gt;
 # On startup of the domain (guest) This script does:&lt;br /&gt;
 # Get Metadata VLAN-ID of the guest and target device of the bridge from&lt;br /&gt;
     # the domain-xml available on standard input. It is the runtime&lt;br /&gt;
     # version from 'virsh dumpxml domainname'. For extracting the&lt;br /&gt;
     # information we use a XSL-stylesheet. Example input into $META:&lt;br /&gt;
     # &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;&lt;br /&gt;
 # Select $DEV  from $META&lt;br /&gt;
 # Select $VLAN from $META&lt;br /&gt;
 # Set $VLAN to $DEV on the bridge&lt;br /&gt;
 &lt;br /&gt;
 case &amp;quot;$2&amp;quot; in&lt;br /&gt;
   prepare)&lt;br /&gt;
     ;;&lt;br /&gt;
   start)&lt;br /&gt;
     META=$(/usr/bin/xmlstarlet tr /etc/libvirt/hooks/qemu.xsl -)&lt;br /&gt;
     DEV=$(echo &amp;quot;$META&amp;quot; | /usr/bin/xmlstarlet sel -t -v '/meta/dev')&lt;br /&gt;
     VLAN=$(echo &amp;quot;$META&amp;quot; | /usr/bin/xmlstarlet sel -t -v '/meta/vlan')&lt;br /&gt;
     if &amp;amp;#91;[ -n $DEV &amp;amp;&amp;amp; -n $VLAN ]&amp;amp;#93;; then&lt;br /&gt;
       /sbin/bridge vlan add vid &amp;quot;$VLAN&amp;quot; dev &amp;quot;$DEV&amp;quot;&lt;br /&gt;
     fi&lt;br /&gt;
     ;;&lt;br /&gt;
   started)&lt;br /&gt;
     ;;&lt;br /&gt;
   stopped)&lt;br /&gt;
     ;;&lt;br /&gt;
   release)&lt;br /&gt;
     ;;&lt;br /&gt;
   migrate)&lt;br /&gt;
     ;;&lt;br /&gt;
   restore)&lt;br /&gt;
     ;;&lt;br /&gt;
   reconnect)&lt;br /&gt;
     ;;&lt;br /&gt;
   attach)&lt;br /&gt;
     ;;&lt;br /&gt;
   *)&lt;br /&gt;
     echo &amp;quot;qemu hook called with unexpected options $*&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
     exit 1&lt;br /&gt;
     ;;&lt;br /&gt;
 esac&lt;br /&gt;
 '''harley$''' sudo chmod 744 /etc/libvirt/hooks/qemu&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.libvirt.org/hooks.html&lt;br /&gt;
* https://serverfault.com/questions/696011/libvirt-hook-qemu-suse12&lt;br /&gt;
&lt;br /&gt;
== Workaround for setting DefaultPVID=none ==&lt;br /&gt;
Setting [https://www.freedesktop.org/software/systemd/man/systemd.netdev.html#DefaultPVID= DefaultPVID] in a&amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt; configuration file to &amp;quot;none&amp;quot; does not work. Until this bug is fixed I've made a workaround. The kernel accepts setting &amp;lt;code&amp;gt;default_pvid&amp;lt;/code&amp;gt; to 0 (means &amp;quot;none&amp;quot;) only if &amp;lt;code&amp;gt;vlan_filtering=0&amp;lt;/code&amp;gt;, so we have to do:&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/default_pvid'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 1 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Check with listing of [[#bridge-settings|bridge-settings]].&lt;br /&gt;
Theese commands must run with &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt; so we need a service for this. First I make a script and make it executable for root:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/DefaultPVID.sh &lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #echo &amp;quot;entering DefaultPVID.sh&amp;quot; &amp;gt;&amp;gt;/tmp/debug.log&lt;br /&gt;
 &lt;br /&gt;
 BRDIR=&amp;quot;/sys/class/net/br0/bridge/&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 if &amp;amp;#91;[ -f $BRDIR/vlan_filtering &amp;amp;&amp;amp; -f $BRDIR/default_pvid ]&amp;amp;#93;; then&lt;br /&gt;
   #echo &amp;quot;setting DefaultPVID&amp;quot; &amp;gt;&amp;gt;/tmp/debug.log&lt;br /&gt;
   VLAN_FILTERING=&amp;quot;$(cat &amp;quot;$BRDIR&amp;quot;/vlan_filtering)&amp;quot;&lt;br /&gt;
   echo 0 &amp;gt;&amp;quot;$BRDIR&amp;quot;/vlan_filtering&lt;br /&gt;
   echo 0 &amp;gt;&amp;quot;$BRDIR&amp;quot;/default_pvid&lt;br /&gt;
   echo &amp;quot;$VLAN_FILTERING&amp;quot; &amp;gt;&amp;quot;$BRDIR&amp;quot;/vlan_filtering&lt;br /&gt;
 fi&lt;br /&gt;
 exit 0&lt;br /&gt;
 '''harley$''' sudo chmod 744 /etc/systemd/network/DefaultPVID.sh&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Next I create a service to execute this script:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/system/DefaultPVID.service &lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=set DefaultPVID on a bridge as workaround&lt;br /&gt;
 Wants=network.target&lt;br /&gt;
 After=network.target&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 Type=oneshot&lt;br /&gt;
 ExecStart=/etc/systemd/network/DefaultPVID.sh&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
And then I create a [https://www.freedesktop.org/software/systemd/man/systemd.unit.html#id-1.11.3 drop-in file for overriding vendor settings] so this service will be executed together with &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt;:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/system/systemd-networkd.service.d/DefaultPVID.conf &lt;br /&gt;
 [Unit]&lt;br /&gt;
 # This is only a workaround. DefaultPVID cannot be set in&lt;br /&gt;
 # /etc/systemd/network/br0.netdev. It seems buggy.&lt;br /&gt;
 Wants=DefaultPVID.service&lt;br /&gt;
 Before=DefaultPVID.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=19</id>
		<title>VLAN for virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=19"/>
				<updated>2017-09-27T21:31:18Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: linkfix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
I wanted to update VLAN connections for virtual&lt;br /&gt;
machines to newer technologies and put a question on&lt;br /&gt;
[https://unix.stackexchange.com/questions/392758/setup-vlan-on-linux-bridge-for-virtual-machines-with-systemd unix.stackexchange]. But I do not get any answer. It seems there is very&lt;br /&gt;
little knowledge for this out there. So I decided to work on it by myself&lt;br /&gt;
and document it here.&lt;br /&gt;
&lt;br /&gt;
In gerneral I will look at three methods:&lt;br /&gt;
# [[#oldstyle linux bridge as hub|oldstyle linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge as hub|linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge with libvirt hook scripts|linux bridge with libvirt hook scripts]]&lt;br /&gt;
&lt;br /&gt;
== Preparation ==&lt;br /&gt;
I have Debian GNU/Linux 9.1 (stretch) on the host and on virtual machines for testing. Setup is described here: [[Setup KVM with console]]. I'm sitting on harley as host, my all day workstation.&lt;br /&gt;
Now I start the virtual machine, login and show its interface setting:&lt;br /&gt;
 '''harley$''' virsh start --console deb9-test&lt;br /&gt;
login&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/08-vlan10.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 Kind=vlan&lt;br /&gt;
 [VLAN]&lt;br /&gt;
 Id=10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/12-vlan10_attach-to-if.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=ens2&lt;br /&gt;
 [Network]&lt;br /&gt;
 VLAN=vlan10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/16-vlan10_up.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 [Network]&lt;br /&gt;
 DHCP=ipv4&lt;br /&gt;
 IPv6AcceptRA=no&lt;br /&gt;
 LinkLocalAddressing=no&lt;br /&gt;
To test if the virtual machine has connection I use:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:34:20 CEST. --&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: Enumeration completed&lt;br /&gt;
 Sep 23 20:34:05 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: DHCPv4 address 192.168.10.89/24 via 192.168.10.1&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: Configured&lt;br /&gt;
 Sep 23 20:34:19 systemd-networkd[204]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
4 sec after Started Network Service it gets an IP-Address and 14 sec later interface ens2 was Configured. If ens2 is Configured and the guest hasn't got an IP-Address the connection failed. It looks like this:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:45:13 CEST. --&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: Enumeration completed&lt;br /&gt;
 Sep 23 20:44:59 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:13 systemd-networkd[197]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
&lt;br /&gt;
Because I have to start the test virtual machine many times I setup autologin. It's no problem. There is nothing on the guest.&lt;br /&gt;
 '''deb9-test$''' grep ^ExecStart= /lib/systemd/system/serial-getty@.service&lt;br /&gt;
 ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
modify to&lt;br /&gt;
 ExecStart=-/sbin/agetty --autologin ''yourloginname'' --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
&amp;lt;span id=&amp;quot;bridge-settings&amp;quot;&amp;gt;To list all settings of the bridge&amp;lt;/span&amp;gt; you can use:&lt;br /&gt;
 '''harley$''' find /sys/class/net/br0/bridge/ -type f -readable -printf '%f = ' -exec cat {} \; | sort&lt;br /&gt;
&lt;br /&gt;
== oldstyle linux bridge as hub ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Disable systemd-networkd and start networking with ifupdown:&lt;br /&gt;
 '''harley$''' sudo systemctl stop systemd-networkd&lt;br /&gt;
 Warning: Stopping systemd-networkd.service, but it can still be activated by:&lt;br /&gt;
   systemd-networkd.socket&lt;br /&gt;
 '''harley$''' sudo systemctl disable systemd-networkd&lt;br /&gt;
 Removed /etc/systemd/system/multi-user.target.wants/systemd-networkd.service.&lt;br /&gt;
 Removed /etc/systemd/system/sockets.target.wants/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install enable networking&lt;br /&gt;
 '''harley$''' sudo systemctl start networking.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/network/interfaces&lt;br /&gt;
 auto br0&lt;br /&gt;
 iface br0 inet manual&lt;br /&gt;
     bridge_ports enp1s0&lt;br /&gt;
     bridge_ageing 0&lt;br /&gt;
     bridge_stp off&lt;br /&gt;
 '''harley$''' sudo ifup br0&lt;br /&gt;
 Waiting for br0 to get ready (MAXWAIT is 32 seconds).&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
It's all in place now:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
Yes, there is no VLAN filtering, means VLAN on the bridge is disabled but the guest sees the VLAN-tagged packets.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://wiki.debian.org/NetworkConfiguration#Bridging_without_Switching&lt;br /&gt;
&lt;br /&gt;
== linux bridge as hub ==&lt;br /&gt;
Now I try to setup [[#oldstyle linux bridge as hub]] just with systemd-networkd.&lt;br /&gt;
&lt;br /&gt;
Disable networking with ifupdown and start systemd-networkd:&lt;br /&gt;
 '''harley$''' sudo systemctl stop networking.service&lt;br /&gt;
 '''harley$''' sudo systemctl disable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install disable networking&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable systemd-networkd&lt;br /&gt;
 Created symlink /etc/systemd/system/multi-user.target.wants/systemd-networkd.service → /lib/systemd/system/systemd-networkd.service.&lt;br /&gt;
 Created symlink /etc/systemd/system/sockets.target.wants/systemd-networkd.socket → /lib/systemd/system/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo systemctl start systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/08-br0.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 AgeingTimeSec=0&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/12-br0_add-enp1s0.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl restart systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
AgeingTimeSec=0 is not acepted but should:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 30000   (means 300 sec)&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
But I've found a workaround. Useing a number between '''.'''01 and '''.'''000001 (there are dots) will set ageing_time to 0.&lt;br /&gt;
So set AgeingTimeSec='''.'''000001 in /etc/systemd/network/08-br0.netdev. I suppose it's a bug. Then we&lt;br /&gt;
will get:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets now an IP-Address on boot and is connected to VLAN 10.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
This works because of [[#References|three conditions]].&lt;br /&gt;
# ageing time is 0: ageing time specifies the number of seconds a MAC Address will be kept in the forwarding database after having a packet received from this MAC Address. Setting it to 0 means there is never a MAC Address stored in the FDB.&lt;br /&gt;
# unicast flood on interfaces is on: this controls whether the bridge should flood traffic for which an FDB entry is missing and the destination is unknown through this port. Defaults to on.&lt;br /&gt;
# spanning tree protocol (stp) is disabled: we don't have a forward_delay at startup for the learning phase of spanning tree.&lt;br /&gt;
I have a running and connected virtual machine:&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   1 PVID Egress Untagged&lt;br /&gt;
 br0      1 PVID Egress Untagged&lt;br /&gt;
 vnet0    1 PVID Egress Untagged&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time&lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/forward_delay&lt;br /&gt;
 1500&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state&lt;br /&gt;
 0&lt;br /&gt;
Indeed we have forward_delay 1500 (means 15 sec) but it doesn't matter. stp_state is 0 (disabled), no spanning tree. Flood (means unicast flood) is on as I can see:&lt;br /&gt;
 '''harley$''' sudo bridge -d link show&lt;br /&gt;
 ''3: enp1s0'' state UP : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 4&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on &lt;br /&gt;
 ''95: vnet0'' state UNKNOWN : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 100&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let's have a look at flooding on the interfaces. I disable it on the physical interface enp1s0 of the bridge and reboot the guest:&lt;br /&gt;
 '''harley$''' sudo bridge link set dev enp1s0 flood off&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets an IP-Address from the DHCP-Server but then can't ping its gateway. DHCP-REQUEST is broadcast and goes thru enp1s0. DHCP-ANSWER comes back thru it to any other (here only vnet0) interface which has flood on. Ping is unicast and isn't forwareded on enp1s0. If I set  enp1s0 flood on and vnet0 flood off and &amp;lt;code&amp;gt;'''deb9-test$ '''sudo systemctl restart systemd-networkd&amp;lt;/code&amp;gt;, I get no IP-Address from DHCP-Server and can't ping the interface. Incoming DHCP-ANSWER isn't broadcast and vnet0 doesn't forward it to the guest.&lt;br /&gt;
&lt;br /&gt;
Btw. this method has bad performance as we can see with monitor. We insert MAC-Addresses into FDB for just deleting it immediately, all for nothing.&lt;br /&gt;
 '''harley$''' sudo bridge monitor fdb&lt;br /&gt;
 52:54:00:01:76:20 dev enp1s0 master br0 &lt;br /&gt;
 52:54:00:b0:ca:63 dev vnet0 master br0 &lt;br /&gt;
 f4:f2:6d:2c:87:f7 dev enp1s0 master br0 &lt;br /&gt;
 00:80:3f:2a:31:1a dev enp1s0 master br0 &lt;br /&gt;
 Deleted 52:54:00:01:76:20 dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted 52:54:00:b0:ca:63 dev vnet0 master br0 stale&lt;br /&gt;
 Deleted 00:80:3f:2a:31:1a dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted f4:f2:6d:2c:87:f7 dev enp1s0 master br0 stale&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.netdev.html&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.network.html&lt;br /&gt;
&lt;br /&gt;
== linux bridge with libvirt hook scripts ==&lt;br /&gt;
We setup a bridge with VLAN enabled:&lt;br /&gt;
 '''harley$''' cat 08-br0.netdev &lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 DefaultPVID=none&lt;br /&gt;
 VLANFiltering=true&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat 12-br0_add-enp1s0.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=10&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=20&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=30&lt;br /&gt;
 '''harley$''' cat 16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
With this I get:&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   1 PVID Egress Untagged&lt;br /&gt;
          10&lt;br /&gt;
          20&lt;br /&gt;
          30  &lt;br /&gt;
 br0      1 PVID Egress Untagged&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
But what is this? We have default VLAN &amp;lt;code&amp;gt;1 PVID Egress Untagged&amp;lt;/code&amp;gt;. I don't want this. Seems setting &amp;lt;code&amp;gt;DefaultPVID=none&amp;lt;/code&amp;gt; in 08-br0.netdev doesn't work. I've made a [[#Workaround for setting DefaultPVID=none|Workaround for setting DefaultPVID=none]]. Looking at this behavior I found that we can set &amp;lt;code&amp;gt;default_pvid&amp;lt;/code&amp;gt; in the kernel only if &amp;lt;code&amp;gt;vlan_filtering = 0&amp;lt;/code&amp;gt;. By hand I have to do:&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/default_pvid'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 1 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
If I start a guest I will get now:&lt;br /&gt;
 '''harley$''' virsh start deb9-test&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   10&lt;br /&gt;
          20&lt;br /&gt;
          30&lt;br /&gt;
 br0     None&lt;br /&gt;
 vnet0   None&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The virtual network interface vnet0 for deb9-test has no VLAN ID. Libvirt does not know something about this so we have to tell it. Libvirt provides [https://www.libvirt.org/hooks.html hook scripts] that we can use for this. We have to:&lt;br /&gt;
# [[#define VLAN-ID the virtual machine belongs to]]&lt;br /&gt;
# [[#get information on startup from the runtime XML-config of the domain]]&lt;br /&gt;
# [[#set VLAN-ID to the dynamic virtual network interface vnet*]]&lt;br /&gt;
&amp;lt;span id=&amp;quot;debug.sh&amp;quot;&amp;gt;For debugging the hook-scripts&amp;lt;/span&amp;gt; I've made a small script:&lt;br /&gt;
 '''harley$''' cat debug.sh&lt;br /&gt;
 #!/bin/bash -e&lt;br /&gt;
 # https://www.libvirt.org/hooks.html&lt;br /&gt;
 # If you make a new hook script then 'sudo systemctl restart libvirtd'.&lt;br /&gt;
 # For debug set symlink to hook-script daemon, qemu, lxc, libxl and/or network,&lt;br /&gt;
 # e.g. 'sudo ln -s debug.sh qemu' and restart libvirtd.&lt;br /&gt;
 &lt;br /&gt;
 logfile='/var/log/libvirt/hooks.log'&lt;br /&gt;
 &lt;br /&gt;
 echo &amp;quot;$0&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 date -Iseconds &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 echo &amp;quot;\$1=$1, \$2=$2, \$3=$3, \$4=$4&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 cat - &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 echo -e &amp;quot;\n---------------------------------------------&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== define VLAN-ID the virtual machine belongs to ===&lt;br /&gt;
For this we have an extra [https://libvirt.org/formatdomain.html#elementsMetadata element &amp;lt;metadata&amp;gt; in Domain XML format] for custom metadata. We can simply add the information to the static configuration with &amp;lt;code&amp;gt;'''harley$''' virsh edit deb9-test&amp;lt;/code&amp;gt; like this (look only at the &amp;lt;metadata&amp;gt; element):&lt;br /&gt;
 '''harley$''' virsh dumpxml deb9-test | head -n9&lt;br /&gt;
 &amp;lt;domain type='kvm' id='1'&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;deb9-test&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;uuid&amp;gt;70d56a28-795d-4010-9403-513a4bd6b66a&amp;lt;/uuid&amp;gt;&lt;br /&gt;
   &amp;lt;metadata&amp;gt;&lt;br /&gt;
     &amp;lt;my:home xmlns:my=&amp;quot;http://hoeft-online.de/my/&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;my:vlan&amp;gt;10&amp;lt;/my:vlan&amp;gt;&lt;br /&gt;
     &amp;lt;/my:home&amp;gt;&lt;br /&gt;
   &amp;lt;/metadata&amp;gt;&lt;br /&gt;
   &amp;lt;memory unit='KiB'&amp;gt;1048576&amp;lt;/memory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get information on startup from the runtime XML-config of the domain ===&lt;br /&gt;
It seems a little bit difficult to get needed information out of the big XML-config but it's no problem with XSLT. I've made a XSL-stylesheet for this and use xmlstarlet. Start a virtual machine and then its runtime configuration is available with &amp;lt;code&amp;gt;'''harley$''' virsh dumpxml deb9-test | xmlstarlet tr qemu.xsl&amp;lt;/code&amp;gt;. With this I can test my stylesheet. Here is it:&lt;br /&gt;
 '''harley$''' cat qemu.xsl &lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;amp;lt;!-- This stylesheet extracts the VLAN-ID and the target device of the&lt;br /&gt;
      bridge from the domain-xml given to the libvirt hook-script &amp;quot;qemu&amp;quot;.&lt;br /&gt;
      Example output: &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;&lt;br /&gt;
 --&amp;amp;gt;&lt;br /&gt;
 &amp;lt;xsl:stylesheet version=&amp;quot;1.0&amp;quot; xmlns:xsl=&amp;quot;http://www.w3.org/1999/XSL/Transform&amp;quot;&lt;br /&gt;
      xmlns:my=&amp;quot;http://hoeft-online.de/my/&amp;quot; exclude-result-prefixes=&amp;quot;my&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:output omit-xml-declaration=&amp;quot;yes&amp;quot; indent=&amp;quot;no&amp;quot;&lt;br /&gt;
        encoding=&amp;quot;utf-8&amp;quot; media-type=&amp;quot;text/xml&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:strip-space elements=&amp;quot;*&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;text()|@*&amp;quot;/&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;/domain&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;meta&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:apply-templates/&amp;gt;&lt;br /&gt;
     &amp;lt;/meta&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;metadata/my:home/my:vlan&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;vlan&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:value-of select=&amp;quot;.&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;/vlan&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match='interface[@type=&amp;quot;bridge&amp;quot;]/target'&amp;gt;&lt;br /&gt;
     &amp;lt;dev&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:value-of select=&amp;quot;@dev&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;/dev&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;/xsl:stylesheet&amp;gt;&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
 '''harley$''' virsh dumpxml deb9-test | xmlstarlet tr /etc/libvirt/hooks/qemu.xsl &lt;br /&gt;
 &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;'''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== set VLAN-ID to the dynamic virtual network interface vnet* ===&lt;br /&gt;
Putting it all together here is the executable hook-script:&lt;br /&gt;
 '''harley$''' cat /etc/libvirt/hooks/qemu&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #/etc/libvirt/hooks/qemu&lt;br /&gt;
 # Docs: https://www.libvirt.org/hooks.html&lt;br /&gt;
 # If you make a new hook script then 'sudo systemctl restart libvirtd'.&lt;br /&gt;
 &lt;br /&gt;
 # On startup of the domain (guest) This script does:&lt;br /&gt;
 # Get Metadata VLAN-ID of the guest and target device of the bridge from&lt;br /&gt;
     # the domain-xml available on standard input. It is the runtime&lt;br /&gt;
     # version from 'virsh dumpxml domainname'. For extracting the&lt;br /&gt;
     # information we use a XSL-stylesheet. Example input into $META:&lt;br /&gt;
     # &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;&lt;br /&gt;
 # Select $DEV  from $META&lt;br /&gt;
 # Select $VLAN from $META&lt;br /&gt;
 # Set $VLAN to $DEV on the bridge&lt;br /&gt;
 &lt;br /&gt;
 case &amp;quot;$2&amp;quot; in&lt;br /&gt;
   prepare)&lt;br /&gt;
     ;;&lt;br /&gt;
   start)&lt;br /&gt;
     META=$(/usr/bin/xmlstarlet tr /etc/libvirt/hooks/qemu.xsl -)&lt;br /&gt;
     DEV=$(echo &amp;quot;$META&amp;quot; | /usr/bin/xmlstarlet sel -t -v '/meta/dev')&lt;br /&gt;
     VLAN=$(echo &amp;quot;$META&amp;quot; | /usr/bin/xmlstarlet sel -t -v '/meta/vlan')&lt;br /&gt;
     if &amp;amp;#91;[ -n $DEV &amp;amp;&amp;amp; -n $VLAN ]&amp;amp;#93;; then&lt;br /&gt;
       /sbin/bridge vlan add vid &amp;quot;$VLAN&amp;quot; dev &amp;quot;$DEV&amp;quot;&lt;br /&gt;
     fi&lt;br /&gt;
     ;;&lt;br /&gt;
   started)&lt;br /&gt;
     ;;&lt;br /&gt;
   stopped)&lt;br /&gt;
     ;;&lt;br /&gt;
   release)&lt;br /&gt;
     ;;&lt;br /&gt;
   migrate)&lt;br /&gt;
     ;;&lt;br /&gt;
   restore)&lt;br /&gt;
     ;;&lt;br /&gt;
   reconnect)&lt;br /&gt;
     ;;&lt;br /&gt;
   attach)&lt;br /&gt;
     ;;&lt;br /&gt;
   *)&lt;br /&gt;
     echo &amp;quot;qemu hook called with unexpected options $*&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
     exit 1&lt;br /&gt;
     ;;&lt;br /&gt;
 esac&lt;br /&gt;
 '''harley$''' sudo chmod 744 /etc/libvirt/hooks/qemu&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.libvirt.org/hooks.html&lt;br /&gt;
* https://serverfault.com/questions/696011/libvirt-hook-qemu-suse12&lt;br /&gt;
&lt;br /&gt;
== Workaround for setting DefaultPVID=none ==&lt;br /&gt;
Setting [https://www.freedesktop.org/software/systemd/man/systemd.netdev.html#DefaultPVID= DefaultPVID] in a&amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt; configuration file to &amp;quot;none&amp;quot; does not work. Until this bug is fixed I've made a workaround. The kernel accepts setting &amp;lt;code&amp;gt;default_pvid&amp;lt;/code&amp;gt; to 0 (means &amp;quot;none&amp;quot;) only if &amp;lt;code&amp;gt;vlan_filtering=0&amp;lt;/code&amp;gt;, so we have to do:&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/default_pvid'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 1 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Check with listing of [[#bridge-settings|bridge-settings]].&lt;br /&gt;
Theese commands must run with &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt; so we need a service for this. First I make a script and make it executable for root:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/DefaultPVID.sh &lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #echo &amp;quot;entering DefaultPVID.sh&amp;quot; &amp;gt;&amp;gt;/tmp/debug.log&lt;br /&gt;
 &lt;br /&gt;
 BRDIR=&amp;quot;/sys/class/net/br0/bridge/&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 if &amp;amp;#91;[ -f $BRDIR/vlan_filtering &amp;amp;&amp;amp; -f $BRDIR/default_pvid ]&amp;amp;#93;; then&lt;br /&gt;
   #echo &amp;quot;setting DefaultPVID&amp;quot; &amp;gt;&amp;gt;/tmp/debug.log&lt;br /&gt;
   VLAN_FILTERING=&amp;quot;$(cat &amp;quot;$BRDIR&amp;quot;/vlan_filtering)&amp;quot;&lt;br /&gt;
   echo 0 &amp;gt;&amp;quot;$BRDIR&amp;quot;/vlan_filtering&lt;br /&gt;
   echo 0 &amp;gt;&amp;quot;$BRDIR&amp;quot;/default_pvid&lt;br /&gt;
   echo &amp;quot;$VLAN_FILTERING&amp;quot; &amp;gt;&amp;quot;$BRDIR&amp;quot;/vlan_filtering&lt;br /&gt;
 fi&lt;br /&gt;
 exit 0&lt;br /&gt;
 '''harley$''' sudo chmod 744 /etc/systemd/network/DefaultPVID.sh&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Next I create a service to execute this script:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/system/DefaultPVID.service &lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=set DefaultPVID on a bridge as workaround&lt;br /&gt;
 Wants=network.target&lt;br /&gt;
 After=network.target&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 Type=oneshot&lt;br /&gt;
 ExecStart=/etc/systemd/network/DefaultPVID.sh&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
And then I create a [https://www.freedesktop.org/software/systemd/man/systemd.unit.html#id-1.11.3 drop-in file for overriding vendor settings] so this service will be executed together with &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt;:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/system/systemd-networkd.service.d/DefaultPVID.conf &lt;br /&gt;
 [Unit]&lt;br /&gt;
 # This is only a workaround. DefaultPVID cannot be set in&lt;br /&gt;
 # /etc/systemd/network/br0.netdev. It seems buggy.&lt;br /&gt;
 Wants=DefaultPVID.service&lt;br /&gt;
 Before=DefaultPVID.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=18</id>
		<title>VLAN for virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=18"/>
				<updated>2017-09-27T21:28:31Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: describe workaround setting DefaultPVID&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
I wanted to update VLAN connections for virtual&lt;br /&gt;
machines to newer technologies and put a question on&lt;br /&gt;
[https://unix.stackexchange.com/questions/392758/setup-vlan-on-linux-bridge-for-virtual-machines-with-systemd unix.stackexchange]. But I do not get any answer. It seems there is very&lt;br /&gt;
little knowledge for this out there. So I decided to work on it by myself&lt;br /&gt;
and document it here.&lt;br /&gt;
&lt;br /&gt;
In gerneral I will look at four methods:&lt;br /&gt;
# [[#oldstyle linux bridge as hub|oldstyle linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge as hub|linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge with libvirt hook scripts|linux bridge with libvirt hook scripts]]&lt;br /&gt;
# [[#Open vSwitch|Open vSwitch]]&lt;br /&gt;
&lt;br /&gt;
== Preparation ==&lt;br /&gt;
I have Debian GNU/Linux 9.1 (stretch) on the host and on virtual machines for testing. Setup is described here: [[Setup KVM with console]]. I'm sitting on harley as host, my all day workstation.&lt;br /&gt;
Now I start the virtual machine, login and show its interface setting:&lt;br /&gt;
 '''harley$''' virsh start --console deb9-test&lt;br /&gt;
login&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/08-vlan10.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 Kind=vlan&lt;br /&gt;
 [VLAN]&lt;br /&gt;
 Id=10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/12-vlan10_attach-to-if.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=ens2&lt;br /&gt;
 [Network]&lt;br /&gt;
 VLAN=vlan10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/16-vlan10_up.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 [Network]&lt;br /&gt;
 DHCP=ipv4&lt;br /&gt;
 IPv6AcceptRA=no&lt;br /&gt;
 LinkLocalAddressing=no&lt;br /&gt;
To test if the virtual machine has connection I use:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:34:20 CEST. --&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: Enumeration completed&lt;br /&gt;
 Sep 23 20:34:05 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: DHCPv4 address 192.168.10.89/24 via 192.168.10.1&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: Configured&lt;br /&gt;
 Sep 23 20:34:19 systemd-networkd[204]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
4 sec after Started Network Service it gets an IP-Address and 14 sec later interface ens2 was Configured. If ens2 is Configured and the guest hasn't got an IP-Address the connection failed. It looks like this:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:45:13 CEST. --&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: Enumeration completed&lt;br /&gt;
 Sep 23 20:44:59 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:13 systemd-networkd[197]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
&lt;br /&gt;
Because I have to start the test virtual machine many times I setup autologin. It's no problem. There is nothing on the guest.&lt;br /&gt;
 '''deb9-test$''' grep ^ExecStart= /lib/systemd/system/serial-getty@.service&lt;br /&gt;
 ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
modify to&lt;br /&gt;
 ExecStart=-/sbin/agetty --autologin ''yourloginname'' --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
&amp;lt;span id=&amp;quot;bridge-settings&amp;quot;&amp;gt;To list all settings of the bridge&amp;lt;/span&amp;gt; you can use:&lt;br /&gt;
 '''harley$''' find /sys/class/net/br0/bridge/ -type f -readable -printf '%f = ' -exec cat {} \; | sort&lt;br /&gt;
&lt;br /&gt;
== oldstyle linux bridge as hub ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Disable systemd-networkd and start networking with ifupdown:&lt;br /&gt;
 '''harley$''' sudo systemctl stop systemd-networkd&lt;br /&gt;
 Warning: Stopping systemd-networkd.service, but it can still be activated by:&lt;br /&gt;
   systemd-networkd.socket&lt;br /&gt;
 '''harley$''' sudo systemctl disable systemd-networkd&lt;br /&gt;
 Removed /etc/systemd/system/multi-user.target.wants/systemd-networkd.service.&lt;br /&gt;
 Removed /etc/systemd/system/sockets.target.wants/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install enable networking&lt;br /&gt;
 '''harley$''' sudo systemctl start networking.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/network/interfaces&lt;br /&gt;
 auto br0&lt;br /&gt;
 iface br0 inet manual&lt;br /&gt;
     bridge_ports enp1s0&lt;br /&gt;
     bridge_ageing 0&lt;br /&gt;
     bridge_stp off&lt;br /&gt;
 '''harley$''' sudo ifup br0&lt;br /&gt;
 Waiting for br0 to get ready (MAXWAIT is 32 seconds).&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
It's all in place now:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
Yes, there is no VLAN filtering, means VLAN on the bridge is disabled but the guest sees the VLAN-tagged packets.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://wiki.debian.org/NetworkConfiguration#Bridging_without_Switching&lt;br /&gt;
&lt;br /&gt;
== linux bridge as hub ==&lt;br /&gt;
Now I try to setup [[#oldstyle linux bridge as hub]] just with systemd-networkd.&lt;br /&gt;
&lt;br /&gt;
Disable networking with ifupdown and start systemd-networkd:&lt;br /&gt;
 '''harley$''' sudo systemctl stop networking.service&lt;br /&gt;
 '''harley$''' sudo systemctl disable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install disable networking&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable systemd-networkd&lt;br /&gt;
 Created symlink /etc/systemd/system/multi-user.target.wants/systemd-networkd.service → /lib/systemd/system/systemd-networkd.service.&lt;br /&gt;
 Created symlink /etc/systemd/system/sockets.target.wants/systemd-networkd.socket → /lib/systemd/system/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo systemctl start systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/08-br0.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 AgeingTimeSec=0&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/12-br0_add-enp1s0.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl restart systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
AgeingTimeSec=0 is not acepted but should:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 30000   (means 300 sec)&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
But I've found a workaround. Useing a number between '''.'''01 and '''.'''000001 (there are dots) will set ageing_time to 0.&lt;br /&gt;
So set AgeingTimeSec='''.'''000001 in /etc/systemd/network/08-br0.netdev. I suppose it's a bug. Then we&lt;br /&gt;
will get:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets now an IP-Address on boot and is connected to VLAN 10.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
This works because of [[#References|three conditions]].&lt;br /&gt;
# ageing time is 0: ageing time specifies the number of seconds a MAC Address will be kept in the forwarding database after having a packet received from this MAC Address. Setting it to 0 means there is never a MAC Address stored in the FDB.&lt;br /&gt;
# unicast flood on interfaces is on: this controls whether the bridge should flood traffic for which an FDB entry is missing and the destination is unknown through this port. Defaults to on.&lt;br /&gt;
# spanning tree protocol (stp) is disabled: we don't have a forward_delay at startup for the learning phase of spanning tree.&lt;br /&gt;
I have a running and connected virtual machine:&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   1 PVID Egress Untagged&lt;br /&gt;
 br0      1 PVID Egress Untagged&lt;br /&gt;
 vnet0    1 PVID Egress Untagged&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time&lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/forward_delay&lt;br /&gt;
 1500&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state&lt;br /&gt;
 0&lt;br /&gt;
Indeed we have forward_delay 1500 (means 15 sec) but it doesn't matter. stp_state is 0 (disabled), no spanning tree. Flood (means unicast flood) is on as I can see:&lt;br /&gt;
 '''harley$''' sudo bridge -d link show&lt;br /&gt;
 ''3: enp1s0'' state UP : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 4&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on &lt;br /&gt;
 ''95: vnet0'' state UNKNOWN : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 100&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let's have a look at flooding on the interfaces. I disable it on the physical interface enp1s0 of the bridge and reboot the guest:&lt;br /&gt;
 '''harley$''' sudo bridge link set dev enp1s0 flood off&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets an IP-Address from the DHCP-Server but then can't ping its gateway. DHCP-REQUEST is broadcast and goes thru enp1s0. DHCP-ANSWER comes back thru it to any other (here only vnet0) interface which has flood on. Ping is unicast and isn't forwareded on enp1s0. If I set  enp1s0 flood on and vnet0 flood off and &amp;lt;code&amp;gt;'''deb9-test$ '''sudo systemctl restart systemd-networkd&amp;lt;/code&amp;gt;, I get no IP-Address from DHCP-Server and can't ping the interface. Incoming DHCP-ANSWER isn't broadcast and vnet0 doesn't forward it to the guest.&lt;br /&gt;
&lt;br /&gt;
Btw. this method has bad performance as we can see with monitor. We insert MAC-Addresses into FDB for just deleting it immediately, all for nothing.&lt;br /&gt;
 '''harley$''' sudo bridge monitor fdb&lt;br /&gt;
 52:54:00:01:76:20 dev enp1s0 master br0 &lt;br /&gt;
 52:54:00:b0:ca:63 dev vnet0 master br0 &lt;br /&gt;
 f4:f2:6d:2c:87:f7 dev enp1s0 master br0 &lt;br /&gt;
 00:80:3f:2a:31:1a dev enp1s0 master br0 &lt;br /&gt;
 Deleted 52:54:00:01:76:20 dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted 52:54:00:b0:ca:63 dev vnet0 master br0 stale&lt;br /&gt;
 Deleted 00:80:3f:2a:31:1a dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted f4:f2:6d:2c:87:f7 dev enp1s0 master br0 stale&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.netdev.html&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.network.html&lt;br /&gt;
&lt;br /&gt;
== linux bridge with libvirt hook scripts ==&lt;br /&gt;
We setup a bridge with VLAN enabled:&lt;br /&gt;
 '''harley$''' cat 08-br0.netdev &lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 DefaultPVID=none&lt;br /&gt;
 VLANFiltering=true&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat 12-br0_add-enp1s0.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=10&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=20&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=30&lt;br /&gt;
 '''harley$''' cat 16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
With this I get:&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   1 PVID Egress Untagged&lt;br /&gt;
          10&lt;br /&gt;
          20&lt;br /&gt;
          30  &lt;br /&gt;
 br0      1 PVID Egress Untagged&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
But what is this? We have default VLAN &amp;lt;code&amp;gt;1 PVID Egress Untagged&amp;lt;/code&amp;gt;. I don't want this. Seems setting &amp;lt;code&amp;gt;DefaultPVID=none&amp;lt;/code&amp;gt; in 08-br0.netdev doesn't work. I've made a [[#Workaround for setting DefaultPVID=none|Workaround for setting DefaultPVID=none]]. Looking at this behavior I found that we can set &amp;lt;code&amp;gt;default_pvid&amp;lt;/code&amp;gt; in the kernel only if &amp;lt;code&amp;gt;vlan_filtering = 0&amp;lt;/code&amp;gt;. By hand I have to do:&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/default_pvid'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 1 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
If I start a guest I will get now:&lt;br /&gt;
 '''harley$''' virsh start deb9-test&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   10&lt;br /&gt;
          20&lt;br /&gt;
          30&lt;br /&gt;
 br0     None&lt;br /&gt;
 vnet0   None&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The virtual network interface vnet0 for deb9-test has no VLAN ID. Libvirt does not know something about this so we have to tell it. Libvirt provides [https://www.libvirt.org/hooks.html hook scripts] that we can use for this. We have to:&lt;br /&gt;
# [[#define VLAN-ID the virtual machine belongs to]]&lt;br /&gt;
# [[#get information on startup from the runtime XML-config of the domain]]&lt;br /&gt;
# [[#set VLAN-ID to the dynamic virtual network interface vnet*]]&lt;br /&gt;
&amp;lt;span id=&amp;quot;debug.sh&amp;quot;&amp;gt;For debugging the hook-scripts&amp;lt;/span&amp;gt; I've made a small script:&lt;br /&gt;
 '''harley$''' cat debug.sh&lt;br /&gt;
 #!/bin/bash -e&lt;br /&gt;
 # https://www.libvirt.org/hooks.html&lt;br /&gt;
 # If you make a new hook script then 'sudo systemctl restart libvirtd'.&lt;br /&gt;
 # For debug set symlink to hook-script daemon, qemu, lxc, libxl and/or network,&lt;br /&gt;
 # e.g. 'sudo ln -s debug.sh qemu' and restart libvirtd.&lt;br /&gt;
 &lt;br /&gt;
 logfile='/var/log/libvirt/hooks.log'&lt;br /&gt;
 &lt;br /&gt;
 echo &amp;quot;$0&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 date -Iseconds &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 echo &amp;quot;\$1=$1, \$2=$2, \$3=$3, \$4=$4&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 cat - &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 echo -e &amp;quot;\n---------------------------------------------&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== define VLAN-ID the virtual machine belongs to ===&lt;br /&gt;
For this we have an extra [https://libvirt.org/formatdomain.html#elementsMetadata element &amp;lt;metadata&amp;gt; in Domain XML format] for custom metadata. We can simply add the information to the static configuration with &amp;lt;code&amp;gt;'''harley$''' virsh edit deb9-test&amp;lt;/code&amp;gt; like this (look only at the &amp;lt;metadata&amp;gt; element):&lt;br /&gt;
 '''harley$''' virsh dumpxml deb9-test | head -n9&lt;br /&gt;
 &amp;lt;domain type='kvm' id='1'&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;deb9-test&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;uuid&amp;gt;70d56a28-795d-4010-9403-513a4bd6b66a&amp;lt;/uuid&amp;gt;&lt;br /&gt;
   &amp;lt;metadata&amp;gt;&lt;br /&gt;
     &amp;lt;my:home xmlns:my=&amp;quot;http://hoeft-online.de/my/&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;my:vlan&amp;gt;10&amp;lt;/my:vlan&amp;gt;&lt;br /&gt;
     &amp;lt;/my:home&amp;gt;&lt;br /&gt;
   &amp;lt;/metadata&amp;gt;&lt;br /&gt;
   &amp;lt;memory unit='KiB'&amp;gt;1048576&amp;lt;/memory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get information on startup from the runtime XML-config of the domain ===&lt;br /&gt;
It seems a little bit difficult to get needed information out of the big XML-config but it's no problem with XSLT. I've made a XSL-stylesheet for this and use xmlstarlet. Start a virtual machine and then its runtime configuration is available with &amp;lt;code&amp;gt;'''harley$''' virsh dumpxml deb9-test | xmlstarlet tr qemu.xsl&amp;lt;/code&amp;gt;. With this I can test my stylesheet. Here is it:&lt;br /&gt;
 '''harley$''' cat qemu.xsl &lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;amp;lt;!-- This stylesheet extracts the VLAN-ID and the target device of the&lt;br /&gt;
      bridge from the domain-xml given to the libvirt hook-script &amp;quot;qemu&amp;quot;.&lt;br /&gt;
      Example output: &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;&lt;br /&gt;
 --&amp;amp;gt;&lt;br /&gt;
 &amp;lt;xsl:stylesheet version=&amp;quot;1.0&amp;quot; xmlns:xsl=&amp;quot;http://www.w3.org/1999/XSL/Transform&amp;quot;&lt;br /&gt;
      xmlns:my=&amp;quot;http://hoeft-online.de/my/&amp;quot; exclude-result-prefixes=&amp;quot;my&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:output omit-xml-declaration=&amp;quot;yes&amp;quot; indent=&amp;quot;no&amp;quot;&lt;br /&gt;
        encoding=&amp;quot;utf-8&amp;quot; media-type=&amp;quot;text/xml&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:strip-space elements=&amp;quot;*&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;text()|@*&amp;quot;/&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;/domain&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;meta&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:apply-templates/&amp;gt;&lt;br /&gt;
     &amp;lt;/meta&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;metadata/my:home/my:vlan&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;vlan&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:value-of select=&amp;quot;.&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;/vlan&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match='interface[@type=&amp;quot;bridge&amp;quot;]/target'&amp;gt;&lt;br /&gt;
     &amp;lt;dev&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:value-of select=&amp;quot;@dev&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;/dev&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;/xsl:stylesheet&amp;gt;&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
 '''harley$''' virsh dumpxml deb9-test | xmlstarlet tr /etc/libvirt/hooks/qemu.xsl &lt;br /&gt;
 &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;'''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== set VLAN-ID to the dynamic virtual network interface vnet* ===&lt;br /&gt;
Putting it all together here is the executable hook-script:&lt;br /&gt;
 '''harley$''' cat /etc/libvirt/hooks/qemu&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #/etc/libvirt/hooks/qemu&lt;br /&gt;
 # Docs: https://www.libvirt.org/hooks.html&lt;br /&gt;
 # If you make a new hook script then 'sudo systemctl restart libvirtd'.&lt;br /&gt;
 &lt;br /&gt;
 # On startup of the domain (guest) This script does:&lt;br /&gt;
 # Get Metadata VLAN-ID of the guest and target device of the bridge from&lt;br /&gt;
     # the domain-xml available on standard input. It is the runtime&lt;br /&gt;
     # version from 'virsh dumpxml domainname'. For extracting the&lt;br /&gt;
     # information we use a XSL-stylesheet. Example input into $META:&lt;br /&gt;
     # &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;&lt;br /&gt;
 # Select $DEV  from $META&lt;br /&gt;
 # Select $VLAN from $META&lt;br /&gt;
 # Set $VLAN to $DEV on the bridge&lt;br /&gt;
 &lt;br /&gt;
 case &amp;quot;$2&amp;quot; in&lt;br /&gt;
   prepare)&lt;br /&gt;
     ;;&lt;br /&gt;
   start)&lt;br /&gt;
     META=$(/usr/bin/xmlstarlet tr /etc/libvirt/hooks/qemu.xsl -)&lt;br /&gt;
     DEV=$(echo &amp;quot;$META&amp;quot; | /usr/bin/xmlstarlet sel -t -v '/meta/dev')&lt;br /&gt;
     VLAN=$(echo &amp;quot;$META&amp;quot; | /usr/bin/xmlstarlet sel -t -v '/meta/vlan')&lt;br /&gt;
     if &amp;amp;#91;[ -n $DEV &amp;amp;&amp;amp; -n $VLAN ]&amp;amp;#93;; then&lt;br /&gt;
       /sbin/bridge vlan add vid &amp;quot;$VLAN&amp;quot; dev &amp;quot;$DEV&amp;quot;&lt;br /&gt;
     fi&lt;br /&gt;
     ;;&lt;br /&gt;
   started)&lt;br /&gt;
     ;;&lt;br /&gt;
   stopped)&lt;br /&gt;
     ;;&lt;br /&gt;
   release)&lt;br /&gt;
     ;;&lt;br /&gt;
   migrate)&lt;br /&gt;
     ;;&lt;br /&gt;
   restore)&lt;br /&gt;
     ;;&lt;br /&gt;
   reconnect)&lt;br /&gt;
     ;;&lt;br /&gt;
   attach)&lt;br /&gt;
     ;;&lt;br /&gt;
   *)&lt;br /&gt;
     echo &amp;quot;qemu hook called with unexpected options $*&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
     exit 1&lt;br /&gt;
     ;;&lt;br /&gt;
 esac&lt;br /&gt;
 '''harley$''' sudo chmod 744 /etc/libvirt/hooks/qemu&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.libvirt.org/hooks.html&lt;br /&gt;
* https://serverfault.com/questions/696011/libvirt-hook-qemu-suse12&lt;br /&gt;
&lt;br /&gt;
== Workaround for setting DefaultPVID=none ==&lt;br /&gt;
Setting [https://www.freedesktop.org/software/systemd/man/systemd.netdev.html#DefaultPVID= DefaultPVID] in a&amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt; configuration file to &amp;quot;none&amp;quot; does not work. Until this bug is fixed I've made a workaround. The kernel accepts setting &amp;lt;code&amp;gt;default_pvid&amp;lt;/code&amp;gt; to 0 (means &amp;quot;none&amp;quot;) only if &amp;lt;code&amp;gt;vlan_filtering=0&amp;lt;/code&amp;gt;, so we have to do:&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/default_pvid'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 1 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Check with listing of [[#bridge-settings|bridge-settings]].&lt;br /&gt;
Theese commands must run with &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt; so we need a service for this. First I make a script and make it executable for root:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/DefaultPVID.sh &lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 #echo &amp;quot;entering DefaultPVID.sh&amp;quot; &amp;gt;&amp;gt;/tmp/debug.log&lt;br /&gt;
 &lt;br /&gt;
 BRDIR=&amp;quot;/sys/class/net/br0/bridge/&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 if &amp;amp;#91;[ -f $BRDIR/vlan_filtering &amp;amp;&amp;amp; -f $BRDIR/default_pvid ]&amp;amp;#93;; then&lt;br /&gt;
   #echo &amp;quot;setting DefaultPVID&amp;quot; &amp;gt;&amp;gt;/tmp/debug.log&lt;br /&gt;
   VLAN_FILTERING=&amp;quot;$(cat &amp;quot;$BRDIR&amp;quot;/vlan_filtering)&amp;quot;&lt;br /&gt;
   echo 0 &amp;gt;&amp;quot;$BRDIR&amp;quot;/vlan_filtering&lt;br /&gt;
   echo 0 &amp;gt;&amp;quot;$BRDIR&amp;quot;/default_pvid&lt;br /&gt;
   echo &amp;quot;$VLAN_FILTERING&amp;quot; &amp;gt;&amp;quot;$BRDIR&amp;quot;/vlan_filtering&lt;br /&gt;
 fi&lt;br /&gt;
 exit 0&lt;br /&gt;
 '''harley$''' sudo chmod 744 /etc/systemd/network/DefaultPVID.sh&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Next I create a service to execute this script:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/system/DefaultPVID.service &lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=set DefaultPVID on a bridge as workaround&lt;br /&gt;
 Wants=network.target&lt;br /&gt;
 After=network.target&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 Type=oneshot&lt;br /&gt;
 ExecStart=/etc/systemd/network/DefaultPVID.sh&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
And then I create a [https://www.freedesktop.org/software/systemd/man/systemd.unit.html#id-1.11.3 drop-in file for overriding vendor settings] so this service will be executed together with &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt;:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/system/systemd-networkd.service.d/DefaultPVID.conf &lt;br /&gt;
 [Unit]&lt;br /&gt;
 # This is only a workaround. DefaultPVID cannot be set in&lt;br /&gt;
 # /etc/systemd/network/br0.netdev. It seems buggy.&lt;br /&gt;
 Wants=DefaultPVID.service&lt;br /&gt;
 Before=DefaultPVID.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=17</id>
		<title>VLAN for virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=17"/>
				<updated>2017-09-27T14:13:32Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: describe bridge with hook scripts&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
I wanted to update VLAN connections for virtual&lt;br /&gt;
machines to newer technologies and put a question on&lt;br /&gt;
[https://unix.stackexchange.com/questions/392758/setup-vlan-on-linux-bridge-for-virtual-machines-with-systemd unix.stackexchange]. But I do not get any answer. It seems there is very&lt;br /&gt;
little knowledge for this out there. So I decided to work on it by myself&lt;br /&gt;
and document it here.&lt;br /&gt;
&lt;br /&gt;
In gerneral I will look at four methods:&lt;br /&gt;
# [[#oldstyle linux bridge as hub|oldstyle linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge as hub|linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge with libvirt hook scripts|linux bridge with libvirt hook scripts]]&lt;br /&gt;
# [[#Open vSwitch|Open vSwitch]]&lt;br /&gt;
&lt;br /&gt;
== Preparation ==&lt;br /&gt;
I have Debian GNU/Linux 9.1 (stretch) on the host and on virtual machines for testing. Setup is described here: [[Setup KVM with console]]. I'm sitting on harley as host, my all day workstation.&lt;br /&gt;
Now I start the virtual machine, login and show its interface setting:&lt;br /&gt;
 '''harley$''' virsh start --console deb9-test&lt;br /&gt;
login&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/08-vlan10.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 Kind=vlan&lt;br /&gt;
 [VLAN]&lt;br /&gt;
 Id=10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/12-vlan10_attach-to-if.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=ens2&lt;br /&gt;
 [Network]&lt;br /&gt;
 VLAN=vlan10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/16-vlan10_up.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 [Network]&lt;br /&gt;
 DHCP=ipv4&lt;br /&gt;
 IPv6AcceptRA=no&lt;br /&gt;
 LinkLocalAddressing=no&lt;br /&gt;
To test if the virtual machine has connection I use:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:34:20 CEST. --&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: Enumeration completed&lt;br /&gt;
 Sep 23 20:34:05 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: DHCPv4 address 192.168.10.89/24 via 192.168.10.1&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: Configured&lt;br /&gt;
 Sep 23 20:34:19 systemd-networkd[204]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
4 sec after Started Network Service it gets an IP-Address and 14 sec later interface ens2 was Configured. If ens2 is Configured and the guest hasn't got an IP-Address the connection failed. It looks like this:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:45:13 CEST. --&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: Enumeration completed&lt;br /&gt;
 Sep 23 20:44:59 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:13 systemd-networkd[197]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
&lt;br /&gt;
Because I have to start the test virtual machine many times I setup autologin. It's no problem. There is nothing on the guest.&lt;br /&gt;
 '''deb9-test$''' grep ^ExecStart= /lib/systemd/system/serial-getty@.service&lt;br /&gt;
 ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
modify to&lt;br /&gt;
 ExecStart=-/sbin/agetty --autologin ''yourloginname'' --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
To list all settings of the bridge you can use:&lt;br /&gt;
 '''harley$''' find /sys/class/net/br0/bridge/ -type f -readable -printf '%f = ' -exec cat {} \; | sort&lt;br /&gt;
&lt;br /&gt;
== oldstyle linux bridge as hub ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Disable systemd-networkd and start networking with ifupdown:&lt;br /&gt;
 '''harley$''' sudo systemctl stop systemd-networkd&lt;br /&gt;
 Warning: Stopping systemd-networkd.service, but it can still be activated by:&lt;br /&gt;
   systemd-networkd.socket&lt;br /&gt;
 '''harley$''' sudo systemctl disable systemd-networkd&lt;br /&gt;
 Removed /etc/systemd/system/multi-user.target.wants/systemd-networkd.service.&lt;br /&gt;
 Removed /etc/systemd/system/sockets.target.wants/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install enable networking&lt;br /&gt;
 '''harley$''' sudo systemctl start networking.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/network/interfaces&lt;br /&gt;
 auto br0&lt;br /&gt;
 iface br0 inet manual&lt;br /&gt;
     bridge_ports enp1s0&lt;br /&gt;
     bridge_ageing 0&lt;br /&gt;
     bridge_stp off&lt;br /&gt;
 '''harley$''' sudo ifup br0&lt;br /&gt;
 Waiting for br0 to get ready (MAXWAIT is 32 seconds).&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
It's all in place now:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
Yes, there is no VLAN filtering, means VLAN on the bridge is disabled but the guest sees the VLAN-tagged packets.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://wiki.debian.org/NetworkConfiguration#Bridging_without_Switching&lt;br /&gt;
&lt;br /&gt;
== linux bridge as hub ==&lt;br /&gt;
Now I try to setup [[#oldstyle linux bridge as hub]] just with systemd-networkd.&lt;br /&gt;
&lt;br /&gt;
Disable networking with ifupdown and start systemd-networkd:&lt;br /&gt;
 '''harley$''' sudo systemctl stop networking.service&lt;br /&gt;
 '''harley$''' sudo systemctl disable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install disable networking&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable systemd-networkd&lt;br /&gt;
 Created symlink /etc/systemd/system/multi-user.target.wants/systemd-networkd.service → /lib/systemd/system/systemd-networkd.service.&lt;br /&gt;
 Created symlink /etc/systemd/system/sockets.target.wants/systemd-networkd.socket → /lib/systemd/system/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo systemctl start systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/08-br0.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 AgeingTimeSec=0&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/12-br0_add-enp1s0.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl restart systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
AgeingTimeSec=0 is not acepted but should:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 30000   (means 300 sec)&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
But I've found a workaround. Useing a number between '''.'''01 and '''.'''000001 (there are dots) will set ageing_time to 0.&lt;br /&gt;
So set AgeingTimeSec='''.'''000001 in /etc/systemd/network/08-br0.netdev. I suppose it's a bug. Then we&lt;br /&gt;
will get:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets now an IP-Address on boot and is connected to VLAN 10.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
This works because of [[#References|three conditions]].&lt;br /&gt;
# ageing time is 0: ageing time specifies the number of seconds a MAC Address will be kept in the forwarding database after having a packet received from this MAC Address. Setting it to 0 means there is never a MAC Address stored in the FDB.&lt;br /&gt;
# unicast flood on interfaces is on: this controls whether the bridge should flood traffic for which an FDB entry is missing and the destination is unknown through this port. Defaults to on.&lt;br /&gt;
# spanning tree protocol (stp) is disabled: we don't have a forward_delay at startup for the learning phase of spanning tree.&lt;br /&gt;
I have a running and connected virtual machine:&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   1 PVID Egress Untagged&lt;br /&gt;
 br0      1 PVID Egress Untagged&lt;br /&gt;
 vnet0    1 PVID Egress Untagged&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time&lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/forward_delay&lt;br /&gt;
 1500&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state&lt;br /&gt;
 0&lt;br /&gt;
Indeed we have forward_delay 1500 (means 15 sec) but it doesn't matter. stp_state is 0 (disabled), no spanning tree. Flood (means unicast flood) is on as I can see:&lt;br /&gt;
 '''harley$''' sudo bridge -d link show&lt;br /&gt;
 ''3: enp1s0'' state UP : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 4&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on &lt;br /&gt;
 ''95: vnet0'' state UNKNOWN : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 100&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let's have a look at flooding on the interfaces. I disable it on the physical interface enp1s0 of the bridge and reboot the guest:&lt;br /&gt;
 '''harley$''' sudo bridge link set dev enp1s0 flood off&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets an IP-Address from the DHCP-Server but then can't ping its gateway. DHCP-REQUEST is broadcast and goes thru enp1s0. DHCP-ANSWER comes back thru it to any other (here only vnet0) interface which has flood on. Ping is unicast and isn't forwareded on enp1s0. If I set  enp1s0 flood on and vnet0 flood off and &amp;lt;code&amp;gt;'''deb9-test$ '''sudo systemctl restart systemd-networkd&amp;lt;/code&amp;gt;, I get no IP-Address from DHCP-Server and can't ping the interface. Incoming DHCP-ANSWER isn't broadcast and vnet0 doesn't forward it to the guest.&lt;br /&gt;
&lt;br /&gt;
Btw. this method has bad performance as we can see with monitor. We insert MAC-Addresses into FDB for just deleting it immediately, all for nothing.&lt;br /&gt;
 '''harley$''' sudo bridge monitor fdb&lt;br /&gt;
 52:54:00:01:76:20 dev enp1s0 master br0 &lt;br /&gt;
 52:54:00:b0:ca:63 dev vnet0 master br0 &lt;br /&gt;
 f4:f2:6d:2c:87:f7 dev enp1s0 master br0 &lt;br /&gt;
 00:80:3f:2a:31:1a dev enp1s0 master br0 &lt;br /&gt;
 Deleted 52:54:00:01:76:20 dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted 52:54:00:b0:ca:63 dev vnet0 master br0 stale&lt;br /&gt;
 Deleted 00:80:3f:2a:31:1a dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted f4:f2:6d:2c:87:f7 dev enp1s0 master br0 stale&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.netdev.html&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.network.html&lt;br /&gt;
&lt;br /&gt;
== linux bridge with libvirt hook scripts ==&lt;br /&gt;
We setup a bridge with VLAN enabled:&lt;br /&gt;
 '''harley$''' cat 08-br0.netdev &lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 DefaultPVID=none&lt;br /&gt;
 VLANFiltering=true&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat 12-br0_add-enp1s0.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=10&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=20&lt;br /&gt;
 [BridgeVLAN]&lt;br /&gt;
 VLAN=30&lt;br /&gt;
 '''harley$''' cat 16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
With this I get:&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   1 PVID Egress Untagged&lt;br /&gt;
          10&lt;br /&gt;
          20&lt;br /&gt;
          30  &lt;br /&gt;
 br0      1 PVID Egress Untagged&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
But what is this? We have default VLAN &amp;lt;code&amp;gt;1 PVID Egress Untagged&amp;lt;/code&amp;gt;. I don't want this. Seems setting &amp;lt;code&amp;gt;DefaultPVID=none&amp;lt;/code&amp;gt; in 08-br0.netdev doesn't work. I've made a [[#Workaround for setting DefaultPVID=none|Workaround for setting DefaultPVID=none]]. Looking at this behavior I found that we can set &amp;lt;code&amp;gt;default_pvid&amp;lt;/code&amp;gt; in the kernel only if &amp;lt;code&amp;gt;vlan_filtering = 0&amp;lt;/code&amp;gt;. By hand I have to do:&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 0 &amp;gt;/sys/class/net/br0/bridge/default_pvid'&lt;br /&gt;
 '''harley$''' sudo bash -c 'echo 1 &amp;gt;/sys/class/net/br0/bridge/vlan_filtering'&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
If I start a guest I will get now:&lt;br /&gt;
 '''harley$''' virsh start deb9-test&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   10&lt;br /&gt;
          20&lt;br /&gt;
          30&lt;br /&gt;
 br0     None&lt;br /&gt;
 vnet0   None&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The virtual network interface vnet0 for deb9-test has no VLAN Id. Libvirt does not know something about this so we have to tell it. Libvirt provides [https://www.libvirt.org/hooks.html hook scripts] that we can use for this. We have to:&lt;br /&gt;
# [[#define VLAN-ID the virtual machine belongs to]]&lt;br /&gt;
# [[#get information on startup from the runtime XML-config of the domain]]&lt;br /&gt;
# [[#set VLAN-ID to the dynamic virtual network interface vnet*]]&lt;br /&gt;
&amp;lt;span id=&amp;quot;debug.sh&amp;quot;&amp;gt;For debugging the hook-scripts&amp;lt;/span&amp;gt; I've made a small script:&lt;br /&gt;
 '''harley$''' cat debug.sh&lt;br /&gt;
 #!/bin/bash -e&lt;br /&gt;
 # https://www.libvirt.org/hooks.html&lt;br /&gt;
 # If you make a new hook script then 'sudo systemctl restart libvirtd'.&lt;br /&gt;
 # For debug set symlink to hook-script daemon, qemu, lxc, libxl and/or network,&lt;br /&gt;
 # e.g. 'sudo ln -s debug.sh qemu' and restart libvirtd.&lt;br /&gt;
 &lt;br /&gt;
 logfile='/var/log/libvirt/hooks.log'&lt;br /&gt;
 &lt;br /&gt;
 echo &amp;quot;$0&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 date -Iseconds &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 echo &amp;quot;\$1=$1, \$2=$2, \$3=$3, \$4=$4&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 cat - &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 echo -e &amp;quot;\n---------------------------------------------&amp;quot; &amp;gt;&amp;gt;$logfile&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== define VLAN-ID the virtual machine belongs to ===&lt;br /&gt;
For thist we have an extra [https://libvirt.org/formatdomain.html#elementsMetadata element &amp;lt;metadata&amp;gt; in Domain XML format] for custom metadata. We can simply add the information to the static configuration with &amp;lt;code&amp;gt;'''harley$''' virsh edit deb9-test&amp;lt;/code&amp;gt; like this (look only at the &amp;lt;metadata&amp;gt; element):&lt;br /&gt;
 '''harley$''' virsh dumpxml deb9-test | head -n9&lt;br /&gt;
 &amp;lt;domain type='kvm' id='1'&amp;gt;&lt;br /&gt;
   &amp;lt;name&amp;gt;deb9-test&amp;lt;/name&amp;gt;&lt;br /&gt;
   &amp;lt;uuid&amp;gt;70d56a28-795d-4010-9403-513a4bd6b66a&amp;lt;/uuid&amp;gt;&lt;br /&gt;
   &amp;lt;metadata&amp;gt;&lt;br /&gt;
     &amp;lt;my:home xmlns:my=&amp;quot;http://hoeft-online.de/my/&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;my:vlan&amp;gt;10&amp;lt;/my:vlan&amp;gt;&lt;br /&gt;
     &amp;lt;/my:home&amp;gt;&lt;br /&gt;
   &amp;lt;/metadata&amp;gt;&lt;br /&gt;
   &amp;lt;memory unit='KiB'&amp;gt;1048576&amp;lt;/memory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get information on startup from the runtime XML-config of the domain ===&lt;br /&gt;
It seems a little bit difficult to get needed information out of the big XML-config but it's no problem with XSLT. I've made a XSL-stylesheet for this and use xmlstarlet. For developing I took a snapshot from runtime XML-config useing [[#debug.sh|debug.sh]] and prepaired it to a well formed xml-document by hand for hook-parameter $2=start. This is the result:&lt;br /&gt;
 '''harley$''' cat qemu.xsl &lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;amp;lt;!-- This stylesheet extracts the VLAN-Id and the target device of the&lt;br /&gt;
      bridge from the domain-xml given to the libvirt hook-script &amp;quot;qemu&amp;quot;.&lt;br /&gt;
      Example output: &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;&lt;br /&gt;
 --&amp;amp;gt;&lt;br /&gt;
 &amp;lt;xsl:stylesheet version=&amp;quot;1.0&amp;quot; xmlns:xsl=&amp;quot;http://www.w3.org/1999/XSL/Transform&amp;quot;&lt;br /&gt;
      xmlns:my=&amp;quot;http://hoeft-online.de/my/&amp;quot; exclude-result-prefixes=&amp;quot;my&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:output omit-xml-declaration=&amp;quot;yes&amp;quot; indent=&amp;quot;no&amp;quot;&lt;br /&gt;
        encoding=&amp;quot;utf-8&amp;quot; media-type=&amp;quot;text/xml&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:strip-space elements=&amp;quot;*&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;text()|@*&amp;quot;/&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;/domain&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;meta&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:apply-templates/&amp;gt;&lt;br /&gt;
     &amp;lt;/meta&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match=&amp;quot;metadata/my:home/my:vlan&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;vlan&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:value-of select=&amp;quot;.&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;/vlan&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;xsl:template match='interface[@type=&amp;quot;bridge&amp;quot;]/target'&amp;gt;&lt;br /&gt;
     &amp;lt;dev&amp;gt;&lt;br /&gt;
       &amp;lt;xsl:value-of select=&amp;quot;@dev&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;/dev&amp;gt;&lt;br /&gt;
   &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;amp;lt;!-- vim: set sts=2 sw=2: --&amp;amp;t;&lt;br /&gt;
 &amp;lt;/xsl:stylesheet&amp;gt;&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
 '''harley$''' xmlstarlet tr qemu.xsl /var/log/libvirt/hooks.xml&lt;br /&gt;
 &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;'''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== set VLAN-ID to the dynamic virtual network interface vnet* ===&lt;br /&gt;
Putting it all together here is the hook-script:&lt;br /&gt;
 '''harley$''' cat /etc/libvirt/hooks/qemu&lt;br /&gt;
 #!/bin/bash -e&lt;br /&gt;
 #/etc/libvirt/hooks/qemu&lt;br /&gt;
 # Docs: https://www.libvirt.org/hooks.html&lt;br /&gt;
 # If you make a new hook script then 'sudo systemctl restart libvirtd'.&lt;br /&gt;
 &lt;br /&gt;
 # On startup of the domain (guest) This script does:&lt;br /&gt;
 # get Metadata VLAN-Id of the guest and target device of the bridge from&lt;br /&gt;
     # the domain-xml available on standard input. It is the runtime&lt;br /&gt;
     # version from 'virsh dumpxml domainname'. For extracting the&lt;br /&gt;
     # information we use a XSL-stylesheet. Example input into $META:&lt;br /&gt;
     # &amp;lt;meta&amp;gt;&amp;lt;vlan&amp;gt;10&amp;lt;/vlan&amp;gt;&amp;lt;dev&amp;gt;vnet0&amp;lt;/dev&amp;gt;&amp;lt;/meta&amp;gt;&lt;br /&gt;
 # Select $DEV  from $META&lt;br /&gt;
 # Select $VLAN from $META&lt;br /&gt;
 # Set $VLAN to $DEV on the bridge&lt;br /&gt;
 &lt;br /&gt;
 case &amp;quot;$2&amp;quot; in&lt;br /&gt;
   prepare)&lt;br /&gt;
     ;;&lt;br /&gt;
   start)&lt;br /&gt;
     META=$(/usr/bin/xmlstarlet tr /etc/libvirt/hooks/qemu.xsl -)&lt;br /&gt;
     DEV=$(echo &amp;quot;$META&amp;quot; | /usr/bin/xmlstarlet sel -t -v '/meta/dev')&lt;br /&gt;
     VLAN=$(echo &amp;quot;$META&amp;quot; | /usr/bin/xmlstarlet sel -t -v '/meta/vlan')&lt;br /&gt;
     if &amp;amp;#91;[ -n $DEV &amp;amp;&amp;amp; -n $VLAN ]&amp;amp;#93;; then&lt;br /&gt;
       /sbin/bridge vlan add vid &amp;quot;$VLAN&amp;quot; dev &amp;quot;$DEV&amp;quot;&lt;br /&gt;
     fi&lt;br /&gt;
     ;;&lt;br /&gt;
   started)&lt;br /&gt;
     ;;&lt;br /&gt;
   stopped)&lt;br /&gt;
     ;;&lt;br /&gt;
   release)&lt;br /&gt;
     ;;&lt;br /&gt;
   migrate)&lt;br /&gt;
     ;;&lt;br /&gt;
   restore)&lt;br /&gt;
     ;;&lt;br /&gt;
   reconnect)&lt;br /&gt;
     ;;&lt;br /&gt;
   attach)&lt;br /&gt;
     ;;&lt;br /&gt;
   *)&lt;br /&gt;
     echo &amp;quot;qemu hook called with unexpected options $*&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
     exit 1&lt;br /&gt;
     ;;&lt;br /&gt;
 esac&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== Workaround for setting DefaultPVID=none ===&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.libvirt.org/hooks.html&lt;br /&gt;
* https://serverfault.com/questions/696011/libvirt-hook-qemu-suse12&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=16</id>
		<title>VLAN for virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=16"/>
				<updated>2017-09-24T11:01:24Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: linkfix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
I wanted to update VLAN connections for virtual&lt;br /&gt;
machines to newer technologies and put a question on&lt;br /&gt;
[https://unix.stackexchange.com/questions/392758/setup-vlan-on-linux-bridge-for-virtual-machines-with-systemd unix.stackexchange]. But I do not get any answer. It seems there is very&lt;br /&gt;
little knowledge for this out there. So I decided to work on it by myself&lt;br /&gt;
and document it here.&lt;br /&gt;
&lt;br /&gt;
In gerneral I will look at four methods:&lt;br /&gt;
# [[#oldstyle linux bridge as hub|oldstyle linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge as hub|linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge with libvirt hook scripts|linux bridge with libvirt hook scripts]]&lt;br /&gt;
# [[#Open vSwitch|Open vSwitch]]&lt;br /&gt;
&lt;br /&gt;
== Preparation ==&lt;br /&gt;
I have Debian GNU/Linux 9.1 (stretch) on the host and on virtual machines for testing. Setup is described here: [[Setup KVM with console]]. I'm sitting on harley as host, my all day workstation.&lt;br /&gt;
Now I start the virtual machine, login and show its interface setting:&lt;br /&gt;
 '''harley$''' virsh start --console deb9-test&lt;br /&gt;
login&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/08-vlan10.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 Kind=vlan&lt;br /&gt;
 [VLAN]&lt;br /&gt;
 Id=10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/12-vlan10_attach-to-if.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=ens2&lt;br /&gt;
 [Network]&lt;br /&gt;
 VLAN=vlan10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/16-vlan10_up.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 [Network]&lt;br /&gt;
 DHCP=ipv4&lt;br /&gt;
 IPv6AcceptRA=no&lt;br /&gt;
 LinkLocalAddressing=no&lt;br /&gt;
To test if the virtual machine has connection I use:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:34:20 CEST. --&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: Enumeration completed&lt;br /&gt;
 Sep 23 20:34:05 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: DHCPv4 address 192.168.10.89/24 via 192.168.10.1&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: Configured&lt;br /&gt;
 Sep 23 20:34:19 systemd-networkd[204]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
4 sec after Started Network Service it gets an IP-Address and 14 sec later interface ens2 was Configured. If ens2 is Configured and the guest hasn't got an IP-Address the connection failed. It looks like this:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:45:13 CEST. --&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: Enumeration completed&lt;br /&gt;
 Sep 23 20:44:59 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:13 systemd-networkd[197]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
&lt;br /&gt;
Because I have to start the test virtual machine many times I setup autologin. It's no problem. There is nothing on the guest.&lt;br /&gt;
 '''deb9-test$''' grep ^ExecStart= /lib/systemd/system/serial-getty@.service&lt;br /&gt;
 ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
modify to&lt;br /&gt;
 ExecStart=-/sbin/agetty --autologin ''yourloginname'' --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
To list all settings of the bridge you can use:&lt;br /&gt;
 '''harley$''' find /sys/class/net/br0/bridge/ -type f -readable -printf '%f = ' -exec cat {} \; | sort&lt;br /&gt;
&lt;br /&gt;
== oldstyle linux bridge as hub ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Disable systemd-networkd and start networking with ifupdown:&lt;br /&gt;
 '''harley$''' sudo systemctl stop systemd-networkd&lt;br /&gt;
 Warning: Stopping systemd-networkd.service, but it can still be activated by:&lt;br /&gt;
   systemd-networkd.socket&lt;br /&gt;
 '''harley$''' sudo systemctl disable systemd-networkd&lt;br /&gt;
 Removed /etc/systemd/system/multi-user.target.wants/systemd-networkd.service.&lt;br /&gt;
 Removed /etc/systemd/system/sockets.target.wants/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install enable networking&lt;br /&gt;
 '''harley$''' sudo systemctl start networking.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/network/interfaces&lt;br /&gt;
 auto br0&lt;br /&gt;
 iface br0 inet manual&lt;br /&gt;
     bridge_ports enp1s0&lt;br /&gt;
     bridge_ageing 0&lt;br /&gt;
     bridge_stp off&lt;br /&gt;
 '''harley$''' sudo ifup br0&lt;br /&gt;
 Waiting for br0 to get ready (MAXWAIT is 32 seconds).&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
It's all in place now:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
Yes, there is no VLAN filtering, means VLAN on the bridge is disabled but the guest sees the VLAN-tagged packets.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://wiki.debian.org/NetworkConfiguration#Bridging_without_Switching&lt;br /&gt;
&lt;br /&gt;
== linux bridge as hub ==&lt;br /&gt;
Now I try to setup [[#oldstyle linux bridge as hub]] just with systemd-networkd.&lt;br /&gt;
&lt;br /&gt;
Disable networking with ifupdown and start systemd-networkd:&lt;br /&gt;
 '''harley$''' sudo systemctl stop networking.service&lt;br /&gt;
 '''harley$''' sudo systemctl disable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install disable networking&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable systemd-networkd&lt;br /&gt;
 Created symlink /etc/systemd/system/multi-user.target.wants/systemd-networkd.service → /lib/systemd/system/systemd-networkd.service.&lt;br /&gt;
 Created symlink /etc/systemd/system/sockets.target.wants/systemd-networkd.socket → /lib/systemd/system/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo systemctl start systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/08-br0.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 AgeingTimeSec=0&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/12-br0_add-enp1s0.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl restart systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
AgeingTimeSec=0 is not acepted but should:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 30000   (means 300 sec)&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
But I've found a workaround. Useing a number between '''.'''01 and '''.'''000001 (there are dots) will set ageing_time to 0.&lt;br /&gt;
So set AgeingTimeSec='''.'''000001 in /etc/systemd/network/08-br0.netdev. I suppose it's a bug. Then we&lt;br /&gt;
will get:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets now an IP-Address on boot and is connected to VLAN 10.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
This works because of [[#References|three conditions]].&lt;br /&gt;
# ageing time is 0: ageing time specifies the number of seconds a MAC Address will be kept in the forwarding database after having a packet received from this MAC Address. Setting it to 0 means there is never a MAC Address stored in the FDB.&lt;br /&gt;
# unicast flood on interfaces is on: this controls whether the bridge should flood traffic for which an FDB entry is missing and the destination is unknown through this port. Defaults to on.&lt;br /&gt;
# spanning tree protocol (stp) is disabled: we don't have a forward_delay at startup for the learning phase of spanning tree.&lt;br /&gt;
I have a running and connected virtual machine:&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   1 PVID Egress Untagged&lt;br /&gt;
 br0      1 PVID Egress Untagged&lt;br /&gt;
 vnet0    1 PVID Egress Untagged&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time&lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/forward_delay&lt;br /&gt;
 1500&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state&lt;br /&gt;
 0&lt;br /&gt;
Indeed we have forward_delay 1500 (means 15 sec) but it doesn't matter. stp_state is 0 (disabled), no spanning tree. Flood (means unicast flood) is on as I can see:&lt;br /&gt;
 '''harley$''' sudo bridge -d link show&lt;br /&gt;
 ''3: enp1s0'' state UP : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 4&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on &lt;br /&gt;
 ''95: vnet0'' state UNKNOWN : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 100&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let's have a look at flooding on the interfaces. I disable it on the physical interface enp1s0 of the bridge and reboot the guest:&lt;br /&gt;
 '''harley$''' sudo bridge link set dev enp1s0 flood off&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets an IP-Address from the DHCP-Server but then can't ping its gateway. DHCP-REQUEST is broadcast and goes thru enp1s0. DHCP-ANSWER comes back thru it to any other (here only vnet0) interface which has flood on. Ping is unicast and isn't forwareded on enp1s0. If I set  enp1s0 flood on and vnet0 flood off and &amp;lt;code&amp;gt;'''deb9-test$ '''sudo systemctl restart systemd-networkd&amp;lt;/code&amp;gt;, I get no IP-Address from DHCP-Server and can't ping the interface. Incoming DHCP-ANSWER isn't broadcast and vnet0 doesn't forward it to the guest.&lt;br /&gt;
&lt;br /&gt;
Btw. this method has bad performance as we can see with monitor. We insert MAC-Addresses into FDB for just deleting it immediately, all for nothing.&lt;br /&gt;
 '''harley$''' sudo bridge monitor fdb&lt;br /&gt;
 52:54:00:01:76:20 dev enp1s0 master br0 &lt;br /&gt;
 52:54:00:b0:ca:63 dev vnet0 master br0 &lt;br /&gt;
 f4:f2:6d:2c:87:f7 dev enp1s0 master br0 &lt;br /&gt;
 00:80:3f:2a:31:1a dev enp1s0 master br0 &lt;br /&gt;
 Deleted 52:54:00:01:76:20 dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted 52:54:00:b0:ca:63 dev vnet0 master br0 stale&lt;br /&gt;
 Deleted 00:80:3f:2a:31:1a dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted f4:f2:6d:2c:87:f7 dev enp1s0 master br0 stale&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.netdev.html&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.network.html&lt;br /&gt;
&lt;br /&gt;
== linux bridge with libvirt hook scripts ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.libvirt.org/hooks.html&lt;br /&gt;
* https://serverfault.com/questions/696011/libvirt-hook-qemu-suse12&lt;br /&gt;
&lt;br /&gt;
== Open vSwitch ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://libvirt.org/formatnetwork.html&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=15</id>
		<title>VLAN for virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=15"/>
				<updated>2017-09-23T23:57:22Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: revise descriptions, add discussion&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
I wanted to update VLAN connections for virtual&lt;br /&gt;
machines to newer technologies and put a question on&lt;br /&gt;
[https://unix.stackexchange.com/questions/392758/setup-vlan-on-linux-bridge-for-virtual-machines-with-systemd unix.stackexchange]. But I do not get any answer. It seems there is very&lt;br /&gt;
little knowledge for this out there. So I decided to work on it by myself&lt;br /&gt;
and document it here.&lt;br /&gt;
&lt;br /&gt;
In gerneral I will look at four methods:&lt;br /&gt;
# [[#oldstyle linux bridge as hub|oldstyle linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge as hub|linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge with libvirt hook scripts|linux bridge with libvirt hook scripts]]&lt;br /&gt;
# [[#Open vSwitch|Open vSwitch]]&lt;br /&gt;
&lt;br /&gt;
== Preparation ==&lt;br /&gt;
I have Debian GNU/Linux 9.1 (stretch) on the host and on virtual machines for testing. Setup is described here: [[Setup KVM with console]]. I'm sitting on harley as host, my all day workstation.&lt;br /&gt;
Now I start the virtual machine, login and show its interface setting:&lt;br /&gt;
 '''harley$''' virsh start --console deb9-test&lt;br /&gt;
login&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/08-vlan10.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 Kind=vlan&lt;br /&gt;
 [VLAN]&lt;br /&gt;
 Id=10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/12-vlan10_attach-to-if.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=ens2&lt;br /&gt;
 [Network]&lt;br /&gt;
 VLAN=vlan10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/16-vlan10_up.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 [Network]&lt;br /&gt;
 DHCP=ipv4&lt;br /&gt;
 IPv6AcceptRA=no&lt;br /&gt;
 LinkLocalAddressing=no&lt;br /&gt;
To test if the virtual machine has connection I use:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:34:20 CEST. --&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: Enumeration completed&lt;br /&gt;
 Sep 23 20:34:05 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:34:05 systemd-networkd[204]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:06 systemd-networkd[204]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: DHCPv4 address 192.168.10.89/24 via 192.168.10.1&lt;br /&gt;
 Sep 23 20:34:09 systemd-networkd[204]: vlan10: Configured&lt;br /&gt;
 Sep 23 20:34:19 systemd-networkd[204]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
4 sec after Started Network Service it gets an IP-Address and 14 sec later interface ens2 was Configured. If ens2 is Configured and the guest hasn't got an IP-Address the connection failed. It looks like this:&lt;br /&gt;
 '''deb9-test$''' journalctl -b --no-hostname -u systemd-networkd.service&lt;br /&gt;
 -- Logs begin at Fri 2017-09-15 17:09:51 CEST, end at Sat 2017-09-23 20:45:13 CEST. --&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: Enumeration completed&lt;br /&gt;
 Sep 23 20:44:59 systemd[1]: Started Network Service.&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: netdev ready&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: IPv6 enabled for interface: Success&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: ens2: Gained carrier&lt;br /&gt;
 Sep 23 20:44:59 systemd-networkd[197]: vlan10: Gained carrier&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: ens2: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:00 systemd-networkd[197]: vlan10: Gained IPv6LL&lt;br /&gt;
 Sep 23 20:45:13 systemd-networkd[197]: ens2: Configured&lt;br /&gt;
 '''deb9-test$'''&lt;br /&gt;
&lt;br /&gt;
Because I have to start the test virtual machine many times I setup autologin. It's no problem. There is nothing on the guest.&lt;br /&gt;
 '''deb9-test$''' grep ^ExecStart= /lib/systemd/system/serial-getty@.service&lt;br /&gt;
 ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
modify to&lt;br /&gt;
 ExecStart=-/sbin/agetty --autologin ''yourloginname'' --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
To list all settings of the bridge you can use:&lt;br /&gt;
 '''harley$''' find /sys/class/net/br0/bridge/ -type f -readable -printf '%f = ' -exec cat {} \; | sort&lt;br /&gt;
&lt;br /&gt;
== oldstyle linux bridge as hub ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Disable systemd-networkd and start networking with ifupdown:&lt;br /&gt;
 '''harley$''' sudo systemctl stop systemd-networkd&lt;br /&gt;
 Warning: Stopping systemd-networkd.service, but it can still be activated by:&lt;br /&gt;
   systemd-networkd.socket&lt;br /&gt;
 '''harley$''' sudo systemctl disable systemd-networkd&lt;br /&gt;
 Removed /etc/systemd/system/multi-user.target.wants/systemd-networkd.service.&lt;br /&gt;
 Removed /etc/systemd/system/sockets.target.wants/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install enable networking&lt;br /&gt;
 '''harley$''' sudo systemctl start networking.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/network/interfaces&lt;br /&gt;
 auto br0&lt;br /&gt;
 iface br0 inet manual&lt;br /&gt;
     bridge_ports enp1s0&lt;br /&gt;
     bridge_ageing 0&lt;br /&gt;
     bridge_stp off&lt;br /&gt;
 '''harley$''' sudo ifup br0&lt;br /&gt;
 Waiting for br0 to get ready (MAXWAIT is 32 seconds).&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
It's all in place now:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
Yes, there is no VLAN filtering, means VLAN on the bridge is disabled but the guest sees the VLAN-tagged packets.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://wiki.debian.org/NetworkConfiguration#Bridging_without_Switching&lt;br /&gt;
&lt;br /&gt;
== linux bridge as hub ==&lt;br /&gt;
Now I try to setup [[#oldstyle linux bridge as hub]] just with systemd-networkd.&lt;br /&gt;
&lt;br /&gt;
Disable networking with ifupdown and start systemd-networkd:&lt;br /&gt;
 '''harley$''' sudo systemctl stop networking.service&lt;br /&gt;
 '''harley$''' sudo systemctl disable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install disable networking&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable systemd-networkd&lt;br /&gt;
 Created symlink /etc/systemd/system/multi-user.target.wants/systemd-networkd.service → /lib/systemd/system/systemd-networkd.service.&lt;br /&gt;
 Created symlink /etc/systemd/system/sockets.target.wants/systemd-networkd.socket → /lib/systemd/system/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo systemctl start systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/08-br0.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 AgeingTimeSec=0&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/12-br0_add-enp1s0.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl restart systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
AgeingTimeSec=0 is not acepted but should:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 30000   (means 300 sec)&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
But I've found a workaround. Useing a number between '''.'''01 and '''.'''000001 (there are dots) will set ageing_time to 0.&lt;br /&gt;
So set AgeingTimeSec='''.'''000001 in /etc/systemd/network/08-br0.netdev. I suppose it's a bug. Then we&lt;br /&gt;
will get:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets now an IP-Address on boot and is connected to VLAN 10.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
This works because of three conditions.&lt;br /&gt;
# ageing time is 0: ageing time specifies the number of seconds a MAC Address will be kept in the forwarding database after having a packet received from this MAC Address. Setting it to 0 means there is never a MAC Address stored in the FDB.&lt;br /&gt;
# unicast flood on interfaces is on: this controls whether the bridge should flood traffic for which an FDB entry is missing and the destination is unknown through this port. Defaults to on.&lt;br /&gt;
# spanning tree protocol (stp) is disabled: we don't have a forward_delay at startup for the learning phase of spanning tree.&lt;br /&gt;
I have a running and connected virtual machine:&lt;br /&gt;
 '''harley$''' sudo bridge vlan show&lt;br /&gt;
 port    vlan ids&lt;br /&gt;
 enp1s0   1 PVID Egress Untagged&lt;br /&gt;
 br0      1 PVID Egress Untagged&lt;br /&gt;
 vnet0    1 PVID Egress Untagged&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time&lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/forward_delay&lt;br /&gt;
 1500&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state&lt;br /&gt;
 0&lt;br /&gt;
Indeed we have forward_delay 1500 (means 15 sec) but it doesn't matter. stp_state is 0 (disabled), no spanning tree. Flood (means unicast flood) is on as I can see:&lt;br /&gt;
 '''harley$''' sudo bridge -d link show&lt;br /&gt;
 ''3: enp1s0'' state UP : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 4&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on &lt;br /&gt;
 ''95: vnet0'' state UNKNOWN : &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 master br0 state forwarding priority 32 cost 100&lt;br /&gt;
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let's have a look at flooding on the interfaces. I disable it on the physical interface enp1s0 of the bridge and reboot the guest:&lt;br /&gt;
 '''harley$''' sudo bridge link set dev enp1s0 flood off&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
The guest gets an IP-Address from the DHCP-Server but then can't ping its gateway. DHCP-REQUEST is broadcast and goes thru enp1s0. DHCP-ANSWER comes back thru it to any other (here only vnet0) interface which has flood on. Ping is unicast and isn't forwareded on enp1s0. If I set  enp1s0 flood on and vnet0 flood off and &amp;lt;code&amp;gt;'''deb9-test$ '''sudo systemctl restart systemd-networkd&amp;lt;/code&amp;gt;, I get no IP-Address from DHCP-Server and can't ping the interface. Incoming DHCP-ANSWER isn't broadcast and vnet0 doesn't forward it to the guest.&lt;br /&gt;
&lt;br /&gt;
Btw. this method has bad performance as we can see with monitor. We insert MAC-Addresses into FDB for just deleting it immediately, all for nothing.&lt;br /&gt;
 '''harley$''' sudo bridge monitor fdb&lt;br /&gt;
 52:54:00:01:76:20 dev enp1s0 master br0 &lt;br /&gt;
 52:54:00:b0:ca:63 dev vnet0 master br0 &lt;br /&gt;
 f4:f2:6d:2c:87:f7 dev enp1s0 master br0 &lt;br /&gt;
 00:80:3f:2a:31:1a dev enp1s0 master br0 &lt;br /&gt;
 Deleted 52:54:00:01:76:20 dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted 52:54:00:b0:ca:63 dev vnet0 master br0 stale&lt;br /&gt;
 Deleted 00:80:3f:2a:31:1a dev enp1s0 master br0 stale&lt;br /&gt;
 Deleted f4:f2:6d:2c:87:f7 dev enp1s0 master br0 stale&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.netdev.html&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.network.html&lt;br /&gt;
&lt;br /&gt;
== linux bridge with libvirt hook scripts ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.libvirt.org/hooks.html&lt;br /&gt;
* https://serverfault.com/questions/696011/libvirt-hook-qemu-suse12&lt;br /&gt;
&lt;br /&gt;
== Open vSwitch ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://libvirt.org/formatnetwork.html&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=14</id>
		<title>VLAN for virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=14"/>
				<updated>2017-09-22T22:05:29Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: describe linux bridge as hub&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
I wanted to update VLAN connections for virtual&lt;br /&gt;
machines to newer technologies and put a question on&lt;br /&gt;
[https://unix.stackexchange.com/questions/392758/setup-vlan-on-linux-bridge-for-virtual-machines-with-systemd?noredirect=1#comment700641_392758 unix.stackexchange]. But I do not get any answer. It seems there is very&lt;br /&gt;
little knowledge for this out there. So I decided to work on it by myself&lt;br /&gt;
and document it here.&lt;br /&gt;
&lt;br /&gt;
In gerneral I will look at four methods:&lt;br /&gt;
# [[#oldstyle linux bridge as hub|oldstyle linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge as hub|linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge with libvirt hook scripts|linux bridge with libvirt hook scripts]]&lt;br /&gt;
# [[#Open vSwitch|Open vSwitch]]&lt;br /&gt;
&lt;br /&gt;
== Preparation ==&lt;br /&gt;
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.&lt;br /&gt;
Now I start the virtual machine, login and show its interface setting:&lt;br /&gt;
 '''harley$''' virsh start --console deb9-test&lt;br /&gt;
login&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/08-vlan10.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 Kind=vlan&lt;br /&gt;
 [VLAN]&lt;br /&gt;
 Id=10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/12-vlan10_attach-to-if.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=ens2&lt;br /&gt;
 [Network]&lt;br /&gt;
 VLAN=vlan10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/16-vlan10_up.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 [Network]&lt;br /&gt;
 Address=192.168.10.57/24&lt;br /&gt;
 Gateway=192.168.10.1&lt;br /&gt;
To test if we have connection direct after startup I append this to .bashrc:&lt;br /&gt;
 '''deb9-test$''' echo ping -c3 192.168.10.1 &amp;gt;&amp;gt; .bashrc&lt;br /&gt;
Because I have to start the test virtual machine many times I setup autologin. It's no problem. There is nothing on the guest.&lt;br /&gt;
 '''deb9-test$''' grep ^ExecStart= /lib/systemd/system/serial-getty@.service&lt;br /&gt;
 ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
modify to&lt;br /&gt;
 ExecStart=-/sbin/agetty --autologin ''yourloginname'' --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
&lt;br /&gt;
== oldstyle linux bridge as hub ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Disable systemd-networkd and start networking with ifupdown:&lt;br /&gt;
 '''harley$''' sudo systemctl stop systemd-networkd&lt;br /&gt;
 Warning: Stopping systemd-networkd.service, but it can still be activated by:&lt;br /&gt;
   systemd-networkd.socket&lt;br /&gt;
 '''harley$''' sudo systemctl disable systemd-networkd&lt;br /&gt;
 Removed /etc/systemd/system/multi-user.target.wants/systemd-networkd.service.&lt;br /&gt;
 Removed /etc/systemd/system/sockets.target.wants/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install enable networking&lt;br /&gt;
 '''harley$''' sudo systemctl start networking.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/network/interfaces&lt;br /&gt;
 auto br0&lt;br /&gt;
 iface br0 inet manual&lt;br /&gt;
     bridge_ports enp1s0&lt;br /&gt;
     bridge_ageing 0&lt;br /&gt;
     bridge_stp off&lt;br /&gt;
 '''harley$''' sudo ifup br0&lt;br /&gt;
 Waiting for br0 to get ready (MAXWAIT is 32 seconds).&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
It's all in place now:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
Yes, there is no VLAN filtering, means VLAN on the bridge is disabled but the guest sees the VLAN-tagged packets.&lt;br /&gt;
To list all settings of the bridge you can use:&lt;br /&gt;
 harley$ find /sys/class/net/br0/bridge/ -type f -readable -printf '%f = ' -exec cat {} \; | sort&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://wiki.debian.org/NetworkConfiguration#Bridging_without_Switching&lt;br /&gt;
&lt;br /&gt;
== linux bridge as hub ==&lt;br /&gt;
Now I try to setup [[#oldstyle linux bridge as hub]] just with systemd-networkd.&lt;br /&gt;
&lt;br /&gt;
Disable networking with ifupdown and start systemd-networkd:&lt;br /&gt;
 '''harley$''' sudo systemctl stop networking.service&lt;br /&gt;
 '''harley$''' sudo systemctl disable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install disable networking&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable systemd-networkd&lt;br /&gt;
 Created symlink /etc/systemd/system/multi-user.target.wants/systemd-networkd.service → /lib/systemd/system/systemd-networkd.service.&lt;br /&gt;
 Created symlink /etc/systemd/system/sockets.target.wants/systemd-networkd.socket → /lib/systemd/system/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo systemctl start systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/08-br0.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 Kind=bridge&lt;br /&gt;
 [Bridge]&lt;br /&gt;
 AgeingTimeSec=0&lt;br /&gt;
 STP=false&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/12-br0_add-enp1s0.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=enp1s0&lt;br /&gt;
 [Network]&lt;br /&gt;
 Bridge=br0&lt;br /&gt;
 '''harley$''' cat /etc/systemd/network/16-br0_up.network &lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=br0&lt;br /&gt;
 '''harley$''' sudo systemctl restart systemd-networkd&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
But AgeingTimeSec=0 is not acepted:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 30000   (means 300 sec)&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.netdev.html&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.network.html&lt;br /&gt;
&lt;br /&gt;
== linux bridge with libvirt hook scripts ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.libvirt.org/hooks.html&lt;br /&gt;
* https://serverfault.com/questions/696011/libvirt-hook-qemu-suse12&lt;br /&gt;
&lt;br /&gt;
== Open vSwitch ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://libvirt.org/formatnetwork.html&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=13</id>
		<title>VLAN for virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=13"/>
				<updated>2017-09-22T14:13:39Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: describe oldstyle linux bridge as hub&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
I wanted to update VLAN connections for virtual&lt;br /&gt;
machines to newer technologies and put a question on&lt;br /&gt;
[https://unix.stackexchange.com/questions/392758/setup-vlan-on-linux-bridge-for-virtual-machines-with-systemd?noredirect=1#comment700641_392758 unix.stackexchange]. But I do not get any answer. It seems there is very&lt;br /&gt;
little knowledge for this out there. So I decided to work on it by myself&lt;br /&gt;
and document it here.&lt;br /&gt;
&lt;br /&gt;
In gerneral I will look at four methods:&lt;br /&gt;
# [[#oldstyle linux bridge as hub|oldstyle linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge as hub|linux bridge as hub]]&lt;br /&gt;
# [[#linux bridge with libvirt hook scripts|linux bridge with libvirt hook scripts]]&lt;br /&gt;
# [[#Open vSwitch|Open vSwitch]]&lt;br /&gt;
&lt;br /&gt;
== Preparation ==&lt;br /&gt;
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.&lt;br /&gt;
Now I start the virtual machine, login and show its interface setting:&lt;br /&gt;
 '''harley$''' virsh start --console deb9-test&lt;br /&gt;
login&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/08-vlan10.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 Kind=vlan&lt;br /&gt;
 [VLAN]&lt;br /&gt;
 Id=10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/12-vlan10_attach-to-if.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=ens2&lt;br /&gt;
 [Network]&lt;br /&gt;
 VLAN=vlan10&lt;br /&gt;
 '''deb9-test$''' cat /etc/systemd/network/16-vlan10_up.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 [Network]&lt;br /&gt;
 Address=192.168.10.57/24&lt;br /&gt;
 Gateway=192.168.10.1&lt;br /&gt;
To test if we have connection direct after startup I append this to .bashrc:&lt;br /&gt;
 '''deb9-test$''' echo ping -c3 192.168.10.1 &amp;gt;&amp;gt; .bashrc&lt;br /&gt;
Because I have to start the test virtual machine many times I setup autologin. It's no problem. There is nothing on the guest.&lt;br /&gt;
 '''deb9-test$''' grep ^ExecStart= /lib/systemd/system/serial-getty@.service&lt;br /&gt;
 ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
modify to&lt;br /&gt;
 ExecStart=-/sbin/agetty --autologin ''yourloginname'' --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
&lt;br /&gt;
== oldstyle linux bridge as hub ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Disable systemd-networkd and start networking with ifupdown:&lt;br /&gt;
 '''harley$''' sudo systemctl stop systemd-networkd&lt;br /&gt;
 Warning: Stopping systemd-networkd.service, but it can still be activated by:&lt;br /&gt;
   systemd-networkd.socket&lt;br /&gt;
 '''harley$''' sudo systemctl disable systemd-networkd&lt;br /&gt;
 Removed /etc/systemd/system/multi-user.target.wants/systemd-networkd.service.&lt;br /&gt;
 Removed /etc/systemd/system/sockets.target.wants/systemd-networkd.socket.&lt;br /&gt;
 '''harley$''' sudo ip link set dev br0 down &amp;amp;&amp;amp; sudo ip link del dev br0&lt;br /&gt;
 '''harley$''' sudo systemctl enable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install enable networking&lt;br /&gt;
 '''harley$''' sudo systemctl start networking.service&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
Setup the bridge and start it:&lt;br /&gt;
 '''harley$''' cat /etc/network/interfaces&lt;br /&gt;
 auto br0&lt;br /&gt;
 iface br0 inet manual&lt;br /&gt;
     bridge_ports enp1s0&lt;br /&gt;
     bridge_ageing 0&lt;br /&gt;
     bridge_stp off&lt;br /&gt;
 '''harley$''' sudo ifup br0&lt;br /&gt;
 Waiting for br0 to get ready (MAXWAIT is 32 seconds).&lt;br /&gt;
 '''harley$'''&lt;br /&gt;
It's all in place now:&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/ageing_time &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/stp_state &lt;br /&gt;
 0&lt;br /&gt;
 '''harley$''' cat /sys/class/net/br0/bridge/vlan_filtering &lt;br /&gt;
 0&lt;br /&gt;
Yes, there is no VLAN filtering, means VLAN on the bridge is disabled but the guest sees the VLAN-tagged packets.&lt;br /&gt;
To list all settings of the bridge you can use:&lt;br /&gt;
 harley$ find /sys/class/net/br0/bridge/ -type f -readable -printf '%f = ' -exec cat {} \; | sort&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://wiki.debian.org/NetworkConfiguration#Bridging_without_Switching&lt;br /&gt;
&lt;br /&gt;
== linux bridge as hub ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.netdev.html&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.network.html&lt;br /&gt;
&lt;br /&gt;
== linux bridge with libvirt hook scripts ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.libvirt.org/hooks.html&lt;br /&gt;
* https://serverfault.com/questions/696011/libvirt-hook-qemu-suse12&lt;br /&gt;
&lt;br /&gt;
== Open vSwitch ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://libvirt.org/formatnetwork.html&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=12</id>
		<title>VLAN for virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=12"/>
				<updated>2017-09-22T12:40:25Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: describe oldstyle linux bridge as hub&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
I wanted to update VLAN connections for virtual&lt;br /&gt;
machines to newer technologies and put a question on&lt;br /&gt;
[https://unix.stackexchange.com/questions/392758/setup-vlan-on-linux-bridge-for-virtual-machines-with-systemd?noredirect=1#comment700641_392758 unix.stackexchange]. But I do not get any answer. It seems there is very&lt;br /&gt;
little knowledge for this out there. So I decided to work on it by myself&lt;br /&gt;
and document it here.&lt;br /&gt;
&lt;br /&gt;
In gerneral I will look at four methods:&lt;br /&gt;
# [[#oldstyle linux bridge as a hub|oldstyle linux bridge as a hub]]&lt;br /&gt;
# [[#linux bridge as a hub|linux bridge as a hub]]&lt;br /&gt;
# [[#linux bridge with libvirt hook scripts|linux bridge with libvirt hook scripts]]&lt;br /&gt;
# [[#Open vSwitch|Open vSwitch]]&lt;br /&gt;
&lt;br /&gt;
== Preparation ==&lt;br /&gt;
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.&lt;br /&gt;
Now I start the virtual machine, login and show its interface setting:&lt;br /&gt;
 harley$ virsh start --console deb9-test&lt;br /&gt;
login&lt;br /&gt;
 deb9-test$ cat /etc/systemd/network/08-vlan10.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 Kind=vlan&lt;br /&gt;
 [VLAN]&lt;br /&gt;
 Id=10&lt;br /&gt;
 deb9-test$ cat /etc/systemd/network/12-vlan10_attach-to-if.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=ens2&lt;br /&gt;
 [Network]&lt;br /&gt;
 VLAN=vlan10&lt;br /&gt;
 deb9-test$ cat /etc/systemd/network/16-vlan10_up.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 [Network]&lt;br /&gt;
 Address=192.168.10.57/24&lt;br /&gt;
 Gateway=192.168.10.1&lt;br /&gt;
To test if we have connection direct after startup I append this to .bashrc:&lt;br /&gt;
 deb9-test$ echo ping -c3 192.168.10.1 &amp;gt;&amp;gt; .bashrc&lt;br /&gt;
Because I have to start the test virtual machine many times I setup autologin. It's no problem. There is nothing on the guest.&lt;br /&gt;
 deb9-test$ grep ^ExecStart= /lib/systemd/system/serial-getty@.service&lt;br /&gt;
 ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
modify to&lt;br /&gt;
 ExecStart=-/sbin/agetty --autologin ''yourloginname'' --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
&lt;br /&gt;
== oldstyle linux bridge as a hub ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Disable systemd-networkd and start networking with ifupdown:&lt;br /&gt;
 harley$ sudo systemctl stop systemd-networkd&lt;br /&gt;
 Warning: Stopping systemd-networkd.service, but it can still be activated by:&lt;br /&gt;
   systemd-networkd.socket&lt;br /&gt;
 harley$ sudo systemctl disable systemd-networkd&lt;br /&gt;
 Removed /etc/systemd/system/multi-user.target.wants/systemd-networkd.service.&lt;br /&gt;
 Removed /etc/systemd/system/sockets.target.wants/systemd-networkd.socket.&lt;br /&gt;
 harley$ sudo systemctl enable networking.service&lt;br /&gt;
 Synchronizing state of networking.service with SysV service script with /lib/systemd/systemd-sysv-install.&lt;br /&gt;
 Executing: /lib/systemd/systemd-sysv-install enable networking&lt;br /&gt;
 harley$ sudo systemctl start networking.service&lt;br /&gt;
 harley$&lt;br /&gt;
&lt;br /&gt;
== linux bridge as a hub ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.netdev.html&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.network.html&lt;br /&gt;
&lt;br /&gt;
== linux bridge with libvirt hook scripts ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.libvirt.org/hooks.html&lt;br /&gt;
* https://serverfault.com/questions/696011/libvirt-hook-qemu-suse12&lt;br /&gt;
&lt;br /&gt;
== Open vSwitch ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://libvirt.org/formatnetwork.html&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=11</id>
		<title>VLAN for virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=11"/>
				<updated>2017-09-22T12:17:35Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: describe Preparation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
I wanted to update VLAN connections for virtual&lt;br /&gt;
machines to newer technologies and put a question on&lt;br /&gt;
[https://unix.stackexchange.com/questions/392758/setup-vlan-on-linux-bridge-for-virtual-machines-with-systemd?noredirect=1#comment700641_392758 unix.stackexchange]. But I do not get any answer. It seems there is very&lt;br /&gt;
little knowledge for this out there. So I decided to work on it by myself&lt;br /&gt;
and document it here.&lt;br /&gt;
&lt;br /&gt;
In gerneral I will look at four methods:&lt;br /&gt;
# [[#oldstyle linux bridge as a hub|oldstyle linux bridge as a hub]]&lt;br /&gt;
# [[#linux bridge as a hub|linux bridge as a hub]]&lt;br /&gt;
# [[#linux bridge with libvirt hook scripts|linux bridge with libvirt hook scripts]]&lt;br /&gt;
# [[#Open vSwitch|Open vSwitch]]&lt;br /&gt;
&lt;br /&gt;
== Preparation ==&lt;br /&gt;
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.&lt;br /&gt;
Now I start the virtual machine, login and show its interface setting:&lt;br /&gt;
 harley$ virsh start --console deb9-test&lt;br /&gt;
login&lt;br /&gt;
 deb9-test$ cat /etc/systemd/network/08-vlan10.netdev&lt;br /&gt;
 [NetDev]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 Kind=vlan&lt;br /&gt;
 [VLAN]&lt;br /&gt;
 Id=10&lt;br /&gt;
 deb9-test$ cat /etc/systemd/network/12-vlan10_attach-to-if.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=ens2&lt;br /&gt;
 [Network]&lt;br /&gt;
 VLAN=vlan10&lt;br /&gt;
 deb9-test$ cat /etc/systemd/network/16-vlan10_up.network&lt;br /&gt;
 [Match]&lt;br /&gt;
 Name=vlan10&lt;br /&gt;
 [Network]&lt;br /&gt;
 Address=192.168.10.57/24&lt;br /&gt;
 Gateway=192.168.10.1&lt;br /&gt;
To test if we have connection direct after startup I append this to .bashrc:&lt;br /&gt;
 deb9-test$ echo ping -c3 192.168.10.1 &amp;gt;&amp;gt; .bashrc&lt;br /&gt;
Because I have to start the test virtual machine many times I setup autologin. It's no problem. There is nothing on the guest.&lt;br /&gt;
 deb9-test$ grep ^ExecStart= /lib/systemd/system/serial-getty@.service&lt;br /&gt;
 ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
modify to&lt;br /&gt;
 ExecStart=-/sbin/agetty --autologin ''yourloginname'' --keep-baud 115200,38400,9600 %I $TERM&lt;br /&gt;
&lt;br /&gt;
== oldstyle linux bridge as a hub ==&lt;br /&gt;
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&lt;br /&gt;
&lt;br /&gt;
== linux bridge as a hub ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.netdev.html&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.network.html&lt;br /&gt;
&lt;br /&gt;
== linux bridge with libvirt hook scripts ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.libvirt.org/hooks.html&lt;br /&gt;
* https://serverfault.com/questions/696011/libvirt-hook-qemu-suse12&lt;br /&gt;
&lt;br /&gt;
== Open vSwitch ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://libvirt.org/formatnetwork.html&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=10</id>
		<title>VLAN for virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=10"/>
				<updated>2017-09-21T22:56:34Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: add references&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
I wanted to update VLAN connections for virtual&lt;br /&gt;
machines to newer technologies and put a question on&lt;br /&gt;
[https://unix.stackexchange.com/questions/392758/setup-vlan-on-linux-bridge-for-virtual-machines-with-systemd?noredirect=1#comment700641_392758 unix.stackexchange]. But I do not get any answer. It seems there is very&lt;br /&gt;
little knowledge for this out there. So I decided to work on it by myself&lt;br /&gt;
and document it here.&lt;br /&gt;
&lt;br /&gt;
In gerneral I will look at three methods:&lt;br /&gt;
# [[#linux bridge as a hub|linux bridge as a hub]]&lt;br /&gt;
# [[#linux bridge with libvirt hook scripts|linux bridge with libvirt hook scripts]]&lt;br /&gt;
# [[#Open vSwitch|Open vSwitch]]&lt;br /&gt;
&lt;br /&gt;
== linux bridge as a hub ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/systemd.netdev.html&lt;br /&gt;
&lt;br /&gt;
== linux bridge with libvirt hook scripts ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.libvirt.org/hooks.html&lt;br /&gt;
* https://serverfault.com/questions/696011/libvirt-hook-qemu-suse12&lt;br /&gt;
&lt;br /&gt;
== Open vSwitch ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://libvirt.org/formatnetwork.html&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=9</id>
		<title>VLAN for virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=9"/>
				<updated>2017-09-21T19:55:15Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: add references&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
I wanted to update VLAN connections for virtual&lt;br /&gt;
machines to newer technologies and put a question on&lt;br /&gt;
[https://unix.stackexchange.com/questions/392758/setup-vlan-on-linux-bridge-for-virtual-machines-with-systemd?noredirect=1#comment700641_392758 unix.stackexchange]. But I do not get any answer. It seems there is very&lt;br /&gt;
little knowledge for this out there. So I decided to work on it by myself&lt;br /&gt;
and document it here.&lt;br /&gt;
&lt;br /&gt;
In gerneral I will look at three methods:&lt;br /&gt;
# [[#linux bridge as a hub|linux bridge as a hub]]&lt;br /&gt;
# [[#linux bridge with libvirt hook scripts|linux bridge with libvirt hook scripts]]&lt;br /&gt;
# [[#Open vSwitch|Open vSwitch]]&lt;br /&gt;
&lt;br /&gt;
== linux bridge as a hub ==&lt;br /&gt;
&lt;br /&gt;
== linux bridge with libvirt hook scripts ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.libvirt.org/hooks.html&lt;br /&gt;
* https://serverfault.com/questions/696011/libvirt-hook-qemu-suse12&lt;br /&gt;
&lt;br /&gt;
== Open vSwitch ==&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://libvirt.org/formatnetwork.html&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=8</id>
		<title>VLAN for virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=VLAN_for_virtual_machines&amp;diff=8"/>
				<updated>2017-09-20T23:30:26Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: create page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
I wanted to update VLAN connections for virtual&lt;br /&gt;
machines to newer technologies and put a question on&lt;br /&gt;
[https://unix.stackexchange.com/questions/392758/setup-vlan-on-linux-bridge-for-virtual-machines-with-systemd?noredirect=1#comment700641_392758 unix.stackexchange]. But I do not get any answer. It seems there is very&lt;br /&gt;
little knowledge for this out there. So I decided to work on it by myself&lt;br /&gt;
and document it here.&lt;br /&gt;
&lt;br /&gt;
In gerneral I will look at three methods:&lt;br /&gt;
# [[#linux bridge as a hub|linux bridge as a hub]]&lt;br /&gt;
# [[#linux bridge with libvirt hook scripts|linux bridge with libvirt hook scripts]]&lt;br /&gt;
# [[#Open vSwitch|Open vSwitch]]&lt;br /&gt;
&lt;br /&gt;
== linux bridge as a hub ==&lt;br /&gt;
== linux bridge with libvirt hook scripts ==&lt;br /&gt;
== Open vSwitch ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=Setup_VGAPassthrough&amp;diff=7</id>
		<title>Setup VGAPassthrough</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=Setup_VGAPassthrough&amp;diff=7"/>
				<updated>2017-09-20T10:46:45Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: create page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== HowTo Setup VGAPassthrough from scratch on Debian 9 (stretch) ==&lt;br /&gt;
Author: Ingo Höft, 2017-08-10&lt;br /&gt;
&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
You need a CPU with virtualization and IOMMU, two different graphic&lt;br /&gt;
cards, two keyboards and mice, one for the host, one for the guest. I&lt;br /&gt;
use one keyboard/mouse with an usb switch.&lt;br /&gt;
&lt;br /&gt;
Install a basic system for testing as described in&lt;br /&gt;
[[Setup_KVM_with_console]] but without Guest Setup.&lt;br /&gt;
&lt;br /&gt;
I have a simple older graphics card for the text console and NVIDIA for&lt;br /&gt;
the guest.&lt;br /&gt;
 ~$ lspci | grep VGA&lt;br /&gt;
 0f:00.0 VGA compatible controller: NVIDIA Corporation GF106GL [Quadro 2000] (rev a1)&lt;br /&gt;
 37:04.0 VGA compatible controller: Matrox Electronics Systems Ltd. MGA 1064SG [Mystique] (rev 03)&lt;br /&gt;
 ~$&lt;br /&gt;
The older NVIDIA Quadro 2000 does not support UEFI bios so we will&lt;br /&gt;
workaround using of debian package ovmf (UEFI firmware for virtual&lt;br /&gt;
machines). virt-install uses seabios by default. Next time I will look&lt;br /&gt;
for a newer graphics card supporting UEFI. If your graphics card support&lt;br /&gt;
UEFI you can look at [https://www.techpowerup.com/vgabios/ Video BIOS Collection]&lt;br /&gt;
or check with this [https://vfio.blogspot.de/2014/08/does-my-graphics-card-rom-support-efi.html rom-parser].&lt;br /&gt;
&lt;br /&gt;
=== Setup VGAPassthrough on host ===&lt;br /&gt;
It is important to blacklist the graphics card for the guest,&lt;br /&gt;
here NVIDIA, so the host will never see it. This should be done&lt;br /&gt;
first to avoid confusion. I had trouble. My linux box does not use&lt;br /&gt;
the right graphics card on boot and I could not see anything. The&lt;br /&gt;
nouveau driver is default for NVIDIA. For blacklisting I use kernel&lt;br /&gt;
parameter. On grub boot menu hit 'e' and append kernel parameter&lt;br /&gt;
'modprobe.blacklist=nouveau' (or what your driver is) and boot with F10.&lt;br /&gt;
&lt;br /&gt;
You should know what driver to blacklist before installing the second&lt;br /&gt;
graphics card. Maybe you can't examine it afterwards because of a black&lt;br /&gt;
screen. Use 'sudo lspci -v' to show what 'Kernel driver in use:' for the&lt;br /&gt;
video card to blacklist.&lt;br /&gt;
&lt;br /&gt;
After booting I set in /etc/default/grub for persistence&lt;br /&gt;
GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;intel_iommu=on modprobe.blacklist=nouveau&amp;quot;&lt;br /&gt;
Now I boot with the right graphics card for the console of the host.&lt;br /&gt;
&lt;br /&gt;
The intel_iommu=on is needed for Intel CPUs, amd_iommu=on for AMD CPUs.&lt;br /&gt;
Don't forget to run&lt;br /&gt;
 ~$ update-grub&lt;br /&gt;
Now we have to load the vfio-pci driver modules for VGAPassthrough.&lt;br /&gt;
They MUST load before any other video driver so the graphics card can't&lt;br /&gt;
be occupied bye other drivers. We do it very early in initram, so edit&lt;br /&gt;
/etc/initramfs-tools/modules like this:&lt;br /&gt;
 ~$ cat /etc/initramfs-tools/modules&lt;br /&gt;
 # List of modules that you want to include in your initramfs.&lt;br /&gt;
 # They will be loaded at boot time in the order below.&lt;br /&gt;
 #&lt;br /&gt;
 # Syntax:  module_name [args ...]&lt;br /&gt;
 #&lt;br /&gt;
 # You must run update-initramfs(8) to effect this change.&lt;br /&gt;
 #&lt;br /&gt;
 # the drivers for vfio must load early in THIS order!&lt;br /&gt;
 vfio&lt;br /&gt;
 vfio_iommu_type1&lt;br /&gt;
 vfio_pci&lt;br /&gt;
 vfio_virqfd&lt;br /&gt;
 ~$&lt;br /&gt;
&lt;br /&gt;
Now we have to append the physical graphics devices to the vfio-pci&lt;br /&gt;
driver. This is somewhat tricky. You cannot passthrough simple devices&lt;br /&gt;
but only complete IOMMU groups. For further information and finding the&lt;br /&gt;
IOMMU group look&lt;br /&gt;
[https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF#Setting_up_IOMMU here]:&lt;br /&gt;
&amp;quot;An IOMMU group is the smallest set of physical devices that can be&lt;br /&gt;
passed to a virtual machine&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Using the small bash script from there for my NVIDA card I found:&lt;br /&gt;
 IOMMU Group 14 0f:00.0 VGA compatible controller [0300]: NVIDIA Corporation GF106GL [Quadro 2000] [10de:0dd8] (rev a1)&lt;br /&gt;
 IOMMU Group 14 0f:00.1 Audio device [0403]: NVIDIA Corporation GF106 High Definition Audio Controller [10de:0be9] (rev a1)&lt;br /&gt;
There are two devices in Group 14: the VGA controller and its build in&lt;br /&gt;
audio device. That's evident.&lt;br /&gt;
&lt;br /&gt;
Now we can add the devices in the group to vfio-pci in&lt;br /&gt;
/etc/modprobe.d/vfio.conf like this:&lt;br /&gt;
 ~$ cat /etc/modprobe.d/vfio.conf&lt;br /&gt;
 options vfio-pci ids=10de:0dd8,10de:0be9&lt;br /&gt;
 options vfio-pci disable_vga=1&lt;br /&gt;
 ~$ sudo update-initramfs -u&lt;br /&gt;
You will find the device numbers from my example and I will not use VGA.&lt;br /&gt;
To get module parameters I use 'sudo modinfo vfio-pci'.&lt;br /&gt;
&lt;br /&gt;
Reboot.&lt;br /&gt;
&lt;br /&gt;
Now you should find the well set up vfio-pci driver like this:&lt;br /&gt;
 ~$ lspci -nnk -d 10de:0dd8&lt;br /&gt;
 0f:00.0 VGA compatible controller [0300]: NVIDIA Corporation GF106GL [Quadro 2000] [10de:0dd8] (rev a1)&lt;br /&gt;
         Subsystem: Hewlett-Packard Company GF106GL [Quadro 2000] [103c:084a]&lt;br /&gt;
         Kernel driver in use: vfio-pci&lt;br /&gt;
         Kernel modules: nouveau&lt;br /&gt;
 ~$ lspci -nnk -d 10de:0be9&lt;br /&gt;
 0f:00.1 Audio device [0403]: NVIDIA Corporation GF106 High Definition Audio Controller [10de:0be9] (rev a1)&lt;br /&gt;
         Subsystem: Hewlett-Packard Company GF106 High Definition Audio Controller [103c:084a]&lt;br /&gt;
         Kernel driver in use: vfio-pci&lt;br /&gt;
         Kernel modules: snd_hda_intel&lt;br /&gt;
 ~$&lt;br /&gt;
Inspecting 'sudo journalctl -k' is also a good thing.&lt;br /&gt;
&lt;br /&gt;
=== Install virtual machine ===&lt;br /&gt;
Now it's up to install a guest with all this:&lt;br /&gt;
 ~$ virsh net-start default&lt;br /&gt;
 ~$ virt-install --virt-type kvm \&lt;br /&gt;
                 --cpu host \&lt;br /&gt;
                 --features kvm_hidden=on \&lt;br /&gt;
                 --name harley \&lt;br /&gt;
                 --location https://ftp.de.debian.org/debian/dists/stretch/main/installer-amd64/ \&lt;br /&gt;
                 --os-variant debian9 \&lt;br /&gt;
                 --extra-args &amp;quot;console=ttyS0,115200&amp;quot; \&lt;br /&gt;
                 --noautoconsole \&lt;br /&gt;
                 --disk size=10 \&lt;br /&gt;
                 --memory 2048 \&lt;br /&gt;
                 --host-device 0f:00.0 \&lt;br /&gt;
                 --host-device 0f:00.1 \&lt;br /&gt;
 ;&lt;br /&gt;
{|cellspacing=&amp;quot;10&amp;quot;&lt;br /&gt;
| --cpu&amp;amp;nbsp;host&lt;br /&gt;
|Yes of course, we want hardware accelleration and this guest with its physical device binding runs only on this host.&lt;br /&gt;
|-&lt;br /&gt;
| --features&amp;amp;nbsp;kvm_hidden=on&lt;br /&gt;
|It was told, that Nvidia does not support running consumer-grade cards in VMs.&lt;br /&gt;
|-&lt;br /&gt;
| --noautoconsole&lt;br /&gt;
|virt-install returns from running guest installation, so you can easy connect with virsh. Autoconsole will not give you the guest installation screen.  '--graphics none' does not work in any way although we only use text mode in guest installation. I don't know why. Maybe it has something to do with the bound graphics devices.&lt;br /&gt;
|-&lt;br /&gt;
| --host-device&lt;br /&gt;
|Two times - this must be the IOMMU group with its two physical devices as described above.&lt;br /&gt;
|}&lt;br /&gt;
Connect to guest installation and install as usual&lt;br /&gt;
 ~$ virsh console harley&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
If you get many error messages from virt-install, try to use&lt;br /&gt;
temporary --cpu kvm64. This is more robust and may give less and more&lt;br /&gt;
understandable messages.&lt;br /&gt;
&lt;br /&gt;
On my machine virt-install canceled the installation with error&lt;br /&gt;
messages [1]. The reason was that the pc has a buggy bios and the kernel&lt;br /&gt;
disabled interrupt remapping (found with 'sudo journalctl -k') [2].&lt;br /&gt;
But IOMMU needs this and there is a way to force this feature with&lt;br /&gt;
iommu_unsave_interrupts like this:&lt;br /&gt;
 ~$ cat /etc/modprobe.d/iommu_unsafe_interrupts.conf&lt;br /&gt;
 options vfio_iommu_type1 allow_unsafe_interrupts=1&lt;br /&gt;
 ~$ sudo update-initramfs -u&lt;br /&gt;
Reboot.&lt;br /&gt;
&lt;br /&gt;
Of course this is also needed for machines does not support interrupt&lt;br /&gt;
remapping at all.&lt;br /&gt;
&lt;br /&gt;
=== Conclusion ===&lt;br /&gt;
I wanted to setup VGAPassthrough to do my work in an efficient way. I&lt;br /&gt;
saw it wasn't as simple as I thought so I decided to do it from scratch&lt;br /&gt;
step by step to learn how it works. After spending about a week I come&lt;br /&gt;
to this result: I'm able to start the vm and get a login prompt on the&lt;br /&gt;
screen attached to the passed through graphics card. It works. But when&lt;br /&gt;
I restart the vm I have no output on the screen. The guests graphics&lt;br /&gt;
card wasn't reset properly so I have to restart the host to get it for&lt;br /&gt;
one time again. For me that is a showstopper but it's a known problem&lt;br /&gt;
and can be fixed by using UEFI. My somewhat older NVIDIA Quadro 2000&lt;br /&gt;
doesn't support it. I have looked for nvidia-smi but test it not&lt;br /&gt;
yet. I should buy a newer graphics card with UEFI support.&lt;br /&gt;
&lt;br /&gt;
Next I wanted to login to the guest on it's login prompt but there is&lt;br /&gt;
no keybord and mouse support there. Seems that it should also passed&lt;br /&gt;
through but could only find generic hints in the many HowTos and manuals&lt;br /&gt;
like: &amp;quot;passthrough your keyboard and mouse to the vm, no problem&amp;quot;. I did&lt;br /&gt;
it and yes, it works. But I have an USB-switch for my keyboard/mouse to&lt;br /&gt;
switch between host and guest. One switch-port attached to an usb-port&lt;br /&gt;
for the host, one switch-port attached to an usb-port for the guest.&lt;br /&gt;
Booting the host with nothing connected to the guests usb-port and&lt;br /&gt;
starting the guest with keyboard/mouse connected to guests usb-port then&lt;br /&gt;
I get it to the login prompt. Seems to work but when I switch to the&lt;br /&gt;
screen of the host without switching the usb-switch back the host will&lt;br /&gt;
occupy the usb-port for the guest and I loose it for the vm. Seems that&lt;br /&gt;
I have to hide this port on the host. When looking around for a solution&lt;br /&gt;
I found this [5].&lt;br /&gt;
&lt;br /&gt;
That was the point I gave up. What will come up with sound? Do I&lt;br /&gt;
have passthrough everything? It seems there is no generic setup for&lt;br /&gt;
VGAPassthrough. I found many HowTows and Manuals but each only for a&lt;br /&gt;
special hardware. I'm not willing to investigate in development to this&lt;br /&gt;
and just make another HowTo for my machine. I have other projects.&lt;br /&gt;
Looking in a year what's going on.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://wiki.debian.org/VGAPassthrough&lt;br /&gt;
* https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF&lt;br /&gt;
* https://davidyat.es/2016/09/08/gpu-passthrough/&lt;br /&gt;
* https://forums.linuxmint.com/viewtopic.php?f=231&amp;amp;t=212692&lt;br /&gt;
* https://vfio.blogspot.de/&lt;br /&gt;
* https://www.redhat.com/archives/vfio-users/&lt;br /&gt;
* http://www.laketide.com/setting-up-gpu-passthrough-with-kvm-on-fedora/&lt;br /&gt;
* https://pve.proxmox.com/wiki/Pci_passthrough#IOMMU_interrupt_remapping&lt;br /&gt;
&lt;br /&gt;
=== Footnotes ===&lt;br /&gt;
 [1] ERROR internal error: qemu unexpectedly closed the monitor:&lt;br /&gt;
           warning: host doesn't support requested feature: CPUID.01H:EDX.ds [bit 21]&lt;br /&gt;
           warning: host doesn't support ...&lt;br /&gt;
 &lt;br /&gt;
 [2] Kernel message:&lt;br /&gt;
     &amp;quot;DMAR-IR: This system BIOS has enabled interrupt remapping on a&lt;br /&gt;
               chipset that contains an erratum making that feature&lt;br /&gt;
               unstable. To maintain system stability interrupt remapping&lt;br /&gt;
               is being disabled. Please contact your BIOS vendor for an&lt;br /&gt;
               update&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=Setup_KVM_with_console&amp;diff=6</id>
		<title>Setup KVM with console</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=Setup_KVM_with_console&amp;diff=6"/>
				<updated>2017-09-19T22:25:03Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== HowTo Setup KVM only with console on Debian 9 (strech) ==&lt;br /&gt;
Author: Ingo Höft, 2017-08-10&lt;br /&gt;
&lt;br /&gt;
I want to have a simple basic linux box with KVM but without graphics&lt;br /&gt;
and not needed components. So I avoid side effects on testing and&lt;br /&gt;
can increase its functionality step by step and use it as server&lt;br /&gt;
(host) for virtual machines only with command line administration as&lt;br /&gt;
usual for server. For this I always use 'apt install' with option&lt;br /&gt;
--no-install-recommends so I can decide what I realy need. I simplify&lt;br /&gt;
this as default for apt-get with:&lt;br /&gt;
 echo APT::Install-Recommends \&amp;quot;false\&amp;quot;\; &amp;gt; /etc/apt/apt.conf.d/99install-recommends&lt;br /&gt;
&lt;br /&gt;
You need a CPU with virtualization.&lt;br /&gt;
&lt;br /&gt;
I use LVM so I can easy try and error with installations and revert to a&lt;br /&gt;
clean tested snapshot. For reference here my most used commands:&lt;br /&gt;
 ~$ sudo lvcreate -n snap -s vmhost-vg/root -L 10G   #create snapshot&lt;br /&gt;
 ~$ sudo lvconvert --merge vmhost-vg/snap            #revert to snapshot&lt;br /&gt;
 ~$ sudo lvremove vmhost-vg/snap                     #commit installation&lt;br /&gt;
&lt;br /&gt;
=== Host Setup ===&lt;br /&gt;
Install a basic system from installation medium in textmode, e.g. from&lt;br /&gt;
CD-ROM or USB-Stick etc. without Desktop and any graphical environment.&lt;br /&gt;
That means on tasksel only select &amp;quot;standard system utilities&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
    [ ] Debian desktop environment&lt;br /&gt;
    [ ] ... GNOME&lt;br /&gt;
    [ ] ... Xfce&lt;br /&gt;
    [ ] ... KDE&lt;br /&gt;
    [ ] ... Cinnamon&lt;br /&gt;
    [ ] ... MATE&lt;br /&gt;
    [ ] ... LXDE&lt;br /&gt;
    [ ] web server&lt;br /&gt;
    [ ] print server&lt;br /&gt;
    [ ] SSH server&lt;br /&gt;
    [*] standard system utilities&lt;br /&gt;
&lt;br /&gt;
After this we have a simple running linux box with console and no&lt;br /&gt;
graphics.&lt;br /&gt;
&lt;br /&gt;
For my network I setup some additional features like uvesafb (if needed)&lt;br /&gt;
for better screen output, ssh, sssd, kerberos, nfs4. Install what you&lt;br /&gt;
need but no xserver-xorg.&lt;br /&gt;
&lt;br /&gt;
Install KVM:&lt;br /&gt;
 ~$ sudo apt --no-install-recommends install qemu-utils qemu-kvm \&lt;br /&gt;
             libvirt-clients dnsmasq-base ebtables libvirt-daemon-system \&lt;br /&gt;
             virtinst libosinfo-bin firewalld&lt;br /&gt;
&lt;br /&gt;
In particular this will prevent virtinst to install not needed&lt;br /&gt;
virt-viewer with big overhead for graphics vnc connection to client.&lt;br /&gt;
Check if you like with: (not needed, information only)&lt;br /&gt;
 ~$ apt --simulate install virt-viewer | less&lt;br /&gt;
&lt;br /&gt;
For system wide installations&lt;br /&gt;
 ~$ export LIBVIRT_DEFAULT_URI=qemu:///system&lt;br /&gt;
I put this in .bashrc.&lt;br /&gt;
&lt;br /&gt;
In order to be able to manage virtual machines as regular user, that&lt;br /&gt;
user needs to be added to some groups:&lt;br /&gt;
 ~$ sudo adduser &amp;lt;youruser&amp;gt; libvirt&lt;br /&gt;
 ~$ sudo adduser &amp;lt;youruser&amp;gt; libvirt-qemu&lt;br /&gt;
&lt;br /&gt;
=== Guest Setup ===&lt;br /&gt;
Now install your first simple guest debian9 (stretch) with console&lt;br /&gt;
setup.&lt;br /&gt;
&lt;br /&gt;
Before starting guest installation get rows and columns from your screen&lt;br /&gt;
on the host. We will need that later. And start the default network if its not running.&lt;br /&gt;
 ~$ stty --all&lt;br /&gt;
 speed 38400 baud; rows 64; columns 160; line = 0; (example)&lt;br /&gt;
 ...&lt;br /&gt;
 ~$&lt;br /&gt;
 ~$ virsh net-start default&lt;br /&gt;
 ( may also use&lt;br /&gt;
 ~$ virsh net-autostart default )&lt;br /&gt;
Install the guest:&lt;br /&gt;
 ~$ virt-install --virt-type kvm \&lt;br /&gt;
                 --cpu kvm64 \&lt;br /&gt;
                 --name base \&lt;br /&gt;
                 --location https://ftp.de.debian.org/debian/dists/stretch/main/installer-amd64/ \&lt;br /&gt;
                 --os-variant debian9 \&lt;br /&gt;
                 --extra-args &amp;quot;console=ttyS0&amp;quot; \&lt;br /&gt;
                 --graphics none \&lt;br /&gt;
                 --disk size=4 \&lt;br /&gt;
                 --memory 512 \&lt;br /&gt;
 ;&lt;br /&gt;
You may use '--cpu host' for better performance, but may cause issues if&lt;br /&gt;
migrating the guest to a host without an identical CPU. Show supported&lt;br /&gt;
CPU models with:&lt;br /&gt;
 ~$ virsh cpu-models x86_64&lt;br /&gt;
&lt;br /&gt;
The installation program of the guest should come up in text mode now&lt;br /&gt;
and you can complete installation on the guest as usual. I also install&lt;br /&gt;
only 'standard system utilities' for testing. On reboot on grub boot&lt;br /&gt;
menu hit 'e', append kernel parameter 'console=ttyS0' and boot&lt;br /&gt;
with F10.&lt;br /&gt;
&lt;br /&gt;
Login to guest and first set&lt;br /&gt;
 ~$ stty rows 64 columns 160 (or what yours is)&lt;br /&gt;
 ~$&lt;br /&gt;
&lt;br /&gt;
Then next set /etc/default/grub to&lt;br /&gt;
 GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet console=ttyS0&amp;quot;&lt;br /&gt;
Don't forget update-grub.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
* https://www.debian.org/distrib/&lt;br /&gt;
* https://wiki.debian.org/KVM&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=Kategorie:Virtualization&amp;diff=5</id>
		<title>Kategorie:Virtualization</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=Kategorie:Virtualization&amp;diff=5"/>
				<updated>2017-09-19T22:24:32Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: create category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Everything to Virtualization technology&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=Hauptseite&amp;diff=3</id>
		<title>Hauptseite</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=Hauptseite&amp;diff=3"/>
				<updated>2017-09-19T21:35:58Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: Redirect to Categories&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Spezial:Kategorien]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	<entry>
		<id>http://wiki.hoeft-online.de/index.php?title=Hauptseite&amp;diff=2</id>
		<title>Hauptseite</title>
		<link rel="alternate" type="text/html" href="http://wiki.hoeft-online.de/index.php?title=Hauptseite&amp;diff=2"/>
				<updated>2017-09-19T21:12:59Z</updated>
		
		<summary type="html">&lt;p&gt;Ingo: redirect to main page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[main page]]&lt;/div&gt;</summary>
		<author><name>Ingo</name></author>	</entry>

	</feed>