In the tests, I think it's a good idea to manually set the
lacp-port-id and the lacp-aggregation-key in the database, because
those are arbitrarily generated by the switch.

Otherwise looks good, This is a huge win.  Thanks for doing this.

Ethan

On Fri, Aug 10, 2012 at 3:25 PM, Ben Pfaff <b...@nicira.com> wrote:
> 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 |   80 ++++++++++-
>  tests/lacp.at      |  430 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 507 insertions(+), 3 deletions(-)
>
> diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c
> index b64a932..cf6aa0c 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. */
>  };
> @@ -65,6 +66,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)
> @@ -127,6 +130,39 @@ netdev_dummy_destroy(struct netdev_dev *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_);
> @@ -203,6 +239,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_WARN_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])
>  {
> @@ -322,8 +396,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,
> @@ -333,7 +407,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 7d96143..44b1e15 100644
> --- a/tests/lacp.at
> +++ b/tests/lacp.at
> @@ -117,3 +117,433 @@ 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
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to