[ovs-dev] [PATCH] ofproto-dpif : propagate may_enable flag as link aliveness

László Sürü laszlo.suru at ericsson.com
Wed Mar 22 11:34:01 UTC 2017


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:blp at ovn.org] 
Sent: Friday, March 17, 2017 7:21 PM
To: László Sürü <laszlo.suru at ericsson.com>
Cc: ovs-dev at 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



More information about the dev mailing list