This allows testing functionality that requires connectivity between
multiple bridges, such as bonding, LACP, and CFM.

This commit adds an example use to test basic LACP negotiation.

Signed-off-by: Ben Pfaff <b...@nicira.com>
---
 lib/netdev-dummy.c |   81 ++++++++++-
 tests/lacp.at      |  428 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 506 insertions(+), 3 deletions(-)

diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c
index 9b9e251..5636854 100644
--- a/lib/netdev-dummy.c
+++ b/lib/netdev-dummy.c
@@ -42,6 +42,7 @@ struct netdev_dev_dummy {
     struct netdev_stats stats;
     enum netdev_flags flags;
     unsigned int change_seq;
+    char *peer;
 
     struct list devs;           /* List of child "netdev_dummy"s. */
 };
@@ -67,6 +68,8 @@ static int netdev_dev_dummy_update_flags(struct 
netdev_dev_dummy *,
                                          enum netdev_flags off,
                                          enum netdev_flags on,
                                          enum netdev_flags *old_flagsp);
+static int netdev_dummy_queue_packet(struct netdev_dev_dummy *,
+                                     const void *data, size_t size);
 
 static bool
 is_dummy_class(const struct netdev_class *class)
@@ -125,10 +128,44 @@ netdev_dummy_destroy(struct netdev_dev *netdev_dev_)
 
     shash_find_and_delete(&dummy_netdev_devs,
                           netdev_dev_get_name(netdev_dev_));
+    free(netdev_dev->peer);
     free(netdev_dev);
 }
 
 static int
+netdev_dummy_set_config(struct netdev_dev *netdev_dev_,
+                        const struct smap *args)
+{
+    struct netdev_dev_dummy *netdev_dev = netdev_dev_dummy_cast(netdev_dev_);
+    const char *name = netdev_dev_get_name(netdev_dev_);
+    const struct smap_node *node;
+    const char *peer;
+
+    SMAP_FOR_EACH (node, args) {
+        if (strcmp(node->key, "peer")) {
+            VLOG_WARN("%s: unknown option '%s'", name, node->key);
+            return EINVAL;
+        }
+    }
+
+    free(netdev_dev->peer);
+    peer = smap_get(args, "peer");
+    netdev_dev->peer = peer ? xstrdup(peer) : NULL;
+    return 0;
+}
+
+static int
+netdev_dummy_get_config(struct netdev_dev *netdev_dev_, struct smap *args)
+{
+    struct netdev_dev_dummy *netdev_dev = netdev_dev_dummy_cast(netdev_dev_);
+
+    if (netdev_dev->peer) {
+        smap_add(args, "peer", netdev_dev->peer);
+    }
+    return 0;
+}
+
+static int
 netdev_dummy_open(struct netdev_dev *netdev_dev_, struct netdev **netdevp)
 {
     struct netdev_dev_dummy *netdev_dev = netdev_dev_dummy_cast(netdev_dev_);
@@ -205,6 +242,44 @@ netdev_dummy_drain(struct netdev *netdev_)
 }
 
 static int
