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