Thanks for the comments! I've applied the recommended style. Indeed, ofport_modified() in the first patch may reported wrong status - even if only for a short time. To avoid this, liveness handling at port state change has been moved out to port_modified() instead and port status update (connmgr_send_port_status()) is called only after that by update_port().
Please find the modified patch below - working fine for me. Thanks and regards Laszlo -----Original Message----- From: Ben Pfaff [mailto:b...@ovn.org] Sent: Friday, March 17, 2017 7:21 PM To: László Sürü <laszlo.s...@ericsson.com> Cc: ovs-dev@openvswitch.org Subject: Re: [ovs-dev] [PATCH] ofproto-dpif : propagate may_enable flag as link aliveness On Fri, Mar 03, 2017 at 01:00:05PM +0000, László Sürü wrote: > hereby I'm sending the implementation of link liveness propagation > functionality including the additional functionalities requested last year > (last activity at Wed Mar 16 23:13:24 UTC 2016). > > The idea is to use OFPPS_LIVE bit to propagate link aliveness state towards > the controller also when sending port status. > The ofport->may_enable flag could be used for this purpose, thus any change > in LIVE bit is propagated towards conrtoller in OFPT_PORT_STATUS message. > OFPPS_LIVE bit is set only when links is not down not administratively, > neither operationally as recommended in OF papers. > I added 9 new unit tests to verify link state changes when monitored with > cfm, bfd or lacp for OF 1.3, OF 1.4 and OF 1.5. > I updated related unit tests according to the changes of ofproto-dpif. Thanks a lot for the revision! I am a little concerned about ofport_modified(). It seems like this does not honor the status of protocols like BFD or CFM. I think this means that, if a port changes for any reason, liveness will initially ignore the status of these protocols, until the next time their status changes. That is probably not a good situation. Do you have any comments on that? I'm passing along an incremental I recommend folding into the next revision of the patch, to make it better fit the usual OVS coding style. (I do hope that the next revision will take less than a year!) Thanks, Ben. --8<--------------------------cut here-------------------------->8-- diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 523adad..95b283a 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -1894,6 +1894,16 @@ port_modified(struct ofport *port_) bfd_set_netdev(port->bfd, netdev); } + /* Set liveness, unless the link is administratively or + * operationally down or link monitoring false */ + if (!(port->up.pp.config & OFPUTIL_PC_PORT_DOWN) && + !(port->up.pp.state & OFPUTIL_PS_LINK_DOWN) && + (port->may_enable)) { + port->up.pp.state |= OFPUTIL_PS_LIVE; + } else { + port->up.pp.state &= ~OFPUTIL_PS_LIVE; + } + ofproto_dpif_monitor_port_update(port, port->bfd, port->cfm, port->lldp, &port->up.pp.hw_addr); @@ -3457,6 +3467,19 @@ port_run(struct ofport_dpif *ofport) if (ofport->rstp_port) { rstp_port_set_mac_operational(ofport->rstp_port, enable); } + + /* Propagate liveness, unless the link is administratively or + * operationally down. */ + if (!(ofport->up.pp.config & OFPUTIL_PC_PORT_DOWN) && + !(ofport->up.pp.state & OFPUTIL_PS_LINK_DOWN)) { + enum ofputil_port_state of_state = ofport->up.pp.state; + if (enable) { + of_state |= OFPUTIL_PS_LIVE; + } else { + of_state &= ~OFPUTIL_PS_LIVE; + } + ofproto_port_set_state(&ofport->up, of_state); + } } ofport->may_enable = enable; diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 84ea95b..6db9ec6 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -2470,9 +2470,6 @@ ofport_modified(struct ofport *port, struct ofputil_phy_port *pp) port->pp.peer = pp->peer; port->pp.curr_speed = pp->curr_speed; port->pp.max_speed = pp->max_speed; - - connmgr_send_port_status(port->ofproto->connmgr, NULL, - &port->pp, OFPPR_MODIFY); } /* Update OpenFlow 'state' in 'port' and notify controller. */ @@ -2616,6 +2613,7 @@ update_port(struct ofproto *ofproto, const char *name) struct netdev *netdev; struct ofport *port; int error = 0; + bool port_changed; COVERAGE_INC(ofproto_update_port); @@ -2630,7 +2628,7 @@ update_port(struct ofproto *ofproto, const char *name) struct netdev *old_netdev = port->netdev; /* 'name' hasn't changed location. Any properties changed? */ - if (!ofport_equal(&port->pp, &pp)) { + if ((port_changed = !ofport_equal(&port->pp, &pp))) { ofport_modified(port, &pp); } @@ -2646,6 +2644,12 @@ update_port(struct ofproto *ofproto, const char *name) port->ofproto->ofproto_class->port_modified(port); } + /* Send status update, if any port property changed */ + if (port_changed) { + connmgr_send_port_status(port->ofproto->connmgr, NULL, + &port->pp, OFPPR_MODIFY); + } + netdev_close(old_netdev); } else { /* If 'port' is nonnull then its name differs from 'name' and thus diff --git a/tests/bfd.at b/tests/bfd.at index dee8124..81c7db2 100644 --- a/tests/bfd.at +++ b/tests/bfd.at @@ -830,3 +830,222 @@ BFD_CHECK([p1], [false], [false], [none], [down], [Control Detection Time Expire OVS_VSWITCHD_STOP AT_CLEANUP + +# test bfd: liveness propagation - OF1.3. +AT_SETUP([bfd - liveness propagation - OF1.3]) +OVS_VSWITCHD_START +AT_CHECK([ovs-ofctl -O OpenFlow13 -P standard monitor br0 --detach --no-chdir --pidfile]) +check_liveness () { + printf '\n\n--- check_liveness %d ---\n\n\n' $1 + shift + + echo >>expout "OFPT_PORT_STATUS (OF1.3): MOD: 1(p0): addr: + config: 0 + state: $1 + speed: 0 Mbps now, 0 Mbps max" + + AT_CHECK( + [[sed ' +s/ (xid=0x[0-9a-fA-F]*)// +s/ *duration.*// +s/addr:[0-9a-fA-F:]*/addr:/' < monitor.log|grep --no-group-separator -A3 "MOD: 1(p0)"]], + [0], [expout]) +} +: > expout +ovs-appctl -t ovs-ofctl ofctl/barrier +ovs-appctl -t ovs-ofctl ofctl/set-output-file monitor.log +# Set miss_send_len to 128, enabling port_status messages to our service connection. +ovs-appctl -t ovs-ofctl ofctl/send 0409000c0123456700000080 +#Create 2 bridges connected by patch ports and enable bfd +AT_CHECK([ovs-vsctl add-br br1 -- \ + set bridge br1 datapath-type=dummy \ + other-config:hwaddr=aa:55:aa:56:00:00 -- \ + add-port br1 p1 -- set Interface p1 type=patch \ + options:peer=p0 ofport_request=2 -- \ + add-port br0 p0 -- set Interface p0 type=patch \ + options:peer=p1 ofport_request=1]) + +AT_CHECK([ovs-vsctl \ + set Interface p0 bfd:enable=true bfd:min_tx=100 bfd:min_rx=100 -- \ + set Interface p1 bfd:enable=true bfd:min_tx=100 bfd:min_rx=100]) + +ovs-appctl time/stop +# Disable the stats update to prevent the race between ovsdb updating +# stats and ovs-vsctl cmd closing the jsonrpc session. +AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:stats-update-interval=50000000]) + +# wait for a while to stablize bfd. +ovs-appctl time/warp 10100 100 +BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) +BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) +BFD_CHECK_TX([p0], [100ms], [100ms], [100ms]) +BFD_CHECK_RX([p0], [100ms], [100ms], [100ms]) +# both p0 and p1 should have flap_count = "1". since down->up. +BFD_VSCTL_LIST_IFACE([p0], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["1"]) +BFD_VSCTL_LIST_IFACE([p1], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["1"]) +check_liveness 1 LIVE + +# turn bfd on p1 off, should increment the bfd:flap_count on p0. +AT_CHECK([ovs-vsctl set interface p1 bfd:enable=false]) +ovs-appctl time/warp 5000 100 +BFD_CHECK([p0], [false], [false], [none], [down], [Control Detection Time Expired], [none], [down], [No Diagnostic]) +BFD_VSCTL_LIST_IFACE([p0], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["2"]) +AT_CHECK([ovs-vsctl list interface p1 | sed -n "s/^.*flap_count=\(.*\), forwarding.*$/\1/p"]) +check_liveness 2 0 + +# turn bfd on p1 on again, should increment the bfd:flap_count on p0. +# p1 should still have flap_count = "1", since it is reset. +AT_CHECK([ovs-vsctl set interface p1 bfd:enable=true]) +ovs-appctl time/warp 5000 100 +BFD_VSCTL_LIST_IFACE([p0], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["3"]) +BFD_VSCTL_LIST_IFACE([p1], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["1"]) +check_liveness 3 LIVE + +OVS_VSWITCHD_STOP +AT_CLEANUP + +# test bfd: liveness propagation - OF1.4. +AT_SETUP([bfd - liveness propagation - OF1.4]) +OVS_VSWITCHD_START +AT_CHECK([ovs-ofctl -O OpenFlow14 -P standard monitor br0 --detach --no-chdir --pidfile]) +check_liveness () { + printf '\n\n--- check_liveness %d ---\n\n\n' $1 + shift + + echo >>expout "OFPT_PORT_STATUS (OF1.4): MOD: 1(p0): addr: + config: 0 + state: $1 + speed: 0 Mbps now, 0 Mbps max" + + AT_CHECK( + [[sed ' +s/ (xid=0x[0-9a-fA-F]*)// +s/ *duration.*// +s/addr:[0-9a-fA-F:]*/addr:/' < monitor.log|grep --no-group-separator -A3 "MOD: 1(p0)"]], + [0], [expout]) +} +: > expout +ovs-appctl -t ovs-ofctl ofctl/barrier +ovs-appctl -t ovs-ofctl ofctl/set-output-file monitor.log +# Set miss_send_len to 128, enabling port_status messages to our service connection. +ovs-appctl -t ovs-ofctl ofctl/send 0509000c0123456700000080 +#Create 2 bridges connected by patch ports and enable bfd +AT_CHECK([ovs-vsctl add-br br1 -- \ + set bridge br1 datapath-type=dummy \ + other-config:hwaddr=aa:55:aa:56:00:00 -- \ + add-port br1 p1 -- set Interface p1 type=patch \ + options:peer=p0 ofport_request=2 -- \ + add-port br0 p0 -- set Interface p0 type=patch \ + options:peer=p1 ofport_request=1]) + +AT_CHECK([ovs-vsctl \ + set Interface p0 bfd:enable=true bfd:min_tx=100 bfd:min_rx=100 -- \ + set Interface p1 bfd:enable=true bfd:min_tx=100 bfd:min_rx=100]) + +ovs-appctl time/stop +# Disable the stats update to prevent the race between ovsdb updating +# stats and ovs-vsctl cmd closing the jsonrpc session. +AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:stats-update-interval=50000000]) + +# wait for a while to stablize bfd. +ovs-appctl time/warp 10100 100 +BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) +BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) +BFD_CHECK_TX([p0], [100ms], [100ms], [100ms]) +BFD_CHECK_RX([p0], [100ms], [100ms], [100ms]) +# both p0 and p1 should have flap_count = "1". since down->up. +BFD_VSCTL_LIST_IFACE([p0], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["1"]) +BFD_VSCTL_LIST_IFACE([p1], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["1"]) +check_liveness 1 LIVE + +# turn bfd on p1 off, should increment the bfd:flap_count on p0. +AT_CHECK([ovs-vsctl set interface p1 bfd:enable=false]) +ovs-appctl time/warp 5000 100 +BFD_CHECK([p0], [false], [false], [none], [down], [Control Detection Time Expired], [none], [down], [No Diagnostic]) +BFD_VSCTL_LIST_IFACE([p0], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["2"]) +AT_CHECK([ovs-vsctl list interface p1 | sed -n "s/^.*flap_count=\(.*\), forwarding.*$/\1/p"]) +check_liveness 2 0 + +# turn bfd on p1 on again, should increment the bfd:flap_count on p0. +# p1 should still have flap_count = "1", since it is reset. +AT_CHECK([ovs-vsctl set interface p1 bfd:enable=true]) +ovs-appctl time/warp 5000 100 +BFD_VSCTL_LIST_IFACE([p0], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["3"]) +BFD_VSCTL_LIST_IFACE([p1], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["1"]) +check_liveness 3 LIVE + +OVS_VSWITCHD_STOP +AT_CLEANUP + +# test bfd: liveness propagation - OF1.5. +AT_SETUP([bfd - liveness propagation - OF1.5]) +OVS_VSWITCHD_START +AT_CHECK([ovs-ofctl -O OpenFlow15 -P standard monitor br0 --detach --no-chdir --pidfile]) +check_liveness () { + printf '\n\n--- check_liveness %d ---\n\n\n' $1 + shift + + echo >>expout "OFPT_PORT_STATUS (OF1.5): MOD: 1(p0): addr: + config: 0 + state: $1 + speed: 0 Mbps now, 0 Mbps max" + + AT_CHECK( + [[sed ' +s/ (xid=0x[0-9a-fA-F]*)// +s/ *duration.*// +s/addr:[0-9a-fA-F:]*/addr:/' < monitor.log|grep --no-group-separator -A3 "MOD: 1(p0)"]], + [0], [expout]) +} +: > expout +ovs-appctl -t ovs-ofctl ofctl/barrier +ovs-appctl -t ovs-ofctl ofctl/set-output-file monitor.log +# Set miss_send_len to 128, enabling port_status messages to our service connection. +ovs-appctl -t ovs-ofctl ofctl/send 0609000c0123456700000080 +#Create 2 bridges connected by patch ports and enable bfd +AT_CHECK([ovs-vsctl add-br br1 -- \ + set bridge br1 datapath-type=dummy \ + other-config:hwaddr=aa:55:aa:56:00:00 -- \ + add-port br1 p1 -- set Interface p1 type=patch \ + options:peer=p0 ofport_request=2 -- \ + add-port br0 p0 -- set Interface p0 type=patch \ + options:peer=p1 ofport_request=1]) + +AT_CHECK([ovs-vsctl \ + set Interface p0 bfd:enable=true bfd:min_tx=100 bfd:min_rx=100 -- \ + set Interface p1 bfd:enable=true bfd:min_tx=100 bfd:min_rx=100]) + +ovs-appctl time/stop +# Disable the stats update to prevent the race between ovsdb updating +# stats and ovs-vsctl cmd closing the jsonrpc session. +AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:stats-update-interval=50000000]) + +# wait for a while to stablize bfd. +ovs-appctl time/warp 10100 100 +BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) +BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) +BFD_CHECK_TX([p0], [100ms], [100ms], [100ms]) +BFD_CHECK_RX([p0], [100ms], [100ms], [100ms]) +# both p0 and p1 should have flap_count = "1". since down->up. +BFD_VSCTL_LIST_IFACE([p0], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["1"]) +BFD_VSCTL_LIST_IFACE([p1], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["1"]) +check_liveness 1 LIVE + +# turn bfd on p1 off, should increment the bfd:flap_count on p0. +AT_CHECK([ovs-vsctl set interface p1 bfd:enable=false]) +ovs-appctl time/warp 5000 100 +BFD_CHECK([p0], [false], [false], [none], [down], [Control Detection Time Expired], [none], [down], [No Diagnostic]) +BFD_VSCTL_LIST_IFACE([p0], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["2"]) +AT_CHECK([ovs-vsctl list interface p1 | sed -n "s/^.*flap_count=\(.*\), forwarding.*$/\1/p"]) +check_liveness 2 0 + +# turn bfd on p1 on again, should increment the bfd:flap_count on p0. +# p1 should still have flap_count = "1", since it is reset. +AT_CHECK([ovs-vsctl set interface p1 bfd:enable=true]) +ovs-appctl time/warp 5000 100 +BFD_VSCTL_LIST_IFACE([p0], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["3"]) +BFD_VSCTL_LIST_IFACE([p1], ["s/^.*flap_count=\(.*\), forwarding.*$/\1/p"], ["1"]) +check_liveness 3 LIVE + +OVS_VSWITCHD_STOP +AT_CLEANUP diff --git a/tests/cfm.at b/tests/cfm.at index d951475..9349268 100644 --- a/tests/cfm.at +++ b/tests/cfm.at @@ -319,3 +319,189 @@ CFM_CHECK_EXTENDED_FAULT([p0], [1], [recv], [0], [up], [up], [300ms]) OVS_VSWITCHD_STOP AT_CLEANUP + +# test cfm liveness propagation - OF1.3. +AT_SETUP([cfm - liveness propagation - OF1.3]) +OVS_VSWITCHD_START +AT_CHECK([ovs-ofctl -O OpenFlow13 -P standard monitor br0 --detach --no-chdir --pidfile]) +check_liveness () { + printf '\n\n--- check_liveness %d ---\n\n\n' $1 + shift + + echo >>expout "OFPT_PORT_STATUS (OF1.3): MOD: 1(p0): addr: + config: 0 + state: $1 + speed: 0 Mbps now, 0 Mbps max" + + AT_CHECK( + [[sed ' +s/ (xid=0x[0-9a-fA-F]*)// +s/ *duration.*// +s/addr:[0-9a-fA-F:]*/addr:/' < monitor.log|grep --no-group-separator -A3 "MOD: 1(p0)"]], + [0], [expout]) +} +: > expout +ovs-appctl -t ovs-ofctl ofctl/barrier +ovs-appctl -t ovs-ofctl ofctl/set-output-file monitor.log +# Set miss_send_len to 128, enabling port_status messages to our service connection. +ovs-appctl -t ovs-ofctl ofctl/send 0409000c0123456700000080 + +#Create 2 bridges connected by patch ports and enable cfm +AT_CHECK([ovs-vsctl add-br br1 -- \ + set bridge br1 datapath-type=dummy \ + other-config:hwaddr=aa:55:aa:56:00:00 -- \ + add-port br1 p1 -- set Interface p1 type=patch \ + options:peer=p0 -- \ + add-port br0 p0 -- set Interface p0 type=patch \ + options:peer=p1]) +check_liveness 1 LIVE + +AT_CHECK([ovs-vsctl \ + set Interface p0 cfm_mpid=1 other_config:cfm_interval=100 other_config:cfm_extended=true -- \ + set Interface p1 cfm_mpid=2 other_config:cfm_interval=100 other_config:cfm_extended=true]) +ovs-appctl time/stop +# wait for a while to stablize cfm. +ovs-appctl time/warp 10100 100 +CFM_CHECK_EXTENDED([p0], [1], [100], [up], [up], [100ms], [2], [up]) +CFM_CHECK_EXTENDED([p1], [2], [100], [up], [up], [100ms], [1], [up]) + +# turn cfm on p1 off, should increment the cfm_flap_count on p0. +AT_CHECK([ovs-vsctl remove interface p1 cfm_mpid 2]) +ovs-appctl time/warp 1100 100 +CFM_VSCTL_LIST_IFACE([p0], [cfm_flap_count], [cfm_flap_count : 1]) +CFM_VSCTL_LIST_IFACE([p1], [cfm_flap_count], [cfm_flap_count : [[]]]) +check_liveness 2 0 + +# turn cfm on p1 on again, should increment the cfm_flap_count on p0. +AT_CHECK([ovs-vsctl set interface p1 cfm_mpid=2]) +ovs-appctl time/warp 1100 100 +check_liveness 3 LIVE + +CFM_VSCTL_LIST_IFACE([p0], [cfm_flap_count], [cfm_flap_count : 2]) + +OVS_VSWITCHD_STOP +AT_CLEANUP + +# test cfm liveness propagation - OF1.4. +AT_SETUP([cfm - liveness propagation - OF1.4]) +OVS_VSWITCHD_START +AT_CHECK([ovs-ofctl -O OpenFlow14 -P standard monitor br0 --detach --no-chdir --pidfile]) +check_liveness () { + printf '\n\n--- check_liveness %d ---\n\n\n' $1 + shift + + echo >>expout "OFPT_PORT_STATUS (OF1.4): MOD: 1(p0): addr: + config: 0 + state: $1 + speed: 0 Mbps now, 0 Mbps max" + + AT_CHECK( + [[sed ' +s/ (xid=0x[0-9a-fA-F]*)// +s/ *duration.*// +s/addr:[0-9a-fA-F:]*/addr:/' < monitor.log|grep --no-group-separator -A3 "MOD: 1(p0)"]], + [0], [expout]) +} +: > expout +ovs-appctl -t ovs-ofctl ofctl/barrier +ovs-appctl -t ovs-ofctl ofctl/set-output-file monitor.log +# Set miss_send_len to 128, enabling port_status messages to our service connection. +ovs-appctl -t ovs-ofctl ofctl/send 0509000c0123456700000080 + +#Create 2 bridges connected by patch ports and enable cfm +AT_CHECK([ovs-vsctl add-br br1 -- \ + set bridge br1 datapath-type=dummy \ + other-config:hwaddr=aa:55:aa:56:00:00 -- \ + add-port br1 p1 -- set Interface p1 type=patch \ + options:peer=p0 -- \ + add-port br0 p0 -- set Interface p0 type=patch \ + options:peer=p1]) +check_liveness 1 LIVE + +AT_CHECK([ovs-vsctl \ + set Interface p0 cfm_mpid=1 other_config:cfm_interval=100 other_config:cfm_extended=true -- \ + set Interface p1 cfm_mpid=2 other_config:cfm_interval=100 other_config:cfm_extended=true]) +ovs-appctl time/stop +# wait for a while to stablize cfm. +ovs-appctl time/warp 10100 100 +CFM_CHECK_EXTENDED([p0], [1], [100], [up], [up], [100ms], [2], [up]) +CFM_CHECK_EXTENDED([p1], [2], [100], [up], [up], [100ms], [1], [up]) + +# turn cfm on p1 off, should increment the cfm_flap_count on p0. +AT_CHECK([ovs-vsctl remove interface p1 cfm_mpid 2]) +ovs-appctl time/warp 1100 100 +CFM_VSCTL_LIST_IFACE([p0], [cfm_flap_count], [cfm_flap_count : 1]) +CFM_VSCTL_LIST_IFACE([p1], [cfm_flap_count], [cfm_flap_count : [[]]]) +check_liveness 2 0 + +# turn cfm on p1 on again, should increment the cfm_flap_count on p0. +AT_CHECK([ovs-vsctl set interface p1 cfm_mpid=2]) +ovs-appctl time/warp 1100 100 +check_liveness 3 LIVE + +CFM_VSCTL_LIST_IFACE([p0], [cfm_flap_count], [cfm_flap_count : 2]) + +OVS_VSWITCHD_STOP +AT_CLEANUP + +# test cfm liveness propagation - OF1.5. +AT_SETUP([cfm - liveness propagation - OF1.5]) +OVS_VSWITCHD_START +AT_CHECK([ovs-ofctl -O OpenFlow15 -P standard monitor br0 --detach --no-chdir --pidfile]) +check_liveness () { + printf '\n\n--- check_liveness %d ---\n\n\n' $1 + shift + + echo >>expout "OFPT_PORT_STATUS (OF1.5): MOD: 1(p0): addr: + config: 0 + state: $1 + speed: 0 Mbps now, 0 Mbps max" + + AT_CHECK( + [[sed ' +s/ (xid=0x[0-9a-fA-F]*)// +s/ *duration.*// +s/addr:[0-9a-fA-F:]*/addr:/' < monitor.log|grep --no-group-separator -A3 "MOD: 1(p0)"]], + [0], [expout]) +} +: > expout +ovs-appctl -t ovs-ofctl ofctl/barrier +ovs-appctl -t ovs-ofctl ofctl/set-output-file monitor.log +# Set miss_send_len to 128, enabling port_status messages to our service connection. +ovs-appctl -t ovs-ofctl ofctl/send 0609000c0123456700000080 + +#Create 2 bridges connected by patch ports and enable cfm +AT_CHECK([ovs-vsctl add-br br1 -- \ + set bridge br1 datapath-type=dummy \ + other-config:hwaddr=aa:55:aa:56:00:00 -- \ + add-port br1 p1 -- set Interface p1 type=patch \ + options:peer=p0 -- \ + add-port br0 p0 -- set Interface p0 type=patch \ + options:peer=p1]) +check_liveness 1 LIVE + +AT_CHECK([ovs-vsctl \ + set Interface p0 cfm_mpid=1 other_config:cfm_interval=100 other_config:cfm_extended=true -- \ + set Interface p1 cfm_mpid=2 other_config:cfm_interval=100 other_config:cfm_extended=true]) +ovs-appctl time/stop +# wait for a while to stablize cfm. +ovs-appctl time/warp 10100 100 +CFM_CHECK_EXTENDED([p0], [1], [100], [up], [up], [100ms], [2], [up]) +CFM_CHECK_EXTENDED([p1], [2], [100], [up], [up], [100ms], [1], [up]) + +# turn cfm on p1 off, should increment the cfm_flap_count on p0. +AT_CHECK([ovs-vsctl remove interface p1 cfm_mpid 2]) +ovs-appctl time/warp 1100 100 +CFM_VSCTL_LIST_IFACE([p0], [cfm_flap_count], [cfm_flap_count : 1]) +CFM_VSCTL_LIST_IFACE([p1], [cfm_flap_count], [cfm_flap_count : [[]]]) +check_liveness 2 0 + +# turn cfm on p1 on again, should increment the cfm_flap_count on p0. +AT_CHECK([ovs-vsctl set interface p1 cfm_mpid=2]) +ovs-appctl time/warp 1100 100 +check_liveness 3 LIVE + +CFM_VSCTL_LIST_IFACE([p0], [cfm_flap_count], [cfm_flap_count : 2]) + +OVS_VSWITCHD_STOP +AT_CLEANUP diff --git a/tests/lacp.at b/tests/lacp.at index 20ec09e..2b8adf3 100644 --- a/tests/lacp.at +++ b/tests/lacp.at @@ -726,3 +726,291 @@ slave p3: enabled OVS_VSWITCHD_STOP AT_CLEANUP + +# test lacp liveness propagation - OF1.3. +AT_SETUP([lacp - liveness propagation - OF1.3]) +OVS_VSWITCHD_START +AT_CHECK([ovs-ofctl -O OpenFlow13 -P standard monitor br0 --detach --no-chdir --pidfile]) +check_liveness () { + printf '\n\n--- check_liveness %d ---\n\n\n' $1 + shift + + echo >>expout "OFPT_PORT_STATUS (OF1.3): MOD: 1(p0): addr: + config: 0 + state: $1 + speed: 0 Mbps now, 0 Mbps max" + + AT_CHECK( + [[sed ' +s/ (xid=0x[0-9a-fA-F]*)// +s/ *duration.*// +s/addr:[0-9a-fA-F:]*/addr:/' < monitor.log|grep --no-group-separator -A3 "MOD: 1(p0)"]], + [0], [expout]) +} +: > expout +ovs-appctl -t ovs-ofctl ofctl/barrier +ovs-appctl -t ovs-ofctl ofctl/set-output-file monitor.log +# Set miss_send_len to 128, enabling port_status messages to our service connection. +ovs-appctl -t ovs-ofctl ofctl/send 0409000c0123456700000080 + +# 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. +AT_CHECK([ovs-vsctl 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=patch options:peer=p2 ofport_request=1 \ + other-config:lacp-aggregation-key=2 -- \ + set interface p1 type=patch options:peer=p3 ofport_request=2 \ + other-config:lacp-aggregation-key=2 -- \ + 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=patch options:peer=p0 ofport_request=3 \ + other-config:lacp-aggregation-key=4 -- \ + set interface p3 type=patch options:peer=p1 ofport_request=4 \ + other-config:lacp-aggregation-key=4 --]) + +AT_CHECK([ovs-appctl netdev-dummy/set-admin-state up], 0, [OK +]) +ovs-appctl time/stop + +# 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 +check_liveness 1 LIVE + +# Makes LACP state "expired" for p0 and p2. +AT_CHECK([ovs-vsctl \ +-- add-port br0 null0 -- set int null0 type=patch options:peer=p2 -- set int p2 options:peer=null0 \ +-- add-port br1 null1 -- set int null1 type=patch options:peer=p0 -- set int p0 options:peer=null1]) +check_liveness 2 LIVE + +# Wait 4 more simulated seconds. The LACP state should become "defaulted" for p0 and p2. +ovs-appctl time/warp 4100 100 +check_liveness 3 0 + +# Reconnect the patch link between p0 and p2 to allow traffic between the ports. +AT_CHECK([ovs-vsctl \ +-- del-port null0 -- set int p2 options:peer=p0 \ +-- del-port null1 -- set int p0 options:peer=p2]) + +# Wait for 30 more seconds (LACP_SLOW_TIME_TX) for the lacp to renegotiate +ovs-appctl time/warp 30100 100 +check_liveness 3 LIVE + +OVS_VSWITCHD_STOP +AT_CLEANUP + +# test lacp liveness propagation - OF1.4. +AT_SETUP([lacp - liveness propagation - OF1.4]) +OVS_VSWITCHD_START +AT_CHECK([ovs-ofctl -O OpenFlow14 -P standard monitor br0 --detach --no-chdir --pidfile]) +check_liveness () { + printf '\n\n--- check_liveness %d ---\n\n\n' $1 + shift + + echo >>expout "OFPT_PORT_STATUS (OF1.4): MOD: 1(p0): addr: + config: 0 + state: $1 + speed: 0 Mbps now, 0 Mbps max" + + AT_CHECK( + [[sed ' +s/ (xid=0x[0-9a-fA-F]*)// +s/ *duration.*// +s/addr:[0-9a-fA-F:]*/addr:/' < monitor.log|grep --no-group-separator -A3 "MOD: 1(p0)"]], + [0], [expout]) +} +: > expout +ovs-appctl -t ovs-ofctl ofctl/barrier +ovs-appctl -t ovs-ofctl ofctl/set-output-file monitor.log +# Set miss_send_len to 128, enabling port_status messages to our service connection. +ovs-appctl -t ovs-ofctl ofctl/send 0509000c0123456700000080 + +# 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. +AT_CHECK([ovs-vsctl 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=patch options:peer=p2 ofport_request=1 \ + other-config:lacp-aggregation-key=2 -- \ + set interface p1 type=patch options:peer=p3 ofport_request=2 \ + other-config:lacp-aggregation-key=2 -- \ + 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=patch options:peer=p0 ofport_request=3 \ + other-config:lacp-aggregation-key=4 -- \ + set interface p3 type=patch options:peer=p1 ofport_request=4 \ + other-config:lacp-aggregation-key=4 --]) + +AT_CHECK([ovs-appctl netdev-dummy/set-admin-state up], 0, [OK +]) +ovs-appctl time/stop + +# 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 +check_liveness 1 LIVE + +# Makes LACP state "expired" for p0 and p2. +AT_CHECK([ovs-vsctl \ +-- add-port br0 null0 -- set int null0 type=patch options:peer=p2 -- set int p2 options:peer=null0 \ +-- add-port br1 null1 -- set int null1 type=patch options:peer=p0 -- set int p0 options:peer=null1]) +check_liveness 2 LIVE + +# Wait 4 more simulated seconds. The LACP state should become "defaulted" for p0 and p2. +ovs-appctl time/warp 4100 100 +check_liveness 3 0 + +# Reconnect the patch link between p0 and p2 to allow traffic between the ports. +AT_CHECK([ovs-vsctl \ +-- del-port null0 -- set int p2 options:peer=p0 \ +-- del-port null1 -- set int p0 options:peer=p2]) + +# Wait for 30 more seconds (LACP_SLOW_TIME_TX) for the lacp to renegotiate +ovs-appctl time/warp 30100 100 +check_liveness 3 LIVE + +OVS_VSWITCHD_STOP +AT_CLEANUP + +# test lacp liveness propagation - OF1.5. +AT_SETUP([lacp - liveness propagation - OF1.5]) +OVS_VSWITCHD_START +AT_CHECK([ovs-ofctl -O OpenFlow15 -P standard monitor br0 --detach --no-chdir --pidfile]) +check_liveness () { + printf '\n\n--- check_liveness %d ---\n\n\n' $1 + shift + + echo >>expout "OFPT_PORT_STATUS (OF1.5): MOD: 1(p0): addr: + config: 0 + state: $1 + speed: 0 Mbps now, 0 Mbps max" + + AT_CHECK( + [[sed ' +s/ (xid=0x[0-9a-fA-F]*)// +s/ *duration.*// +s/addr:[0-9a-fA-F:]*/addr:/' < monitor.log|grep --no-group-separator -A3 "MOD: 1(p0)"]], + [0], [expout]) +} +: > expout +ovs-appctl -t ovs-ofctl ofctl/barrier +ovs-appctl -t ovs-ofctl ofctl/set-output-file monitor.log +# Set miss_send_len to 128, enabling port_status messages to our service connection. +ovs-appctl -t ovs-ofctl ofctl/send 0609000c0123456700000080 + +# 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. +AT_CHECK([ovs-vsctl 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=patch options:peer=p2 ofport_request=1 \ + other-config:lacp-aggregation-key=2 -- \ + set interface p1 type=patch options:peer=p3 ofport_request=2 \ + other-config:lacp-aggregation-key=2 -- \ + 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=patch options:peer=p0 ofport_request=3 \ + other-config:lacp-aggregation-key=4 -- \ + set interface p3 type=patch options:peer=p1 ofport_request=4 \ + other-config:lacp-aggregation-key=4 --]) + +AT_CHECK([ovs-appctl netdev-dummy/set-admin-state up], 0, [OK +]) +ovs-appctl time/stop + +# 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 +check_liveness 1 LIVE + +# Makes LACP state "expired" for p0 and p2. +AT_CHECK([ovs-vsctl \ +-- add-port br0 null0 -- set int null0 type=patch options:peer=p2 -- set int p2 options:peer=null0 \ +-- add-port br1 null1 -- set int null1 type=patch options:peer=p0 -- set int p0 options:peer=null1]) +check_liveness 2 LIVE + +# Wait 4 more simulated seconds. The LACP state should become "defaulted" for p0 and p2. +ovs-appctl time/warp 4100 100 +check_liveness 3 0 + +# Reconnect the patch link between p0 and p2 to allow traffic between the ports. +AT_CHECK([ovs-vsctl \ +-- del-port null0 -- set int p2 options:peer=p0 \ +-- del-port null1 -- set int p0 options:peer=p2]) + +# Wait for 30 more seconds (LACP_SLOW_TIME_TX) for the lacp to renegotiate +ovs-appctl time/warp 30100 100 +check_liveness 3 LIVE + +OVS_VSWITCHD_STOP +AT_CLEANUP diff --git a/tests/ofproto.at b/tests/ofproto.at index b1ce712..9386f95 100644 --- a/tests/ofproto.at +++ b/tests/ofproto.at @@ -1194,15 +1194,15 @@ AT_CLEANUP AT_SETUP([ofproto - mod-port (OpenFlow 1.2)]) OVS_VSWITCHD_START for command_config_state in \ - 'up 0 0' \ + 'up 0 LIVE' \ 'down PORT_DOWN LINK_DOWN' \ 'no-receive PORT_DOWN,NO_RECV LINK_DOWN' \ 'no-forward PORT_DOWN,NO_RECV,NO_FWD LINK_DOWN' \ 'no-packet-in PORT_DOWN,NO_RECV,NO_FWD,NO_PACKET_IN LINK_DOWN' \ 'forward PORT_DOWN,NO_RECV,NO_PACKET_IN LINK_DOWN' \ 'packet-in PORT_DOWN,NO_RECV LINK_DOWN' \ - 'up NO_RECV 0' \ - 'receive 0 0' + 'up NO_RECV LIVE' \ + 'receive 0 LIVE' do set $command_config_state command=$[1] config=`echo $[2] | sed 's/,/ /g'` state=$[3] @@ -1225,15 +1225,15 @@ AT_CLEANUP AT_SETUP([ofproto - mod-port (OpenFlow 1.4)]) OVS_VSWITCHD_START for command_config_state in \ - 'up 0 0' \ + 'up 0 LIVE' \ 'down PORT_DOWN LINK_DOWN' \ 'no-receive PORT_DOWN,NO_RECV LINK_DOWN' \ 'no-forward PORT_DOWN,NO_RECV,NO_FWD LINK_DOWN' \ 'no-packet-in PORT_DOWN,NO_RECV,NO_FWD,NO_PACKET_IN LINK_DOWN' \ 'forward PORT_DOWN,NO_RECV,NO_PACKET_IN LINK_DOWN' \ 'packet-in PORT_DOWN,NO_RECV LINK_DOWN' \ - 'up NO_RECV 0' \ - 'receive 0 0' + 'up NO_RECV LIVE' \ + 'receive 0 LIVE' do set $command_config_state command=$[1] config=`echo $[2] | sed 's/,/ /g'` state=$[3] @@ -3454,7 +3454,7 @@ udp,vlan_tci=0x0000,dl_src=00:26:b9:8c:b0:f9,dl_dst=00:25:83:df:b4:00,nw_src=172 speed: 0 Mbps now, 0 Mbps max OFPT_PORT_STATUS (OF1.4): MOD: ${INDEX}(test): addr:aa:55:aa:55:00:0x config: 0 - state: 0 + state: LIVE speed: 0 Mbps now, 0 Mbps max" fi @@ -3463,7 +3463,7 @@ OFPT_PORT_STATUS (OF1.4): MOD: ${INDEX}(test): addr:aa:55:aa:55:00:0x if test X"$1" = X"OFPPR_DELETE"; then shift; echo >>expout "OFPT_PORT_STATUS (OF1.4): DEL: ${INDEX}(test): addr:aa:55:aa:55:00:0x config: 0 - state: 0 + state: LIVE speed: 0 Mbps now, 0 Mbps max" fi @@ -3636,7 +3636,7 @@ check_async () { speed: 0 Mbps now, 0 Mbps max OFPT_PORT_STATUS (OF1.5): MOD: 2(test): addr:aa:55:aa:55:00:0x config: 0 - state: 0 + state: LIVE speed: 0 Mbps now, 0 Mbps max" fi @@ -3645,7 +3645,7 @@ OFPT_PORT_STATUS (OF1.5): MOD: 2(test): addr:aa:55:aa:55:00:0x if test X"$1" = X"OFPPR_DELETE"; then shift; echo >>expout "OFPT_PORT_STATUS (OF1.5): DEL: ${INDEX}(test): addr:aa:55:aa:55:00:0x config: 0 - state: 0 + state: LIVE speed: 0 Mbps now, 0 Mbps max" fi _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev