commit ca4cb04946136b730b4de19d4cbbe6515967e1ea
Author: Jiri Prochazka <jprochaz(a)redhat.com>
Date: Sun Nov 23 21:05:02 2014 +0100
Phase 1 regression tests + quick guides examples
* Added phase 1 regression tests.
+ Each test has its own .README file describing topology,
test scenario and other useful info
+ Some tests do not work well with NetworkManager or/and
with older distros
+ Test virtual_bridge_2_vlans_over_round_robin is currently
broken for unknown reason
* Added quick guides examples
+ Added some examples from wiki pages
Signed-off-by: Jiri Prochazka <jprochaz(a)redhat.com>
Signed-off-by: Jiri Pirko <jiri(a)resnulli.us>
recipes/examples/quick_guides/bonding.xml | 40 +++++
recipes/examples/quick_guides/iperf.xml | 43 ++++++
recipes/examples/quick_guides/netperf.xml | 39 +++++
recipes/examples/quick_guides/vlan.xml | 49 +++++++
recipes/regression_tests/phase1/3_vlans.README | 45 ++++++
recipes/regression_tests/phase1/3_vlans.py | 86 +++++++++++
recipes/regression_tests/phase1/3_vlans.xml | 82 +++++++++++
.../phase1/3_vlans_over_active_backup.README | 54 +++++++
.../phase1/3_vlans_over_active_backup.xml | 96 ++++++++++++
.../phase1/3_vlans_over_round_robin.README | 54 +++++++
.../phase1/3_vlans_over_round_robin.xml | 96 ++++++++++++
.../regression_tests/phase1/active_backup.README | 51 +++++++
recipes/regression_tests/phase1/active_backup.xml | 34 +++++
.../phase1/active_backup_double_bond.README | 51 +++++++
.../phase1/active_backup_double_bond.xml | 44 ++++++
recipes/regression_tests/phase1/bonding_test.py | 110 ++++++++++++++
recipes/regression_tests/phase1/ping_flood.README | 38 +++++
recipes/regression_tests/phase1/ping_flood.xml | 23 +++
recipes/regression_tests/phase1/round_robin.README | 51 +++++++
recipes/regression_tests/phase1/round_robin.xml | 34 +++++
.../phase1/round_robin_double_bond.README | 51 +++++++
.../phase1/round_robin_double_bond.xml | 44 ++++++
recipes/regression_tests/phase1/simple_ping.py | 19 +++
...irtual_bridge_2_vlans_over_active_backup.README | 76 ++++++++++
.../virtual_bridge_2_vlans_over_active_backup.xml | 153 ++++++++++++++++++++
.../phase1/virtual_bridge_2_vlans_over_bond.py | 99 +++++++++++++
.../virtual_bridge_2_vlans_over_round_robin.README | 76 ++++++++++
.../virtual_bridge_2_vlans_over_round_robin.xml | 153 ++++++++++++++++++++
.../phase1/virtual_bridge_vlan_in_guest.README | 52 +++++++
.../phase1/virtual_bridge_vlan_in_guest.py | 65 +++++++++
.../phase1/virtual_bridge_vlan_in_guest.xml | 53 +++++++
.../phase1/virtual_bridge_vlan_in_host.README | 52 +++++++
.../phase1/virtual_bridge_vlan_in_host.py | 66 +++++++++
.../phase1/virtual_bridge_vlan_in_host.xml | 54 +++++++
34 files changed, 2133 insertions(+), 0 deletions(-)
---
diff --git a/recipes/examples/quick_guides/bonding.xml b/recipes/examples/quick_guides/bonding.xml
new file mode 100644
index 0000000..8934403
--- /dev/null
+++ b/recipes/examples/quick_guides/bonding.xml
@@ -0,0 +1,40 @@
+<lnstrecipe>
+ <network>
+ <host id="testmachine1">
+ <interfaces>
+ <eth label="test_net" id="test_if1"/>
+ <eth label="test_net" id="test_if2"/>
+ <bond id="test_bond">
+ <options>
+ <option name="mode" value="balance-rr"/>
+ <option name="miimon" value="100"/>
+ </options>
+ <slaves>
+ <slave id="test_if1"/>
+ <slave id="test_if2"/>
+ </slaves>
+ <addresses>
+ <address value="192.168.200.1/24"/>
+ </addresses>
+ </bond>
+ </interfaces>
+ </host>
+ <host id="testmachine2">
+ <interfaces>
+ <eth id="test_if3" label="test_net">
+ <addresses>
+ <address value="192.168.200.2/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+ <task>
+ <run module="IcmpPing" host="testmachine1">
+ <options>
+ <option name="addr" value="{ip(testmachine2, test_if3)}"/>
+ <option name="count" value="5"/>
+ </options>
+ </run>
+ </task>
+</lnstrecipe>
diff --git a/recipes/examples/quick_guides/iperf.xml b/recipes/examples/quick_guides/iperf.xml
new file mode 100644
index 0000000..721b3bb
--- /dev/null
+++ b/recipes/examples/quick_guides/iperf.xml
@@ -0,0 +1,43 @@
+<lnstrecipe>
+ <network>
+ <host id="testmachine1">
+ <interfaces>
+ <eth label="tnet" id="testifc1">
+ <addresses>
+ <address value="192.168.200.2/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+
+ <host id="testmachine2">
+ <interfaces>
+ <eth label="tnet" id="testifc2">
+ <addresses>
+ <address value="192.168.200.3/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+
+
+ <task>
+ <run module="Iperf" host="testmachine2" bg_id="server">
+ <options>
+ <option name="role" value="server"/>
+ <option name="bind" value="{ip(testmachine2, testifc2)}"/>
+ <option name="duration" value="15"/>
+ </options>
+ </run>
+ <run module="Iperf" host="testmachine1">
+ <options>
+ <option name="role" value="client"/>
+ <option name="iperf_server" value="{ip(testmachine2, testifc2)}"/>
+ <option name="duration" value="1"/>
+ <option name="threshold" value="155 Tbits/sec"/>
+ </options>
+ </run>
+ <kill host="testmachine2" bg_id="server"/>
+ </task>
+</lnstrecipe>
diff --git a/recipes/examples/quick_guides/netperf.xml b/recipes/examples/quick_guides/netperf.xml
new file mode 100644
index 0000000..dd339a5
--- /dev/null
+++ b/recipes/examples/quick_guides/netperf.xml
@@ -0,0 +1,39 @@
+<lnstrecipe>
+ <network>
+ <host id="testmachine1">
+ <interfaces>
+ <eth label="tnet" id="testifc1">
+ <addresses>
+ <address value="192.168.200.2/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ <host id="testmachine2">
+ <interfaces>
+ <eth label="tnet" id="testifc2">
+ <addresses>
+ <address value="192.168.200.3/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+ <task>
+ <run module="Netperf" host="testmachine2" bg_id="server">
+ <options>
+ <option name="role" value="server"/>
+ <option name="bind" value="{ip(testmachine2, testifc2)}"/>
+ </options>
+ </run>
+ <run module="Netperf" host="testmachine1">
+ <options>
+ <option name="role" value="client"/>
+ <option name="netperf_server" value="{ip(testmachine2, testifc2)}"/>
+ </options>
+ </run>
+
+ <kill host="testmachine2" bg_id="server"/>
+
+ </task>
+</lnstrecipe>
diff --git a/recipes/examples/quick_guides/vlan.xml b/recipes/examples/quick_guides/vlan.xml
new file mode 100644
index 0000000..a7af769
--- /dev/null
+++ b/recipes/examples/quick_guides/vlan.xml
@@ -0,0 +1,49 @@
+<lnstrecipe>
+ <network>
+
+ <host id="testmachine1">
+ <interfaces>
+ <eth id="1" label="tnet"/>
+ <vlan id="testifc1">
+ <options>
+ <option name="vlan_tci" value="10"/>
+ </options>
+ <slaves>
+ <slave id="1"/>
+ </slaves>
+ <addresses>
+ <address value="192.168.200.2/24"/>
+ </addresses>
+ </vlan>
+ </interfaces>
+ </host>
+
+ <host id="testmachine2">
+ <interfaces>
+ <eth id="1" label="tnet"/>
+ <vlan id="testifc2">
+ <options>
+ <option name="vlan_tci" value="10"/>
+ </options>
+ <slaves>
+ <slave id="1"/>
+ </slaves>
+ <addresses>
+ <address value="192.168.200.3/24"/>
+ </addresses>
+ </vlan>
+ </interfaces>
+ </host>
+
+ </network>
+
+ <task>
+ <run module="IcmpPing" host="testmachine1">
+ <options>
+ <option name="addr" value="{ip(testmachine2,testifc2)}"/>
+ <option name="count" value="3"/>
+ </options>
+ </run>
+ </task>
+
+</lnstrecipe>
diff --git a/recipes/regression_tests/phase1/3_vlans.README b/recipes/regression_tests/phase1/3_vlans.README
new file mode 100644
index 0000000..54037a5
--- /dev/null
+++ b/recipes/regression_tests/phase1/3_vlans.README
@@ -0,0 +1,45 @@
+Topology:
+
+ switch
+ VLAN10 +------+ VLAN10
+ +-------------------+ | | +-------------------+
+ | VLAN20 | | | | VLAN20 |
+ | +-------------------+ +-------------------+ |
+ | | VLAN30 | | | | VLAN30 | |
+ | | +-----------+ | | +-----------+ | |
+ | | | +------+ | | |
+ | | | | | |
+ +-------+ +-------+
+ | |
+ +--+--+ +--+--+
++----| eth |----+ +----| eth |----+
+| +-----+ | | +-----+ |
+| | | |
+| | | |
+| host1 | | host2 |
+| | | |
+| | | |
+| | | |
++---------------+ +---------------+
+
+
+Number of hosts: 2
+Host #1 description:
+ One ethernet device with 3 VLAN subinterfaces
+Host #2 description:
+ One ethernet device with 3 VLAN subinterfaces
+Test name:
+ 3_vlans.py
+Test description (3_vlans.py):
+ Ping:
+ + count: 100
+ + interval: 0.1s
+ + between interfaces in the same VLAN (these should pass)
+ + between interfaces in different VLANs (these should fail)
+ Netperf:
+ + duration: 60s
+ + TCP_STREAM and UDP_STREAM
+ + between interfaces in the same VLAN
+ Offloads:
+ + TSO, GRO, GSO
+ + tested both on/off variants
diff --git a/recipes/regression_tests/phase1/3_vlans.py b/recipes/regression_tests/phase1/3_vlans.py
new file mode 100644
index 0000000..4681d8a
--- /dev/null
+++ b/recipes/regression_tests/phase1/3_vlans.py
@@ -0,0 +1,86 @@
+from lnst.Controller.Task import ctl
+
+# ------
+# SETUP
+# ------
+
+m1 = ctl.get_host("testmachine1")
+m2 = ctl.get_host("testmachine2")
+
+m1.sync_resources(modules=["IcmpPing", "Netperf"])
+m2.sync_resources(modules=["IcmpPing", "Netperf"])
+
+# ------
+# TESTS
+# ------
+
+vlans = ["vlan10", "vlan20", "vlan30"]
+offloads = ["gso", "gro", "tso"]
+
+for vlan1 in vlans:
+ for vlan2 in vlans:
+ ping_mod = ctl.get_module("IcmpPing",
+ options={
+ "addr" : m2.get_ip(vlan2),
+ "count" : 100,
+ "iface" : m1.get_devname(vlan1),
+ "interval" : 0.1
+ })
+ netperf_srv = ctl.get_module("Netperf",
+ options={
+ "role" : "server",
+ "bind" : m1.get_ip(vlan1),
+ })
+ netperf_cli_tcp = ctl.get_module("Netperf",
+ options={
+ "role" : "client",
+ "netperf_server" :
+ m1.get_ip(vlan1),
+ "duration" : 60,
+ "testname" : "TCP_STREAM",
+ "netperf_opts" :
+ "-L %s" % m2.get_ip(vlan1)
+ })
+ netperf_cli_udp = ctl.get_module("Netperf",
+ options={
+ "role" : "client",
+ "netperf_server" :
+ m1.get_ip(vlan1),
+ "duration" : 60,
+ "testname" : "UDP_STREAM",
+ "netperf_opts" :
+ "-L %s" % m2.get_ip(vlan1)
+ })
+ for offload in offloads:
+ # These tests should pass
+ # Ping between same VLANs
+ if vlan1 == vlan2:
+ for state in ["on", "off"]:
+ # Offload setup
+ m1.run("ethtool -K %s %s %s" % (m1.get_devname("eth1"),
+ offload, state))
+ m2.run("ethtool -K %s %s %s" % (m2.get_devname("eth1"),
+ offload, state))
+
+ # Ping test
+ m1.run(ping_mod)
+
+ # Netperf test (both TCP and UDP)
+ srv_proc = m1.run(netperf_srv, bg=True)
+ ctl.wait(2)
+ m2.run(netperf_cli_tcp, timeout=65)
+ m2.run(netperf_cli_udp, timeout=65)
+ srv_proc.intr()
+
+ # These tests should fail
+ # Ping across different VLAN
+ elif vlan1 != vlan2:
+ for state in ["on", "off"]:
+ # Offload setup
+ m1.run("ethtool -K %s %s %s" % (m1.get_devname("eth1"),
+ offload, state))
+ m2.run("ethtool -K %s %s %s" % (m2.get_devname("eth1"),
+ offload, state))
+
+ # Ping test
+ m1.run(ping_mod, expect="fail")
diff --git a/recipes/regression_tests/phase1/3_vlans.xml b/recipes/regression_tests/phase1/3_vlans.xml
new file mode 100644
index 0000000..faa5045
--- /dev/null
+++ b/recipes/regression_tests/phase1/3_vlans.xml
@@ -0,0 +1,82 @@
+<lnstrecipe>
+ <network>
+ <host id="testmachine1">
+ <interfaces>
+ <eth id="eth1" label="tnet" />
+ <vlan id="vlan10">
+ <options>
+ <option name="vlan_tci" value="10" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ </slaves>
+ <addresses>
+ <address value="192.168.10.1/24" />
+ </addresses>
+ </vlan>
+ <vlan id="vlan20">
+ <options>
+ <option name="vlan_tci" value="20" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ </slaves>
+ <addresses>
+ <address value="192.168.20.1/24" />
+ </addresses>
+ </vlan>
+ <vlan id="vlan30">
+ <options>
+ <option name="vlan_tci" value="30" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ </slaves>
+ <addresses>
+ <address value="192.168.30.1/24" />
+ </addresses>
+ </vlan>
+ </interfaces>
+ </host>
+ <host id="testmachine2">
+ <interfaces>
+ <eth id="eth1" label="tnet" />
+ <vlan id="vlan10">
+ <options>
+ <option name="vlan_tci" value="10" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ </slaves>
+ <addresses>
+ <address value="192.168.10.2/24" />
+ </addresses>
+ </vlan>
+ <vlan id="vlan20">
+ <options>
+ <option name="vlan_tci" value="20" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ </slaves>
+ <addresses>
+ <address value="192.168.20.2/24" />
+ </addresses>
+ </vlan>
+ <vlan id="vlan30">
+ <options>
+ <option name="vlan_tci" value="30" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ </slaves>
+ <addresses>
+ <address value="192.168.30.2/24" />
+ </addresses>
+ </vlan>
+ </interfaces>
+ </host>
+ </network>
+
+ <task python="3_vlans.py" />
+</lnstrecipe>
diff --git a/recipes/regression_tests/phase1/3_vlans_over_active_backup.README b/recipes/regression_tests/phase1/3_vlans_over_active_backup.README
new file mode 100644
index 0000000..e20fcb0
--- /dev/null
+++ b/recipes/regression_tests/phase1/3_vlans_over_active_backup.README
@@ -0,0 +1,54 @@
+Topology:
+
+ switch
+ VLAN10 +------+ VLAN10
+ +-------------------+ | | +-------------------+
+ | VLAN20 | | | | VLAN20 |
+ | +-------------------+ +-------------------+ |
+ | | VLAN30 | | | | VLAN30 | |
+ | | +-----------+ | | +-----------+ | |
+ | | | +------+ | | |
+ | | | | | |
+ +-------+ +-------+
+ | |
+ | |
+ | |
+ +----+---+ +----+---+
+ | BOND | | BOND |
+ +---++---+ +---++---+
+ || ||
+ +--++--+ +--++--+
+ | | | |
+ +--+-+ +-+--+ +--+-+ +-+--+
++---|eth1|--|eth2|---+ +---|eth1|--|eth2|---+
+| +----+ +----+ | | +----+ +----+ |
+| | | |
+| | | |
+| host1 | | host2 |
+| | | |
+| | | |
+| | | |
++--------------------+ +--------------------+
+
+Number of hosts: 2
+Host #1 description:
+ Two ethernet devices, in active-backup bond mode
+ 3 VLANs on bond interface
+Host #2 description:
+ Two ethernet devices, in active-backup bond mode
+ 3 VLANs on bond interface
+Test name:
+ 3_vlans.py
+Test description:
+ Ping:
+ + count: 100
+ + interval: 0.1s
+ + between interfaces in the same VLAN (these should pass)
+ + between interfaces in different VLANs (these should fail)
+ Netperf:
+ + duration: 60s
+ + TCP_STREAM and UDP_STREAM
+ + between interfaces in the same VLAN
+ Offloads:
+ + TSO, GRO, GSO
+ + tested both on/off variants
diff --git a/recipes/regression_tests/phase1/3_vlans_over_active_backup.xml b/recipes/regression_tests/phase1/3_vlans_over_active_backup.xml
new file mode 100644
index 0000000..705e77c
--- /dev/null
+++ b/recipes/regression_tests/phase1/3_vlans_over_active_backup.xml
@@ -0,0 +1,96 @@
+<lnstrecipe>
+ <network>
+ <host id="testmachine1">
+ <interfaces>
+ <eth id="eth1" label="tnet" />
+ <eth id="eth2" label="tnet" />
+ <bond id="test_bond">
+ <options>
+ <option name="mode" value="active-backup" />
+ <option name="miimon" value="100" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ <slave id="eth2" />
+ </slaves>
+ <addresses>
+ <address value="1.2.3.4/24" />
+ </addresses>
+ </bond>
+ <vlan id="vlan10">
+ <options>
+ <option name="vlan_tci" value="10" />
+ </options>
+ <slaves>
+ <slave id="test_bond" />
+ </slaves>
+ <addresses>
+ <address value="192.168.10.1/24" />
+ </addresses>
+ </vlan>
+ <vlan id="vlan20">
+ <options>
+ <option name="vlan_tci" value="20" />
+ </options>
+ <slaves>
+ <slave id="test_bond" />
+ </slaves>
+ <addresses>
+ <address value="192.168.20.1/24" />
+ </addresses>
+ </vlan>
+ <vlan id="vlan30">
+ <options>
+ <option name="vlan_tci" value="30" />
+ </options>
+ <slaves>
+ <slave id="test_bond" />
+ </slaves>
+ <addresses>
+ <address value="192.168.30.1/24" />
+ </addresses>
+ </vlan>
+ </interfaces>
+ </host>
+ <host id="testmachine2">
+ <interfaces>
+ <eth id="eth1" label="tnet" />
+ <vlan id="vlan10">
+ <options>
+ <option name="vlan_tci" value="10" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ </slaves>
+ <addresses>
+ <address value="192.168.10.2/24" />
+ </addresses>
+ </vlan>
+ <vlan id="vlan20">
+ <options>
+ <option name="vlan_tci" value="20" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ </slaves>
+ <addresses>
+ <address value="192.168.20.2/24" />
+ </addresses>
+ </vlan>
+ <vlan id="vlan30">
+ <options>
+ <option name="vlan_tci" value="30" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ </slaves>
+ <addresses>
+ <address value="192.168.30.2/24" />
+ </addresses>
+ </vlan>
+ </interfaces>
+ </host>
+ </network>
+
+ <task python="3_vlans.py" />
+</lnstrecipe>
diff --git a/recipes/regression_tests/phase1/3_vlans_over_round_robin.README b/recipes/regression_tests/phase1/3_vlans_over_round_robin.README
new file mode 100644
index 0000000..dbf53eb
--- /dev/null
+++ b/recipes/regression_tests/phase1/3_vlans_over_round_robin.README
@@ -0,0 +1,54 @@
+Topology:
+
+ switch
+ VLAN10 +------+ VLAN10
+ +-------------------+ | | +-------------------+
+ | VLAN20 | | | | VLAN20 |
+ | +-------------------+ +-------------------+ |
+ | | VLAN30 | | | | VLAN30 | |
+ | | +-----------+ | | +-----------+ | |
+ | | | +------+ | | |
+ | | | | | |
+ +-------+ +-------+
+ | |
+ | |
+ | |
+ +----+---+ +----+---+
+ | BOND | | BOND |
+ +---++---+ +---++---+
+ || ||
+ +--++--+ +--++--+
+ | | | |
+ +--+-+ +-+--+ +--+-+ +-+--+
++---|eth1|--|eth2|---+ +---|eth1|--|eth2|---+
+| +----+ +----+ | | +----+ +----+ |
+| | | |
+| | | |
+| host1 | | host2 |
+| | | |
+| | | |
+| | | |
++--------------------+ +--------------------+
+
+Number of hosts: 2
+Host #1 decsription:
+ Two ethernet devices, in round-robin bond mode
+ 3 VLANs on bond interface
+Host #2 description:
+ Two ethernet devices, in round-robin bond mode
+ 3 VLANs on bond interface
+Test name:
+ 3_vlans.py
+Test description:
+ Ping:
+ + count: 100
+ + interval: 0.1s
+ + between interfaces in the same VLAN (these should pass)
+ + between interfaces in different VLANs (these should fail)
+ Netperf:
+ + duration: 60s
+ + TCP_STREAM and UDP_STREAM
+ + between interfaces in the same VLAN
+ Offloads:
+ + TSO, GRO, GSO
+ + tested both on/off variants
diff --git a/recipes/regression_tests/phase1/3_vlans_over_round_robin.xml b/recipes/regression_tests/phase1/3_vlans_over_round_robin.xml
new file mode 100644
index 0000000..89f01c6
--- /dev/null
+++ b/recipes/regression_tests/phase1/3_vlans_over_round_robin.xml
@@ -0,0 +1,96 @@
+<lnstrecipe>
+ <network>
+ <host id="testmachine1">
+ <interfaces>
+ <eth id="eth1" label="tnet" />
+ <eth id="eth2" label="tnet" />
+ <bond id="test_bond">
+ <options>
+ <option name="mode" value="balance-rr" />
+ <option name="miimon" value="100" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ <slave id="eth2" />
+ </slaves>
+ <addresses>
+ <address value="1.2.3.4/24" />
+ </addresses>
+ </bond>
+ <vlan id="vlan10">
+ <options>
+ <option name="vlan_tci" value="10" />
+ </options>
+ <slaves>
+ <slave id="test_bond" />
+ </slaves>
+ <addresses>
+ <address value="192.168.10.1/24" />
+ </addresses>
+ </vlan>
+ <vlan id="vlan20">
+ <options>
+ <option name="vlan_tci" value="20" />
+ </options>
+ <slaves>
+ <slave id="test_bond" />
+ </slaves>
+ <addresses>
+ <address value="192.168.20.1/24" />
+ </addresses>
+ </vlan>
+ <vlan id="vlan30">
+ <options>
+ <option name="vlan_tci" value="30" />
+ </options>
+ <slaves>
+ <slave id="test_bond" />
+ </slaves>
+ <addresses>
+ <address value="192.168.30.1/24" />
+ </addresses>
+ </vlan>
+ </interfaces>
+ </host>
+ <host id="testmachine2">
+ <interfaces>
+ <eth id="eth1" label="tnet" />
+ <vlan id="vlan10">
+ <options>
+ <option name="vlan_tci" value="10" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ </slaves>
+ <addresses>
+ <address value="192.168.10.2/24" />
+ </addresses>
+ </vlan>
+ <vlan id="vlan20">
+ <options>
+ <option name="vlan_tci" value="20" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ </slaves>
+ <addresses>
+ <address value="192.168.20.2/24" />
+ </addresses>
+ </vlan>
+ <vlan id="vlan30">
+ <options>
+ <option name="vlan_tci" value="30" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ </slaves>
+ <addresses>
+ <address value="192.168.30.2/24" />
+ </addresses>
+ </vlan>
+ </interfaces>
+ </host>
+ </network>
+
+ <task python="3_vlans.py" />
+</lnstrecipe>
diff --git a/recipes/regression_tests/phase1/active_backup.README b/recipes/regression_tests/phase1/active_backup.README
new file mode 100644
index 0000000..8980098
--- /dev/null
+++ b/recipes/regression_tests/phase1/active_backup.README
@@ -0,0 +1,51 @@
+Topology:
+
+ switch
+ +------+
+ | |
+ | |
+ +-------------------+ +------------------+
+ | | | |
+ | | | |
+ | +------+ |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----+---+ |
+ | BOND | |
+ +---++---+ |
+ || |
+ +--++--+ |
+ | | |
+ +--+-+ +-+--+ +-+--+
++---|eth1|--|eth2|---+ +-------|eth1|------+
+| +----+ +----+ | | +----+ |
+| | | |
+| | | |
+| host1 | | host2 |
+| | | |
+| | | |
+| | | |
++--------------------+ +-------------------+
+
+Number of hosts: 2
+Host #1 description:
+ Two ethernet devices, in active-backup bond mode
+Host #2 description:
+ One ethernet device
+Test name:
+ bonding_test.py
+Test description:
+ Ping:
+ + count: 100
+ + interval: 0.1s
+ + from both sides
+ Netperf:
+ + duration: 60s
+ + TCP_STREAM and UDP_STREAM
+ + from both sides
+ Offloads:
+ + TSO, GRO, GSO
+ + tested both on/off variants
diff --git a/recipes/regression_tests/phase1/active_backup.xml b/recipes/regression_tests/phase1/active_backup.xml
new file mode 100644
index 0000000..760ff8d
--- /dev/null
+++ b/recipes/regression_tests/phase1/active_backup.xml
@@ -0,0 +1,34 @@
+<lnstrecipe>
+ <network>
+ <host id="testmachine1">
+ <interfaces>
+ <eth id="eth1" label="tnet" />
+ <eth id="eth2" label="tnet" />
+ <bond id="test_if">
+ <options>
+ <option name="mode" value="active-backup" />
+ <option name="miimon" value="100" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ <slave id="eth2" />
+ </slaves>
+ <addresses>
+ <address value="192.168.0.1/24" />
+ </addresses>
+ </bond>
+ </interfaces>
+ </host>
+ <host id="testmachine2">
+ <interfaces>
+ <eth id="test_if" label="tnet">
+ <addresses>
+ <address value="192.168.0.2/24" />
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+
+ <task python="bonding_test.py" />
+</lnstrecipe>
diff --git a/recipes/regression_tests/phase1/active_backup_double_bond.README b/recipes/regression_tests/phase1/active_backup_double_bond.README
new file mode 100644
index 0000000..5deb92f
--- /dev/null
+++ b/recipes/regression_tests/phase1/active_backup_double_bond.README
@@ -0,0 +1,51 @@
+Topology:
+
+ switch
+ +------+
+ | |
+ | |
+ +-------------------+ +-------------------+
+ | | | |
+ | | | |
+ | +------+ |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----+---+ +----+---+
+ | BOND | | BOND |
+ +---++---+ +---++---+
+ || ||
+ +--++--+ +--++--+
+ | | | |
+ +--+-+ +-+--+ +--+-+ +-+--+
++---|eth1|--|eth2|---+ +---|eth1|--|eth2|---+
+| +----+ +----+ | | +----+ +----+ |
+| | | |
+| | | |
+| host1 | | host2 |
+| | | |
+| | | |
+| | | |
++--------------------+ +--------------------+
+
+Number of hosts: 2
+Host #1 description:
+ Two ethernet devices, in active-backup bond mode
+Host #2 description:
+ Two ethernet devices, in active-backup bond mode
+Test name:
+ bonding_test.py
+Test description:
+ Ping:
+ + count: 100
+ + interval: 0.1s
+ + from both sides
+ Netperf:
+ + duration: 60s
+ + TCP_STREAM and UDP_STREAM
+ + from both sides
+ Offloads:
+ + TSO, GRO, GSO
+ + tested both on/off variants
diff --git a/recipes/regression_tests/phase1/active_backup_double_bond.xml b/recipes/regression_tests/phase1/active_backup_double_bond.xml
new file mode 100644
index 0000000..9fa6286
--- /dev/null
+++ b/recipes/regression_tests/phase1/active_backup_double_bond.xml
@@ -0,0 +1,44 @@
+<lnstrecipe>
+ <network>
+ <host id="testmachine1">
+ <interfaces>
+ <eth id="eth1" label="tnet" />
+ <eth id="eth2" label="tnet" />
+ <bond id="test_if">
+ <options>
+ <option name="mode" value="active-backup" />
+ <option name="miimon" value="100" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ <slave id="eth2" />
+ </slaves>
+ <addresses>
+ <address value="192.168.0.1/24" />
+ </addresses>
+ </bond>
+ </interfaces>
+ </host>
+ <host id="testmachine2">
+ <interfaces>
+ <eth id="eth1" label="tnet" />
+ <eth id="eth2" label="tnet" />
+ <bond id="test_if">
+ <options>
+ <option name="mode" value="active-backup" />
+ <option name="miimon" value="100" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ <slave id="eth2" />
+ </slaves>
+ <addresses>
+ <address value="192.168.0.2/24" />
+ </addresses>
+ </bond>
+ </interfaces>
+ </host>
+ </network>
+
+ <task python="bonding_test.py" />
+</lnstrecipe>
diff --git a/recipes/regression_tests/phase1/bonding_test.py b/recipes/regression_tests/phase1/bonding_test.py
new file mode 100644
index 0000000..38e058b
--- /dev/null
+++ b/recipes/regression_tests/phase1/bonding_test.py
@@ -0,0 +1,110 @@
+from lnst.Controller.Task import ctl
+
+# ------
+# SETUP
+# ------
+
+m1 = ctl.get_host("testmachine1")
+m2 = ctl.get_host("testmachine2")
+
+m1.sync_resources(modules=["IcmpPing", "Netperf"])
+m2.sync_resources(modules=["IcmpPing", "Netperf"])
+
+m1_ip = m1.get_ip("test_if")
+m2_ip = m2.get_ip("test_if")
+
+# ------
+# TESTS
+# ------
+
+offloads = ["tso", "gro", "gso"]
+
+ping_mod = ctl.get_module("IcmpPing",
+ options={
+ "addr" : m2_ip,
+ "count" : 100,
+ "iface" : m1.get_devname("test_if"),
+ "interval" : 0.1
+ })
+
+netperf_srv = ctl.get_module("Netperf",
+ options = {
+ "role" : "server",
+ "bind" : m1_ip
+ })
+
+netperf_cli_tcp = ctl.get_module("Netperf",
+ options = {
+ "role" : "client",
+ "netperf_server" : m1_ip,
+ "duration" : 60,
+ "testname" : "TCP_STREAM",
+ "netperf_opts" : "-L %s" % m2_ip
+ })
+
+netperf_cli_udp = ctl.get_module("Netperf",
+ options = {
+ "role" : "client",
+ "netperf_server" : m1_ip,
+ "duration" : 60,
+ "testname" : "UDP_STREAM",
+ "netperf_opts" : "-L %s" % m2_ip
+ })
+for offload in offloads:
+ for state in ["on", "off"]:
+ m1.run("ethtool -K %s %s %s" % (m1.get_devname("test_if"), offload,
+ state))
+ m2.run("ethtool -K %s %s %s" % (m2.get_devname("test_if"), offload,
+ state))
+ m1.run(ping_mod)
+ server_proc = m1.run(netperf_srv, bg=True)
+ ctl.wait(2)
+ m2.run(netperf_cli_tcp, timeout=65)
+ m2.run(netperf_cli_udp, timeout=65)
+ server_proc.intr()
+
+ping_mod = ctl.get_module("IcmpPing",
+ options={
+ "addr" : m1_ip,
+ "count" : 100,
+ "iface" : m2.get_devname("test_if"),
+ "interval" : 0.1
+ })
+
+
+netperf_srv = ctl.get_module("Netperf",
+ options = {
+ "role" : "server",
+ "bind" : m2_ip
+ })
+
+netperf_cli_tcp = ctl.get_module("Netperf",
+ options = {
+ "role" : "client",
+ "netperf_server" : m2_ip,
+ "duration" : 60,
+ "testname" : "TCP_STREAM",
+ "netperf_opts" : "-L %s" % m1_ip
+ })
+
+netperf_cli_udp = ctl.get_module("Netperf",
+ options = {
+ "role" : "client",
+ "netperf_server" : m2_ip,
+ "duration" : 60,
+ "testname" : "UDP_STREAM",
+ "netperf_opts" : "-L %s" % m1_ip
+ })
+
+for offload in offloads:
+ for state in ["on", "off"]:
+ m1.run("ethtool -K %s %s %s" % (m1.get_devname("test_if"), offload,
+ state))
+ m2.run("ethtool -K %s %s %s" % (m2.get_devname("test_if"), offload,
+ state))
+ m2.run(ping_mod)
+ server_proc = m2.run(netperf_srv, bg=True)
+ ctl.wait(2)
+ m1.run(netperf_cli_tcp, timeout=65)
+ m1.run(netperf_cli_udp, timeout=65)
+ server_proc.intr()
diff --git a/recipes/regression_tests/phase1/ping_flood.README b/recipes/regression_tests/phase1/ping_flood.README
new file mode 100644
index 0000000..516f2ac
--- /dev/null
+++ b/recipes/regression_tests/phase1/ping_flood.README
@@ -0,0 +1,38 @@
+Topology:
+ +--------+
+ | |
+ +----------------------+ switch +----------------------+
+ | | | |
+ | +--------+ |
+ | |
+ | |
+ | |
+ | |
+ +--+-+ +-+--+
++-------|eth1|-------+ +-------|eth1|-------+
+| +----+ | | +----+ |
+| | | |
+| | | |
+| | | |
+| | | |
+| host1 | | host2 |
+| | | |
+| | | |
+| | | |
+| | | |
+| | | |
++--------------------+ +--------------------+
+
+
+Number of hosts: 2
+Host #1 description:
+ One ethernet device
+Host #2 description:
+ One ethernet device
+Test name:
+ simple_ping.py
+Test description:
+ Ping:
+ + count: 100
+ + interval: 0.2s
+ + from host1 to host2
diff --git a/recipes/regression_tests/phase1/ping_flood.xml b/recipes/regression_tests/phase1/ping_flood.xml
new file mode 100644
index 0000000..3f466d9
--- /dev/null
+++ b/recipes/regression_tests/phase1/ping_flood.xml
@@ -0,0 +1,23 @@
+<lnstrecipe>
+ <network>
+ <host id="machine1">
+ <interfaces>
+ <eth id="testiface" label="testnet">
+ <addresses>
+ <address>192.168.100.10/24</address>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ <host id="machine2">
+ <interfaces>
+ <eth id="testiface" label="testnet">
+ <addresses>
+ <address>192.168.100.11/24</address>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+ <task python="simple_ping.py"/>
+</lnstrecipe>
diff --git a/recipes/regression_tests/phase1/round_robin.README b/recipes/regression_tests/phase1/round_robin.README
new file mode 100644
index 0000000..06244f8
--- /dev/null
+++ b/recipes/regression_tests/phase1/round_robin.README
@@ -0,0 +1,51 @@
+Topology:
+
+ switch
+ +------+
+ | |
+ | |
+ +-------------------+ +------------------+
+ | | | |
+ | | | |
+ | +------+ |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----+---+ |
+ | BOND | |
+ +---++---+ |
+ || |
+ +--++--+ |
+ | | |
+ +--+-+ +-+--+ +-+--+
++---|eth1|--|eth2|---+ +-------|eth1|------+
+| +----+ +----+ | | +----+ |
+| | | |
+| | | |
+| host1 | | host2 |
+| | | |
+| | | |
+| | | |
++--------------------+ +-------------------+
+
+Number of hosts: 2
+Host #1 description:
+ Two ethernet devices, in round-robin bond mode
+Host #2 description:
+ One ethernet device
+Test name:
+ bonding_test.py
+Test description:
+ Ping:
+ + count: 100
+ + interval: 0.1s
+ + from both sides
+ Netperf:
+ + duration: 60s
+ + TCP_STREAM and UDP_STREAM
+ + from both sides
+ Offloads:
+ + TSO, GRO, GSO
+ + tested both on/off variants
diff --git a/recipes/regression_tests/phase1/round_robin.xml b/recipes/regression_tests/phase1/round_robin.xml
new file mode 100644
index 0000000..728dfa4
--- /dev/null
+++ b/recipes/regression_tests/phase1/round_robin.xml
@@ -0,0 +1,34 @@
+<lnstrecipe>
+ <network>
+ <host id="testmachine1">
+ <interfaces>
+ <eth id="eth1" label="tnet" />
+ <eth id="eth2" label="tnet" />
+ <bond id="test_if">
+ <options>
+ <option name="mode" value="balance-rr" />
+ <option name="miimon" value="100" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ <slave id="eth2" />
+ </slaves>
+ <addresses>
+ <address value="192.168.0.1/24" />
+ </addresses>
+ </bond>
+ </interfaces>
+ </host>
+ <host id="testmachine2">
+ <interfaces>
+ <eth id="test_if" label="tnet">
+ <addresses>
+ <address value="192.168.0.2/24" />
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+
+ <task python="bonding_test.py" />
+</lnstrecipe>
diff --git a/recipes/regression_tests/phase1/round_robin_double_bond.README b/recipes/regression_tests/phase1/round_robin_double_bond.README
new file mode 100644
index 0000000..e5b127d
--- /dev/null
+++ b/recipes/regression_tests/phase1/round_robin_double_bond.README
@@ -0,0 +1,51 @@
+Topology:
+
+ switch
+ +------+
+ | |
+ | |
+ +-------------------+ +-------------------+
+ | | | |
+ | | | |
+ | +------+ |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----+---+ +----+---+
+ | BOND | | BOND |
+ +---++---+ +---++---+
+ || ||
+ +--++--+ +--++--+
+ | | | |
+ +--+-+ +-+--+ +--+-+ +-+--+
++---|eth1|--|eth2|---+ +---|eth1|--|eth2|---+
+| +----+ +----+ | | +----+ +----+ |
+| | | |
+| | | |
+| host1 | | host2 |
+| | | |
+| | | |
+| | | |
++--------------------+ +--------------------+
+
+Number of hosts: 2
+Host #1 description:
+ Two ethernet devices, in round-robin bond mode
+Host #2 description:
+ Two ethernet devices, in round-robin bond mode
+Test name:
+ bonding_test.py
+Test description:
+ Ping:
+ + count: 100
+ + interval: 0.1s
+ + from both sides
+ Netperf:
+ + duration: 60s
+ + TCP_STREAM and UDP_STREAM
+ + from both sides
+ Offloads:
+ + TSO, GRO, GSO
+ + tested both on/off variants
diff --git a/recipes/regression_tests/phase1/round_robin_double_bond.xml b/recipes/regression_tests/phase1/round_robin_double_bond.xml
new file mode 100644
index 0000000..556fbd2
--- /dev/null
+++ b/recipes/regression_tests/phase1/round_robin_double_bond.xml
@@ -0,0 +1,44 @@
+<lnstrecipe>
+ <network>
+ <host id="testmachine1">
+ <interfaces>
+ <eth id="eth1" label="tnet" />
+ <eth id="eth2" label="tnet" />
+ <bond id="test_if">
+ <options>
+ <option name="mode" value="balance-rr" />
+ <option name="miimon" value="100" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ <slave id="eth2" />
+ </slaves>
+ <addresses>
+ <address value="192.168.0.1/24" />
+ </addresses>
+ </bond>
+ </interfaces>
+ </host>
+ <host id="testmachine2">
+ <interfaces>
+ <eth id="eth1" label="tnet" />
+ <eth id="eth2" label="tnet" />
+ <bond id="test_if">
+ <options>
+ <option name="mode" value="balance-rr" />
+ <option name="miimon" value="100" />
+ </options>
+ <slaves>
+ <slave id="eth1" />
+ <slave id="eth2" />
+ </slaves>
+ <addresses>
+ <address value="192.168.0.2/24" />
+ </addresses>
+ </bond>
+ </interfaces>
+ </host>
+ </network>
+
+ <task python="bonding_test.py" />
+</lnstrecipe>
diff --git a/recipes/regression_tests/phase1/simple_ping.py b/recipes/regression_tests/phase1/simple_ping.py
new file mode 100644
index 0000000..400104a
--- /dev/null
+++ b/recipes/regression_tests/phase1/simple_ping.py
@@ -0,0 +1,19 @@
+from lnst.Controller.Task import ctl
+
+hostA = ctl.get_host("machine1")
+hostB = ctl.get_host("machine2")
+
+hostA.sync_resources(modules=["IcmpPing"])
+hostB.sync_resources(modules=["IcmpPing"])
+
+hostA_devices = hostA.get_interface("testiface")
+hostB_devices = hostB.get_interface("testiface")
+
+ping_mod = ctl.get_module("IcmpPing",
+ options={
+ "addr": hostB.get_ip("testiface", 0),
+ "count": 100,
+ "interval": 0.2,
+ "limit_rate": 95})
+
+hostA.run(ping_mod)
diff --git a/recipes/regression_tests/phase1/virtual_bridge_2_vlans_over_active_backup.README b/recipes/regression_tests/phase1/virtual_bridge_2_vlans_over_active_backup.README
new file mode 100644
index 0000000..876c89c
--- /dev/null
+++ b/recipes/regression_tests/phase1/virtual_bridge_2_vlans_over_active_backup.README
@@ -0,0 +1,76 @@
+Topology:
+
+ switch
+ +--------+
+ | |
+ +-------------------------+ +--------------------------+
+ | | | |
+ | +---------------+ +----------------+ |
+ | | | | | |
+ | | +--------+ | |
+ | | | |
+ | | | |
+ +--+-+ +--+-+ +-+--+ +-+--+
++----+eth1+----+eth2+----+ +----+eth1+----+eth2+----+
+| +-+--+ +--+-+ | | +-+--+ +--+-+ |
+| +--++ ++--+ | | +--++ ++--+ |
+| | | | | | | |
+| | | | | | | |
+| +-+--+-+ | | +-+--+-+ |
+| | bond | | | | bond | |
+| VLAN10 +-+--+-+ VLAN20 | | VLAN10 +-+--+-+ VLAN20 |
+| +---+-+ +-+---+ | | +---+-+ +-+---+ |
+| | | | | | | |
+| +-+-+ +-+-+ | | +-+-+ +-+-+ |
+| |br0| host1 |br1| | | |br0| host2 |br1| |
+| +-+-+ +-+-+ | | +-+-+ +-+-+ |
+| | | | | | | |
+| | | | | | | |
+| | | | | | | |
+| +-+-+ +-+-+ | | +-+-+ +-+-+ |
++--+tap+----------+tap+--+ +--+tap+----------+tap+--+
+ +-+-+ +-+-+ +-+-+ +-+-+
+ | | | |
+ +-+-+ +-+-+ +-+-+ +-+-+
++--+eth+--+ +--+eth+--+ +--+eth+--+ +--+eth+--+
+| +---+ | | +---+ | | +---+ | | +---+ |
+| | | | | | | |
+| guest1 | | guest2 | | guest3 | | guest4 |
+| | | | | | | |
+| | | | | | | |
++---------+ +---------+ +---------+ +---------+
+
+Number of hosts: 4
+Host #1 description:
+ Two ethernet devices
+ Two tap devices
+ One bond in active-backup mode, bonding ethernet devices
+ Two VLANs over bond device
+ Two bridge devices, bridging VLAN and tap devices
+ Host for guest1 and guest2 virtual machines
+Host #2 description:
+ Two ethernet devices
+ Two tap devices
+ One bond in active-backup mode, bonding ethernet devices
+ Two VLANs over bond device
+ Two bridge devices, bridging VLAN and tap devices
+ Host for guest3 and guest4 virtual machines
+Guest #1 description:
+ One ethernet device
+Guest #2 description:
+ One ethernet device
+Guest #3 description:
+ One ethernet device
+Guest #4 description:
+ One ethernet device
+Test name:
+ virtual_bridge_2_vlans_over_bond.py
+Test description:
+ Ping:
+ + count: 100
+ + interval: 0.1s
+ + between guests in same VLANs
+ Netperf:
+ + duration: 5
+ + TCP_STREAM and UDP_STREAM
+ + between guests in same VLANs
diff --git a/recipes/regression_tests/phase1/virtual_bridge_2_vlans_over_active_backup.xml b/recipes/regression_tests/phase1/virtual_bridge_2_vlans_over_active_backup.xml
new file mode 100644
index 0000000..950bf0d
--- /dev/null
+++ b/recipes/regression_tests/phase1/virtual_bridge_2_vlans_over_active_backup.xml
@@ -0,0 +1,153 @@
+<lnstrecipe>
+ <network>
+ <host id="host1">
+ <interfaces>
+ <eth id="nic1" label="to_switch" />
+ <eth id="nic2" label="to_switch" />
+ <eth id="tap1" label="to_guest1" />
+ <eth id="tap2" label="to_guest2" />
+ <bond id="bond">
+ <options>
+ <option name="mode" value="active-backup" />
+ <option name="miimon" value="100" />
+ </options>
+ <slaves>
+ <slave id="nic1" />
+ <slave id="nic2" />
+ </slaves>
+ <addresses>
+ <address>1.2.3.4/24</address>
+ </addresses>
+ </bond>
+ <vlan id="vlan10">
+ <options>
+ <option name="vlan_tci" value="10" />
+ </options>
+ <slaves>
+ <slave id="bond" />
+ </slaves>
+ </vlan>
+ <vlan id="vlan20">
+ <options>
+ <option name="vlan_tci" value="20" />
+ </options>
+ <slaves>
+ <slave id="bond" />
+ </slaves>
+ </vlan>
+ <bridge id="br1">
+ <slaves>
+ <slave id="tap1" />
+ <slave id="vlan10" />
+ </slaves>
+ <addresses>
+ <address>192.168.10.10/24</address>
+ </addresses>
+ </bridge>
+ <bridge id="br2">
+ <slaves>
+ <slave id="tap2" />
+ <slave id="vlan20" />
+ </slaves>
+ <addresses>
+ <address>192.168.20.10/24</address>
+ </addresses>
+ </bridge>
+ </interfaces>
+ </host>
+ <host id="guest1">
+ <interfaces>
+ <eth id="guestnic" label="to_guest1">
+ <addresses>
+ <address>192.168.10.100/24</address>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ <host id="guest2">
+ <interfaces>
+ <eth id="guestnic" label="to_guest2">
+ <addresses>
+ <address>192.168.20.100/24</address>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+
+ <host id="host2">
+ <interfaces>
+ <eth id="nic1" label="to_switch"/>
+ <eth id="nic2" label="to_switch"/>
+ <eth id="tap1" label="to_guest3"/>
+ <eth id="tap2" label="to_guest4"/>
+ <bond id="bond">
+ <options>
+ <option name="mode" value="active-backup" />
+ <option name="miimon" value="100" />
+ </options>
+ <slaves>
+ <slave id="nic1" />
+ <slave id="nic2" />
+ </slaves>
+ <addresses>
+ <address>1.2.3.4/24</address>
+ </addresses>
+ </bond>
+ <vlan id="vlan10">
+ <options>
+ <option name="vlan_tci" value="10" />
+ </options>
+ <slaves>
+ <slave id="bond" />
+ </slaves>
+ </vlan>
+ <vlan id="vlan20">
+ <options>
+ <option name="vlan_tci" value="20" />
+ </options>
+ <slaves>
+ <slave id="bond" />
+ </slaves>
+ </vlan>
+ <bridge id="br1">
+ <slaves>
+ <slave id="vlan10"/>
+ <slave id="tap1"/>
+ </slaves>
+ <addresses>
+ <address>192.168.10.11/24</address>
+ </addresses>
+ </bridge>
+ <bridge id="br2">
+ <slaves>
+ <slave id="vlan20"/>
+ <slave id="tap2"/>
+ </slaves>
+ <addresses>
+ <address>192.168.20.11/24</address>
+ </addresses>
+ </bridge>
+ </interfaces>
+ </host>
+ <host id="guest3">
+ <interfaces>
+ <eth id="guestnic" label="to_guest3">
+ <addresses>
+ <address>192.168.10.101/24</address>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ <host id="guest4">
+ <interfaces>
+ <eth id="guestnic" label="to_guest4">
+ <addresses>
+ <address>192.168.20.101/24</address>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+
+ <task python="virtual_bridge_2_vlans_over_bond.py" />
+</lnstrecipe>
diff --git a/recipes/regression_tests/phase1/virtual_bridge_2_vlans_over_bond.py b/recipes/regression_tests/phase1/virtual_bridge_2_vlans_over_bond.py
new file mode 100644
index 0000000..36eabd3
--- /dev/null
+++ b/recipes/regression_tests/phase1/virtual_bridge_2_vlans_over_bond.py
@@ -0,0 +1,99 @@
+from lnst.Controller.Task import ctl
+
+# ------
+# SETUP
+# ------
+
+# Host 1 + guests 1 and 2
+#h1 = ctl.get_host("host1")
+g1 = ctl.get_host("guest1")
+g1.sync_resources(modules=["IcmpPing", "Netperf"])
+g2 = ctl.get_host("guest2")
+g2.sync_resources(modules=["IcmpPing", "Netperf"])
+
+# Host 2 + guests 3 and 4
+#h2 = ctl.get_host("host2")
+g3 = ctl.get_host("guest3")
+g3.sync_resources(modules=["IcmpPing", "Netperf"])
+g4 = ctl.get_host("guest4")
+g4.sync_resources(modules=["IcmpPing", "Netperf"])
+
+# ------
+# TESTS
+# ------
+
+offloads = ["gso", "gro", "tso"]
+
+ping_mod = ctl.get_module("IcmpPing",
+ options={
+ "addr" : g3.get_ip("guestnic"),
+ "count" : 100,
+ "iface" : g1.get_devname("guestnic"),
+ "interval" : 0.1
+ })
+ping_mod2 = ctl.get_module("IcmpPing",
+ options={
+ "addr" : g2.get_ip("guestnic"),
+ "count" : 100,
+ "iface" : g4.get_devname("guestnic"),
+ "interval" : 0.1
+ })
+netperf_srv = ctl.get_module("Netperf",
+ options={
+ "role": "server",
+ "bind" : g1.get_ip("guestnic")
+ })
+
+netperf_cli_tcp = ctl.get_module("Netperf",
+ options={
+ "role" : "client",
+ "netperf_server" : g1.get_ip("guestnic"),
+ "duration" : 60,
+ "testname" : "TCP_STREAM",
+ "netperf_opts" : "-L %s" %
+ g3.get_ip("guestnic")
+ })
+
+netperf_cli_udp = ctl.get_module("Netperf",
+ options={
+ "role" : "client",
+ "netperf_server" : g1.get_ip("guestnic"),
+ "duration" : 60,
+ "testname" : "UDP_STREAM",
+ "netperf_opts" : "-L %s" %
+ g3.get_ip("guestnic")
+ })
+ping_mod_bad = ctl.get_module("IcmpPing",
+ options={
+ "addr" : g4.get_ip("guestnic"),
+ "count" : 100,
+ "iface" : g1.get_devname("guestnic"),
+ "interval" : 0.1
+ })
+ping_mod_bad2 = ctl.get_module("IcmpPing",
+ options={
+ "addr" : g2.get_ip("guestnic"),
+ "count" : 100,
+ "iface" : g3.get_devname("guestnic"),
+ "interval" : 0.1
+ })
+
+for offload in offloads:
+ for state in ["on", "off"]:
+ g1.run("ethtool -K %s %s %s" % (g1.get_devname("guestnic"),
+ offload, state))
+ g2.run("ethtool -K %s %s %s" % (g2.get_devname("guestnic"),
+ offload, state))
+ g3.run("ethtool -K %s %s %s" % (g3.get_devname("guestnic"),
+ offload, state))
+ g4.run("ethtool -K %s %s %s" % (g4.get_devname("guestnic"),
+ offload, state))
+ g1.run(ping_mod)
+ g4.run(ping_mod2)
+ g1.run(ping_mod_bad, expect="fail")
+ g3.run(ping_mod_bad2, expect="fail")
+
+ g1.run(netperf_srv, bg=True, timeout=125)
+ ctl.wait(2)
+ g3.run(netperf_cli_tcp, timeout=65)
+ g3.run(netperf_cli_udp, timeout=65)
diff --git a/recipes/regression_tests/phase1/virtual_bridge_2_vlans_over_round_robin.README b/recipes/regression_tests/phase1/virtual_bridge_2_vlans_over_round_robin.README
new file mode 100644
index 0000000..7048b8c
--- /dev/null
+++ b/recipes/regression_tests/phase1/virtual_bridge_2_vlans_over_round_robin.README
@@ -0,0 +1,76 @@
+Topology:
+
+ switch
+ +--------+
+ | |
+ +-------------------------+ +--------------------------+
+ | | | |
+ | +---------------+ +----------------+ |
+ | | | | | |
+ | | +--------+ | |
+ | | | |
+ | | | |
+ +--+-+ +--+-+ +-+--+ +-+--+
++----+eth1+----+eth2+----+ +----+eth1+----+eth2+----+
+| +-+--+ +--+-+ | | +-+--+ +--+-+ |
+| +--++ ++--+ | | +--++ ++--+ |
+| | | | | | | |
+| | | | | | | |
+| +-+--+-+ | | +-+--+-+ |
+| | bond | | | | bond | |
+| VLAN10 +-+--+-+ VLAN20 | | VLAN10 +-+--+-+ VLAN20 |
+| +---+-+ +-+---+ | | +---+-+ +-+---+ |
+| | | | | | | |
+| +-+-+ +-+-+ | | +-+-+ +-+-+ |
+| |br0| host1 |br1| | | |br0| host2 |br1| |
+| +-+-+ +-+-+ | | +-+-+ +-+-+ |
+| | | | | | | |
+| | | | | | | |
+| | | | | | | |
+| +-+-+ +-+-+ | | +-+-+ +-+-+ |
++--+tap+----------+tap+--+ +--+tap+----------+tap+--+
+ +-+-+ +-+-+ +-+-+ +-+-+
+ | | | |
+ +-+-+ +-+-+ +-+-+ +-+-+
++--+eth+--+ +--+eth+--+ +--+eth+--+ +--+eth+--+
+| +---+ | | +---+ | | +---+ | | +---+ |
+| | | | | | | |
+| guest1 | | guest2 | | guest3 | | guest4 |
+| | | | | | | |
+| | | | | | | |
++---------+ +---------+ +---------+ +---------+
+
+Number of hosts: 4
+Host #1 description:
+ Two ethernet devices
+ Two tap devices
+ One bond in round-robin mode, bonding ethernet devices
+ Two VLANs over bond device
+ Two bridge devices, bridging VLAN and tap devices
+ Host for guest1 and guest2 virtual machines
+Host #2 description:
+ Two ethernet devices
+ Two tap devices
+ One bond in round-robin mode, bonding ethernet devices
+ Two VLANs over bond device
+ Two bridge devices, bridging VLAN and tap devices
+ Host for guest3 and guest4 virtual machines
+Guest #1 description:
+ One ethernet device
+Guest #2 description:
+ One ethernet device
+Guest #3 description:
+ One ethernet device
+Guest #4 description:
+ One ethernet device
+Test name:
+ virtual_bridge_2_vlans_over_bond.py
+Test description:
+ Ping:
+ + count: 100
+ + interval: 0.1s
+ + between guests in same VLANs
+ Netperf:
+ + duration: 5
+ + TCP_STREAM and UDP_STREAM
+ + between guests in same VLANs
diff --git a/recipes/regression_tests/phase1/virtual_bridge_2_vlans_over_round_robin.xml b/recipes/regression_tests/phase1/virtual_bridge_2_vlans_over_round_robin.xml
new file mode 100644
index 0000000..e914636
--- /dev/null
+++ b/recipes/regression_tests/phase1/virtual_bridge_2_vlans_over_round_robin.xml
@@ -0,0 +1,153 @@
+<lnstrecipe>
+ <network>
+ <host id="host1">
+ <interfaces>
+ <eth id="nic1" label="to_switch" />
+ <eth id="nic2" label="to_switch" />
+ <eth id="tap1" label="to_guest1" />
+ <eth id="tap2" label="to_guest2" />
+ <bond id="bond">
+ <options>
+ <option name="mode" value="balance-rr" />
+ <option name="miimon" value="100" />
+ </options>
+ <slaves>
+ <slave id="nic1" />
+ <slave id="nic2" />
+ </slaves>
+ <addresses>
+ <address>1.2.3.4/24</address>
+ </addresses>
+ </bond>
+ <vlan id="vlan10">
+ <options>
+ <option name="vlan_tci" value="10" />
+ </options>
+ <slaves>
+ <slave id="bond" />
+ </slaves>
+ </vlan>
+ <vlan id="vlan20">
+ <options>
+ <option name="vlan_tci" value="20" />
+ </options>
+ <slaves>
+ <slave id="bond" />
+ </slaves>
+ </vlan>
+ <bridge id="br1">
+ <slaves>
+ <slave id="tap1" />
+ <slave id="vlan10" />
+ </slaves>
+ <addresses>
+ <address>192.168.10.10/24</address>
+ </addresses>
+ </bridge>
+ <bridge id="br2">
+ <slaves>
+ <slave id="tap2" />
+ <slave id="vlan20" />
+ </slaves>
+ <addresses>
+ <address>192.168.20.10/24</address>
+ </addresses>
+ </bridge>
+ </interfaces>
+ </host>
+ <host id="guest1">
+ <interfaces>
+ <eth id="guestnic" label="to_guest1">
+ <addresses>
+ <address>192.168.10.100/24</address>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ <host id="guest2">
+ <interfaces>
+ <eth id="guestnic" label="to_guest2">
+ <addresses>
+ <address>192.168.20.100/24</address>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+
+ <host id="host2">
+ <interfaces>
+ <eth id="nic1" label="to_switch"/>
+ <eth id="nic2" label="to_switch"/>
+ <eth id="tap1" label="to_guest3"/>
+ <eth id="tap2" label="to_guest4"/>
+ <bond id="bond">
+ <options>
+ <option name="mode" value="balance-rr" />
+ <option name="miimon" value="100" />
+ </options>
+ <slaves>
+ <slave id="nic1" />
+ <slave id="nic2" />
+ </slaves>
+ <addresses>
+ <address>1.2.3.4/24</address>
+ </addresses>
+ </bond>
+ <vlan id="vlan10">
+ <options>
+ <option name="vlan_tci" value="10" />
+ </options>
+ <slaves>
+ <slave id="bond" />
+ </slaves>
+ </vlan>
+ <vlan id="vlan20">
+ <options>
+ <option name="vlan_tci" value="20" />
+ </options>
+ <slaves>
+ <slave id="bond" />
+ </slaves>
+ </vlan>
+ <bridge id="br1">
+ <slaves>
+ <slave id="vlan10"/>
+ <slave id="tap1"/>
+ </slaves>
+ <addresses>
+ <address>192.168.10.11/24</address>
+ </addresses>
+ </bridge>
+ <bridge id="br2">
+ <slaves>
+ <slave id="vlan20"/>
+ <slave id="tap2"/>
+ </slaves>
+ <addresses>
+ <address>192.168.20.11/24</address>
+ </addresses>
+ </bridge>
+ </interfaces>
+ </host>
+ <host id="guest3">
+ <interfaces>
+ <eth id="guestnic" label="to_guest3">
+ <addresses>
+ <address>192.168.10.101/24</address>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ <host id="guest4">
+ <interfaces>
+ <eth id="guestnic" label="to_guest4">
+ <addresses>
+ <address>192.168.20.101/24</address>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+
+ <task python="virtual_bridge_2_vlans_over_bond.py" />
+</lnstrecipe>
diff --git a/recipes/regression_tests/phase1/virtual_bridge_vlan_in_guest.README b/recipes/regression_tests/phase1/virtual_bridge_vlan_in_guest.README
new file mode 100644
index 0000000..673a6c2
--- /dev/null
+++ b/recipes/regression_tests/phase1/virtual_bridge_vlan_in_guest.README
@@ -0,0 +1,52 @@
+Topology:
+
+ +----------+
+ | | VLAN10
+ +-----------------+ switch +-----------------+
+ | | | |
+ | +----------+ |
+ | |
+ +-+-+ |
++------|nic|------+ +-+-+
+| +-+-+ | +------|nic|------+
+| | | | +---+ |
+| +----+ | | |
+| | | | |
+| +-+-+ | | |
+| |br0| | | host2 |
+| +-+-+ host1 | | |
+| | | | |
+| +-+-+ | | |
++-|tap|-----------+ | |
+ +-+-+ +-----------------+
+ |
+ |VLAN10
+ |
+ +-+-+
++-|nic|--+
+| +---+ |
+| guest1 |
+| |
++--------+
+
+Number of hosts: 3
+Host #1 description:
+ One ethernet device
+ One tap device
+ One bridge device, bridging ethernet and tap devices
+ Host for guest1 virtual machine
+Host #2 description:
+ One ethernet device with one VLAN subinterface
+Guest #1 description:
+ One ethernet device with one VLAN subinterface
+Test name:
+ virtual_bridge_vlan_in_guest.py
+Test description:
+ Ping:
+ + count: 100
+ + interval: 0.1s
+ + between guest1's VLAN10 and host2's VLAN10
+ Netperf:
+ + duration: 60s
+ + TCP_STREAM and UDP_STREAM
+ + between guest1's VLAN10 and host2's VLAN10
diff --git a/recipes/regression_tests/phase1/virtual_bridge_vlan_in_guest.py b/recipes/regression_tests/phase1/virtual_bridge_vlan_in_guest.py
new file mode 100644
index 0000000..71c7f4d
--- /dev/null
+++ b/recipes/regression_tests/phase1/virtual_bridge_vlan_in_guest.py
@@ -0,0 +1,65 @@
+from lnst.Controller.Task import ctl
+
+# ------
+# SETUP
+# ------
+
+h1 = ctl.get_host("host1")
+g1 = ctl.get_host("guest1")
+
+h2 = ctl.get_host("host2")
+
+g1.sync_resources(modules=["IcmpPing", "Netperf"])
+h2.sync_resources(modules=["IcmpPing", "Netperf"])
+
+# ------
+# TESTS
+# ------
+
+offloads = ["gso", "gro", "tso"]
+
+ping_mod = ctl.get_module("IcmpPing",
+ options={
+ "addr" : h2.get_ip("vlan10"),
+ "count" : 100,
+ "iface" : g1.get_devname("vlan10"),
+ "interval" : 0.1
+ })
+netperf_srv = ctl.get_module("Netperf",
+ options={
+ "role" : "server",
+ "bind" : g1.get_ip("vlan10")
+ })
+
+netperf_cli_tcp = ctl.get_module("Netperf",
+ options={
+ "role" : "client",
+ "netperf_server" : g1.get_ip("vlan10"),
+ "duration" : 60,
+ "testname" : "TCP_STREAM",
+ "netperf_opts" : "-L %s" %
+ h2.get_ip("vlan10")
+ })
+
+netperf_cli_udp = ctl.get_module("Netperf",
+ options={
+ "role" : "client",
+ "netperf_server" : g1.get_ip("vlan10"),
+ "duration" : 60,
+ "testname" : "UDP_STREAM",
+ "netperf_opts" : "-L %s" %
+ h2.get_ip("vlan10")
+ })
+for offload in offloads:
+ for state in ["on", "off"]:
+ g1.run("ethtool -K %s %s %s" % (g1.get_devname("guestnic"),
+ offload, state))
+ h2.run("ethtool -K %s %s %s" % (h2.get_devname("nic"),
+ offload, state))
+ g1.run(ping_mod)
+ server_proc = g1.run(netperf_srv, bg=True)
+ ctl.wait(2)
+ h2.run(netperf_cli_tcp, timeout=65)
+ h2.run(netperf_cli_udp, timeout=65)
+
+ server_proc.intr()
diff --git a/recipes/regression_tests/phase1/virtual_bridge_vlan_in_guest.xml b/recipes/regression_tests/phase1/virtual_bridge_vlan_in_guest.xml
new file mode 100644
index 0000000..95ec86f
--- /dev/null
+++ b/recipes/regression_tests/phase1/virtual_bridge_vlan_in_guest.xml
@@ -0,0 +1,53 @@
+<lnstrecipe>
+ <network>
+ <host id="host1">
+ <interfaces>
+ <eth id="nic" label="to_switch" />
+ <eth id="tap" label="to_guest" />
+ <bridge id="br">
+ <slaves>
+ <slave id="tap" />
+ <slave id="nic" />
+ </slaves>
+ <addresses>
+ <address>192.168.10.1/24</address>
+ </addresses>
+ </bridge>
+ </interfaces>
+ </host>
+ <host id="guest1">
+ <interfaces>
+ <eth id="guestnic" label="to_guest" />
+ <vlan id="vlan10">
+ <options>
+ <option name="vlan_tci" value="10" />
+ </options>
+ <slaves>
+ <slave id="guestnic" />
+ </slaves>
+ <addresses>
+ <address>192.168.10.10/24</address>
+ </addresses>
+ </vlan>
+ </interfaces>
+ </host>
+ <host id="host2">
+ <interfaces>
+ <eth id="nic" label="to_switch" />
+ <vlan id="vlan10">
+ <options>
+ <option name="vlan_tci" value="10" />
+ </options>
+ <slaves>
+ <slave id="nic" />
+ </slaves>
+ <addresses>
+ <address>192.168.10.11/24</address>
+ </addresses>
+ </vlan>
+ </interfaces>
+ </host>
+ </network>
+
+ <task python="virtual_bridge_vlan_in_guest.py" />
+</lnstrecipe>
diff --git a/recipes/regression_tests/phase1/virtual_bridge_vlan_in_host.README b/recipes/regression_tests/phase1/virtual_bridge_vlan_in_host.README
new file mode 100644
index 0000000..9ab0b5a
--- /dev/null
+++ b/recipes/regression_tests/phase1/virtual_bridge_vlan_in_host.README
@@ -0,0 +1,52 @@
+Topology:
+
+ +----------+
+ | | VLAN10
+ +-----------------+ switch +-----------------+
+ | | | |
+ | +----------+ |
+ | |
+ +-+-+ |
++------|nic|------+ +-+-+
+| +-+-+ | +------|nic|------+
+| VLAN10 | | | +---+ |
+| +----+ | | |
+| | | | |
+| +-+-+ | | |
+| |br0| | | host2 |
+| +-+-+ host1 | | |
+| | | | |
+| +-+-+ | | |
++-|tap|-----------+ | |
+ +-+-+ +-----------------+
+ |
+ |
+ |
+ +-+-+
++-|nic|--+
+| +---+ |
+| guest1 |
+| |
++--------+
+
+Number of hosts: 3
+Host #1 description:
+ One ethernet device with one VLAN subinterface
+ One tap device
+ One bridge device, bridging VLAN and tap devices
+ Host for guest1 virtual machine
+Host #2 description:
+ One ethernet device with one VLAN subinterface
+Guest #1 description:
+ One ethernet device
+Test name:
+ virtual_bridge_vlan_in_guest.py
+Test description:
+ Ping:
+ + count: 100
+ + interval: 0.1s
+ + between guest1's NIC and host2's VLAN10
+ Netperf:
+ + duration: 60s
+ + TCP_STREAM and UDP_STREAM
+ + between guest1's NIC and host2's VLAN10
diff --git a/recipes/regression_tests/phase1/virtual_bridge_vlan_in_host.py b/recipes/regression_tests/phase1/virtual_bridge_vlan_in_host.py
new file mode 100644
index 0000000..4543387
--- /dev/null
+++ b/recipes/regression_tests/phase1/virtual_bridge_vlan_in_host.py
@@ -0,0 +1,66 @@
+from lnst.Controller.Task import ctl
+
+# ------
+# SETUP
+# ------
+
+h1 = ctl.get_host("host1")
+g1 = ctl.get_host("guest1")
+
+h2 = ctl.get_host("host2")
+
+g1.sync_resources(modules=["IcmpPing", "Netperf"])
+h2.sync_resources(modules=["IcmpPing", "Netperf"])
+
+# ------
+# TESTS
+# ------
+
+offloads = ["gso", "gro", "tso"]
+
+ping_mod = ctl.get_module("IcmpPing",
+ options={
+ "addr" : h2.get_ip("vlan10"),
+ "count" : 100,
+ "iface" : g1.get_devname("guestnic"),
+ "interval" : 0.1
+ })
+netperf_srv = ctl.get_module("Netperf",
+ options={
+ "role" : "server",
+ "bind" : g1.get_ip("guestnic")
+ })
+
+netperf_cli_tcp = ctl.get_module("Netperf",
+ options={
+ "role" : "client",
+ "netperf_server" : g1.get_ip("guestnic"),
+ "duration" : 60,
+ "testname" : "TCP_STREAM",
+ "netperf_opts" : "-L %s" %
+ h2.get_ip("vlan10")
+ })
+
+netperf_cli_udp = ctl.get_module("Netperf",
+ options={
+ "role" : "client",
+ "netperf_server" : g1.get_ip("guestnic"),
+ "duration" : 60,
+ "testname" : "UDP_STREAM",
+ "netperf_opts" : "-L %s" %
+ h2.get_ip("vlan10")
+ })
+
+for offload in offloads:
+ for state in ["on", "off"]:
+ g1.run("ethtool -K %s %s %s" % (g1.get_devname("guestnic"),
+ offload, state))
+ h2.run("ethtool -K %s %s %s" % (h2.get_devname("nic"),
+ offload, state))
+ g1.run(ping_mod)
+ server_proc = g1.run(netperf_srv, bg=True)
+ ctl.wait(2)
+ h2.run(netperf_cli_tcp, timeout=65)
+ h2.run(netperf_cli_udp, timeout=65)
+
+ server_proc.intr()
diff --git a/recipes/regression_tests/phase1/virtual_bridge_vlan_in_host.xml b/recipes/regression_tests/phase1/virtual_bridge_vlan_in_host.xml
new file mode 100644
index 0000000..5508c33
--- /dev/null
+++ b/recipes/regression_tests/phase1/virtual_bridge_vlan_in_host.xml
@@ -0,0 +1,54 @@
+<lnstrecipe>
+ <network>
+ <host id="host1">
+ <interfaces>
+ <eth id="nic" label="to_switch" />
+ <eth id="tap" label="to_guest" />
+ <vlan id="vlan10">
+ <options>
+ <option name="vlan_tci" value="10" />
+ </options>
+ <slaves>
+ <slave id="nic" />
+ </slaves>
+ </vlan>
+ <bridge id="br">
+ <slaves>
+ <slave id="tap" />
+ <slave id="vlan10" />
+ </slaves>
+ <addresses>
+ <address>192.168.10.1/24</address>
+ </addresses>
+ </bridge>
+ </interfaces>
+ </host>
+ <host id="guest1">
+ <interfaces>
+ <eth id="guestnic" label="to_guest">
+ <addresses>
+ <address>192.168.10.10/24</address>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ <host id="host2">
+ <interfaces>
+ <eth id="nic" label="to_switch" />
+ <vlan id="vlan10">
+ <options>
+ <option name="vlan_tci" value="10" />
+ </options>
+ <slaves>
+ <slave id="nic" />
+ </slaves>
+ <addresses>
+ <address>192.168.10.11/24</address>
+ </addresses>
+ </vlan>
+ </interfaces>
+ </host>
+ </network>
+
+ <task python="virtual_bridge_vlan_in_host.py" />
+</lnstrecipe>