+netdev_dummy_send(struct netdev *netdev, const void *buffer, size_t size)
+{
+    struct netdev_dev_dummy *dev =
+        netdev_dev_dummy_cast(netdev_get_dev(netdev));
+
+    if (size < ETH_HEADER_LEN) {
+        return EMSGSIZE;
+    } else {
+        const struct eth_header *eth = buffer;
+        int max_size;
+
+        max_size = dev->mtu + ETH_HEADER_LEN;
+        if (eth->eth_type == htons(ETH_TYPE_VLAN)) {
+            max_size += VLAN_HEADER_LEN;
+        }
+        if (size > max_size) {
+            return EMSGSIZE;
+        }
+    }
+
+    if (dev->peer) {
+        struct netdev_dev_dummy *peer;
+
+        peer = shash_find_data(&dummy_netdev_devs, dev->peer);
+        if (peer) {
+            netdev_dummy_queue_packet(peer, buffer, size);
+        } else {
+            static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
+
+            VLOG_INFO_RL(&rl, "%s: configured peer %s does not exist",
+                         netdev_get_name(netdev), dev->peer);
+        }
+    }
+
+    return 0;
+}
+
+static int
 netdev_dummy_set_etheraddr(struct netdev *netdev,
                            const uint8_t mac[ETH_ADDR_LEN])
 {
@@ -324,8 +399,8 @@ static const struct netdev_class dummy_class = {
 
     netdev_dummy_create,
     netdev_dummy_destroy,
-    NULL,                       /* get_config */
-    NULL,                       /* set_config */
+    netdev_dummy_get_config,
+    netdev_dummy_set_config,
 
     netdev_dummy_open,
     netdev_dummy_close,
@@ -335,7 +410,7 @@ static const struct netdev_class dummy_class = {
     netdev_dummy_recv_wait,
     netdev_dummy_drain,
 
-    NULL,                       /* send */
+    netdev_dummy_send,          /* send */
     NULL,                       /* send_wait */
 
     netdev_dummy_set_etheraddr,
diff --git a/tests/lacp.at b/tests/lacp.at
index d473d70..e9c1948 100644
--- a/tests/lacp.at
+++ b/tests/lacp.at
@@ -117,3 +117,431 @@ slave p2: disabled
 ])
 OVS_VSWITCHD_STOP
 AT_CLEANUP
+
+AT_SETUP([lacp - negotiation])
+# Create bond0 on br0 with interfaces p0 and p1
+#    and bond1 on br1 with interfaces p2 and p3
+# with p0 patched to p2 and p1 patched to p3.
+OVS_VSWITCHD_START(
+  [add-bond br0 bond0 p0 p1 bond_mode=balance-tcp lacp=active \
+                            other-config:lacp-time=fast \
+                            other-config:bond-rebalance-interval=0 -- \
+   set interface p0 type=dummy options:peer=p2 -- \
+   set interface p1 type=dummy options:peer=p3 -- \
+   add-br br1 -- \
+   set bridge br1 other-config:hwaddr=aa:66:aa:66:00:00 -- \
+   set bridge br1 datapath-type=dummy other-config:datapath-id=1234 \
+                  fail-mode=secure -- \
+   add-bond br1 bond1 p2 p3 bond_mode=balance-tcp lacp=active \
+                            other-config:lacp-time=fast \
+                            other-config:bond-rebalance-interval=0 -- \
+   set interface p2 type=dummy options:peer=p0 -- \
+   set interface p3 type=dummy options:peer=p1])
+
+AT_CHECK([ovs-appctl netdev-dummy/set-admin-state up], 0, [OK
+])
+
+# Wait for up to 5 (simulated) seconds, until LACP negotiation finishes.
+i=0
+while :; do
+    ovs-appctl lacp/show bond0 > bond0
+    AT_CAPTURE_FILE([bond0])
+    ovs-appctl lacp/show bond1 > bond1
+    AT_CAPTURE_FILE([bond1])
+    if grep negotiated bond0 && grep negotiated bond1; then
+        if grep expired bond0 || grep expired bond1; then
+            :
+        else
+            break
+        fi
+    fi
+    i=`expr $i + 1`
+    if test $i = 50; then
+        AT_FAIL_IF([:])
+    fi
+    ovs-appctl time/warp 100
+done
+
+# Now check the correctly negotiated configuration.
+AT_CHECK(
+  [ovs-appctl lacp/show bond0
+ovs-appctl lacp/show bond1
+ovs-appctl bond/show bond0
+ovs-appctl bond/show bond1], [0], [stdout])
+AT_CHECK([sed '/active slave/d' stdout], [0], [dnl
+---- bond0 ----
+       status: active negotiated
+       sys_id: aa:55:aa:55:00:00
+       sys_priority: 65534
+       aggregation key: 1
+       lacp_time: fast
+
+slave: p0: current attached
+       port_id: 2
+       port_priority: 65535
+       may_enable: true
+
+       actor sys_id: aa:55:aa:55:00:00
+       actor sys_priority: 65534
+       actor port_id: 2
+       actor port_priority: 65535
+       actor key: 1
+       actor state: activity timeout aggregation synchronized collecting 
distributing
+
+       partner sys_id: aa:66:aa:66:00:00
+       partner sys_priority: 65534
+       partner port_id: 2
+       partner port_priority: 65535
+       partner key: 2
+       partner state: activity timeout aggregation synchronized collecting 
distributing
+
+slave: p1: current attached
+       port_id: 1
+       port_priority: 65535
+       may_enable: true
+
+       actor sys_id: aa:55:aa:55:00:00
+       actor sys_priority: 65534
+       actor port_id: 1
+       actor port_priority: 65535
+       actor key: 1
+       actor state: activity timeout aggregation synchronized collecting 
distributing
+
+       partner sys_id: aa:66:aa:66:00:00
+       partner sys_priority: 65534
+       partner port_id: 3
+       partner port_priority: 65535
+       partner key: 2
+       partner state: activity timeout aggregation synchronized collecting 
distributing
+---- bond1 ----
+       status: active negotiated
+       sys_id: aa:66:aa:66:00:00
+       sys_priority: 65534
+       aggregation key: 2
+       lacp_time: fast
+
+slave: p2: current attached
+       port_id: 2
+       port_priority: 65535
+       may_enable: true
+
+       actor sys_id: aa:66:aa:66:00:00
+       actor sys_priority: 65534
+       actor port_id: 2
+       actor port_priority: 65535
+       actor key: 2
+       actor state: activity timeout aggregation synchronized collecting 
distributing
+
+       partner sys_id: aa:55:aa:55:00:00
+       partner sys_priority: 65534
+       partner port_id: 2
+       partner port_priority: 65535
+       partner key: 1
+       partner state: activity timeout aggregation synchronized collecting 
distributing
+
+slave: p3: current attached
+       port_id: 3
+       port_priority: 65535
+       may_enable: true
+
+       actor sys_id: aa:66:aa:66:00:00
+       actor sys_priority: 65534
+       actor port_id: 3
+       actor port_priority: 65535
+       actor key: 2
+       actor state: activity timeout aggregation synchronized collecting 
distributing
+
+       partner sys_id: aa:55:aa:55:00:00
+       partner sys_priority: 65534
+       partner port_id: 1
+       partner port_priority: 65535
+       partner key: 1
+       partner state: activity timeout aggregation synchronized collecting 
distributing
+---- bond0 ----
+bond_mode: balance-tcp
+bond-hash-basis: 0
+updelay: 0 ms
+downdelay: 0 ms
+lacp_status: negotiated
+
+slave p0: enabled
+       may_enable: true
+
+slave p1: enabled
+       may_enable: true
+
+---- bond1 ----
+bond_mode: balance-tcp
+bond-hash-basis: 0
+updelay: 0 ms
+downdelay: 0 ms
+lacp_status: negotiated
+
+slave p2: enabled
+       may_enable: true
+
+slave p3: enabled
+       may_enable: true
+
+])
+AT_CHECK([grep 'active slave' stdout], [0], [dnl
+       active slave
+       active slave
+])
+
+# Drop the patch link between p0 and p2, so that no packets get
+# back and forth across them anymore.  Then wait 4 simulated
+# seconds.  The LACP state should become "expired" for p0 and p2.
+AT_CHECK([ovs-vsctl remove interface p0 options peer -- \
+                    remove interface p2 options peer])
+for i in `seq 0 40`; do ovs-appctl time/warp 100; done
+AT_CHECK(
+  [ovs-appctl lacp/show bond0
+ovs-appctl lacp/show bond1
+ovs-appctl bond/show bond0
+ovs-appctl bond/show bond1], [0], [dnl
+---- bond0 ----
+       status: active negotiated
+       sys_id: aa:55:aa:55:00:00
+       sys_priority: 65534
+       aggregation key: 1
+       lacp_time: fast
+
+slave: p0: expired attached
+       port_id: 2
+       port_priority: 65535
+       may_enable: false
+
+       actor sys_id: aa:55:aa:55:00:00
+       actor sys_priority: 65534
+       actor port_id: 2
+       actor port_priority: 65535
+       actor key: 1
+       actor state: activity timeout aggregation synchronized collecting 
distributing expired
+
+       partner sys_id: aa:66:aa:66:00:00
+       partner sys_priority: 65534
+       partner port_id: 2
+       partner port_priority: 65535
+       partner key: 2
+       partner state: activity timeout aggregation collecting distributing
+
+slave: p1: current attached
+       port_id: 1
+       port_priority: 65535
+       may_enable: true
+
+       actor sys_id: aa:55:aa:55:00:00
+       actor sys_priority: 65534
+       actor port_id: 1
+       actor port_priority: 65535
+       actor key: 1
+       actor state: activity timeout aggregation synchronized collecting 
distributing
+
+       partner sys_id: aa:66:aa:66:00:00
+       partner sys_priority: 65534
+       partner port_id: 3
+       partner port_priority: 65535
+       partner key: 2
+       partner state: activity timeout aggregation synchronized collecting 
distributing
+---- bond1 ----
+       status: active negotiated
+       sys_id: aa:66:aa:66:00:00
+       sys_priority: 65534
+       aggregation key: 2
+       lacp_time: fast
+
+slave: p2: expired attached
+       port_id: 2
+       port_priority: 65535
+       may_enable: false
+
+       actor sys_id: aa:66:aa:66:00:00
+       actor sys_priority: 65534
+       actor port_id: 2
+       actor port_priority: 65535
+       actor key: 2
+       actor state: activity timeout aggregation synchronized collecting 
distributing expired
+
+       partner sys_id: aa:55:aa:55:00:00
+       partner sys_priority: 65534
+       partner port_id: 2
+       partner port_priority: 65535
+       partner key: 1
+       partner state: activity timeout aggregation collecting distributing
+
+slave: p3: current attached
+       port_id: 3
+       port_priority: 65535
+       may_enable: true
+
+       actor sys_id: aa:66:aa:66:00:00
+       actor sys_priority: 65534
+       actor port_id: 3
+       actor port_priority: 65535
+       actor key: 2
+       actor state: activity timeout aggregation synchronized collecting 
distributing
+
+       partner sys_id: aa:55:aa:55:00:00
+       partner sys_priority: 65534
+       partner port_id: 1
+       partner port_priority: 65535
+       partner key: 1
+       partner state: activity timeout aggregation synchronized collecting 
distributing
+---- bond0 ----
+bond_mode: balance-tcp
+bond-hash-basis: 0
+updelay: 0 ms
+downdelay: 0 ms
+lacp_status: negotiated
+
+slave p0: disabled
+       may_enable: false
+
+slave p1: enabled
+       active slave
+       may_enable: true
+
+---- bond1 ----
+bond_mode: balance-tcp
+bond-hash-basis: 0
+updelay: 0 ms
+downdelay: 0 ms
+lacp_status: negotiated
+
+slave p2: disabled
+       may_enable: false
+
+slave p3: enabled
+       active slave
+       may_enable: true
+
+])
+
+# Wait 4 more simulated seconds.  The LACP state should become
+# "defaulted" for p0 and p2.
+for i in `seq 0 40`; do ovs-appctl time/warp 100; done
+AT_CHECK(
+  [ovs-appctl lacp/show bond0
+ovs-appctl lacp/show bond1
+ovs-appctl bond/show bond0
+ovs-appctl bond/show bond1], [0], [dnl
+---- bond0 ----
+       status: active negotiated
+       sys_id: aa:55:aa:55:00:00
+       sys_priority: 65534
+       aggregation key: 1
+       lacp_time: fast
+
+slave: p0: defaulted detached
+       port_id: 2
+       port_priority: 65535
+       may_enable: false
+
+       actor sys_id: aa:55:aa:55:00:00
+       actor sys_priority: 65534
+       actor port_id: 2
+       actor port_priority: 65535
+       actor key: 1
+       actor state: activity timeout aggregation defaulted
+
+       partner sys_id: 00:00:00:00:00:00
+       partner sys_priority: 0
+       partner port_id: 0
+       partner port_priority: 0
+       partner key: 0
+       partner state:
+
+slave: p1: current attached
+       port_id: 1
+       port_priority: 65535
+       may_enable: true
+
+       actor sys_id: aa:55:aa:55:00:00
+       actor sys_priority: 65534
+       actor port_id: 1
+       actor port_priority: 65535
+       actor key: 1
+       actor state: activity timeout aggregation synchronized collecting 
distributing
+
+       partner sys_id: aa:66:aa:66:00:00
+       partner sys_priority: 65534
+       partner port_id: 3
+       partner port_priority: 65535
+       partner key: 2
+       partner state: activity timeout aggregation synchronized collecting 
distributing
+---- bond1 ----
+       status: active negotiated
+       sys_id: aa:66:aa:66:00:00
+       sys_priority: 65534
+       aggregation key: 2
+       lacp_time: fast
+
+slave: p2: defaulted detached
+       port_id: 2
+       port_priority: 65535
+       may_enable: false
+
+       actor sys_id: aa:66:aa:66:00:00
+       actor sys_priority: 65534
+       actor port_id: 2
+       actor port_priority: 65535
+       actor key: 2
+       actor state: activity timeout aggregation defaulted
+
+       partner sys_id: 00:00:00:00:00:00
+       partner sys_priority: 0
+       partner port_id: 0
+       partner port_priority: 0
+       partner key: 0
+       partner state:
+
+slave: p3: current attached
+       port_id: 3
+       port_priority: 65535
+       may_enable: true
+
+       actor sys_id: aa:66:aa:66:00:00
+       actor sys_priority: 65534
+       actor port_id: 3
+       actor port_priority: 65535
+       actor key: 2
+       actor state: activity timeout aggregation synchronized collecting 
distributing
+
+       partner sys_id: aa:55:aa:55:00:00
+       partner sys_priority: 65534
+       partner port_id: 1
+       partner port_priority: 65535
+       partner key: 1
+       partner state: activity timeout aggregation synchronized collecting 
distributing
+---- bond0 ----
+bond_mode: balance-tcp
+bond-hash-basis: 0
+updelay: 0 ms
+downdelay: 0 ms
+lacp_status: negotiated
+
+slave p0: disabled
+       may_enable: false
+
+slave p1: enabled
+       active slave
+       may_enable: true
+
+---- bond1 ----
+bond_mode: balance-tcp
+bond-hash-basis: 0
+updelay: 0 ms
+downdelay: 0 ms
+lacp_status: negotiated
+
+slave p2: disabled
+       may_enable: false
+
+slave p3: enabled
+       active slave
+       may_enable: true
+
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP
-- 
1.7.2.5

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to