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

Submitted by László Sürü on April 20, 2017, 3:41 p.m.

Details

Message ID DB4PR07MB316FFE04D071376BC776578811B0@DB4PR07MB316.eurprd07.prod.outlook.com
State Accepted
Headers show

Commit Message

László Sürü April 20, 2017, 3:41 p.m.
Thanks for the review and comments.
All unit tests were passing for me before with 'make check', I haven't seen failing unit tests.
It might have been a temporary misbehavior.

I've applied the proposed changes and successfully rerun the tests 
also with 'testsuite' this time based on your attached log (see attachment).
Also, I've adapted the tests to the new OF 1.6 test as well.

Please find the modified patched below in this mail.

Thanks and regards
Laszlo

-----Original Message-----
From: Ben Pfaff [mailto:blp@ovn.org] 
Sent: Saturday, April 15, 2017 6:44 AM
To: László Sürü <laszlo.suru@ericsson.com>
Cc: ovs-dev@openvswitch.org
Subject: Re: [ovs-dev] [PATCH] ofproto-dpif : propagate may_enable flag as link aliveness

Thanks a lot for the revised patch!  It will be good to get this done properly.

I'm appending some changes that I suggest folding in to better match the usual OVS coding style.

However, when I run the testsuite, I get the failures below.  Do you see these too?  Can you take a look at them?  I'm also attaching the full testsuite.log in case it helps.

bfd

 22: bfd - liveness propagation - OF1.3              FAILED (bfd.at:847)
 23: bfd - liveness propagation - OF1.4              FAILED (bfd.at:920)
 24: bfd - liveness propagation - OF1.5              FAILED (bfd.at:993)

ofproto

890: ofproto - mod-port (OpenFlow 1.6)               FAILED (ofproto.at:1308)

--8<--------------------------cut here-------------------------->8--

Comments

Ben Pfaff April 21, 2017, 5:38 p.m.
Thanks for the revision.

I still saw the failures, so I spent some time looking at why.  It
turned out to be related to the two different database transactions used
to configure BFD.  When I combined the two transactions into one,
e.g. changed

    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])

into

    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 -- \
              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])

I no longer saw the failures.

I made that change in each of the BFD tests.  I also got rid of the use
of the GNU grep --no-group-separator option, which BSD doesn't appear to
support.

With those changes, I applied this to master.  Thanks again!

On Thu, Apr 20, 2017 at 03:41:57PM +0000, László Sürü wrote:
> Thanks for the review and comments.
> All unit tests were passing for me before with 'make check', I haven't seen failing unit tests.
> It might have been a temporary misbehavior.
> 
> I've applied the proposed changes and successfully rerun the tests 
> also with 'testsuite' this time based on your attached log (see attachment).
> Also, I've adapted the tests to the new OF 1.6 test as well.
> 
> Please find the modified patched below in this mail.
> 
> Thanks and regards
> Laszlo
> 
> -----Original Message-----
> From: Ben Pfaff [mailto:blp@ovn.org] 
> Sent: Saturday, April 15, 2017 6:44 AM
> To: László Sürü <laszlo.suru@ericsson.com>
> Cc: ovs-dev@openvswitch.org
> Subject: Re: [ovs-dev] [PATCH] ofproto-dpif : propagate may_enable flag as link aliveness
> 
> Thanks a lot for the revised patch!  It will be good to get this done properly.
> 
> I'm appending some changes that I suggest folding in to better match the usual OVS coding style.
> 
> However, when I run the testsuite, I get the failures below.  Do you see these too?  Can you take a look at them?  I'm also attaching the full testsuite.log in case it helps.
> 
> bfd
> 
>  22: bfd - liveness propagation - OF1.3              FAILED (bfd.at:847)
>  23: bfd - liveness propagation - OF1.4              FAILED (bfd.at:920)
>  24: bfd - liveness propagation - OF1.5              FAILED (bfd.at:993)
> 
> ofproto
> 
> 890: ofproto - mod-port (OpenFlow 1.6)               FAILED (ofproto.at:1308)
> 
> --8<--------------------------cut here-------------------------->8--
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index 218e8eb..c82640d 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 7440d5b..d41e35a 100644
> --- a/ofproto/ofproto.c
> +++ b/ofproto/ofproto.c
> @@ -2473,9 +2473,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. */
> @@ -2633,7 +2630,8 @@ 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)) {
> +            bool port_changed = !ofport_equal(&port->pp, &pp);
> +            if (port_changed) {
>                  ofport_modified(port, &pp);
>              }
>  
> @@ -2649,6 +2647,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 5c0d076..e191c49 100644
> --- a/tests/ofproto.at
> +++ b/tests/ofproto.at
> @@ -1228,15 +1228,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]
> @@ -1259,15 +1259,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]
> @@ -1291,15 +1291,15 @@ AT_CLEANUP
>  AT_SETUP([ofproto - mod-port (OpenFlow 1.6)])
>  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]
> @@ -3520,7 +3520,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
>  
> @@ -3529,7 +3529,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
>  
> @@ -3702,7 +3702,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
>  
> @@ -3711,7 +3711,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
> 
>
László Sürü April 26, 2017, 4:10 p.m.
Thanks for the bfd update!

Just one more question,
Is the backporting of liveness propagation to OVS 2.7 branch planned also?

Thanks and regards
Laszlo

-----Original Message-----
From: Ben Pfaff [mailto:blp@ovn.org] 
Sent: Friday, April 21, 2017 7:39 PM
To: László Sürü <laszlo.suru@ericsson.com>
Cc: ovs-dev@openvswitch.org
Subject: Re: [ovs-dev] [PATCH] ofproto-dpif : propagate may_enable flag as link aliveness

Thanks for the revision.

I still saw the failures, so I spent some time looking at why.  It turned out to be related to the two different database transactions used to configure BFD.  When I combined the two transactions into one, e.g. changed

    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])

into

    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 -- \
              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])

I no longer saw the failures.

I made that change in each of the BFD tests.  I also got rid of the use of the GNU grep --no-group-separator option, which BSD doesn't appear to support.

With those changes, I applied this to master.  Thanks again!

On Thu, Apr 20, 2017 at 03:41:57PM +0000, László Sürü wrote:
> Thanks for the review and comments.
> All unit tests were passing for me before with 'make check', I haven't seen failing unit tests.
> It might have been a temporary misbehavior.
> 
> I've applied the proposed changes and successfully rerun the tests 
> also with 'testsuite' this time based on your attached log (see attachment).
> Also, I've adapted the tests to the new OF 1.6 test as well.
> 
> Please find the modified patched below in this mail.
> 
> Thanks and regards
> Laszlo
> 
> -----Original Message-----
> From: Ben Pfaff [mailto:blp@ovn.org]
> Sent: Saturday, April 15, 2017 6:44 AM
> To: László Sürü <laszlo.suru@ericsson.com>
> Cc: ovs-dev@openvswitch.org
> Subject: Re: [ovs-dev] [PATCH] ofproto-dpif : propagate may_enable 
> flag as link aliveness
> 
> Thanks a lot for the revised patch!  It will be good to get this done properly.
> 
> I'm appending some changes that I suggest folding in to better match the usual OVS coding style.
> 
> However, when I run the testsuite, I get the failures below.  Do you see these too?  Can you take a look at them?  I'm also attaching the full testsuite.log in case it helps.
> 
> bfd
> 
>  22: bfd - liveness propagation - OF1.3              FAILED (bfd.at:847)
>  23: bfd - liveness propagation - OF1.4              FAILED (bfd.at:920)
>  24: bfd - liveness propagation - OF1.5              FAILED (bfd.at:993)
> 
> ofproto
> 
> 890: ofproto - mod-port (OpenFlow 1.6)               FAILED (ofproto.at:1308)
> 
> --8<--------------------------cut here-------------------------->8--
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 
> 218e8eb..c82640d 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 
> 7440d5b..d41e35a 100644
> --- a/ofproto/ofproto.c
> +++ b/ofproto/ofproto.c
> @@ -2473,9 +2473,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. */ @@ 
> -2633,7 +2630,8 @@ 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)) {
> +            bool port_changed = !ofport_equal(&port->pp, &pp);
> +            if (port_changed) {
>                  ofport_modified(port, &pp);
>              }
>  
> @@ -2649,6 +2647,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 
> 5c0d076..e191c49 100644
> --- a/tests/ofproto.at
> +++ b/tests/ofproto.at
> @@ -1228,15 +1228,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] @@ 
> -1259,15 +1259,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] @@ 
> -1291,15 +1291,15 @@ AT_CLEANUP  AT_SETUP([ofproto - mod-port 
> (OpenFlow 1.6)])  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] @@ 
> -3520,7 +3520,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
>  
> @@ -3529,7 +3529,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
>  
> @@ -3702,7 +3702,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
>  
> @@ -3711,7 +3711,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
> 
>
Ben Pfaff April 26, 2017, 7:57 p.m.
No, we don't add features to release branches.

On Wed, Apr 26, 2017 at 04:10:36PM +0000, László Sürü wrote:
> Thanks for the bfd update!
> 
> Just one more question,
> Is the backporting of liveness propagation to OVS 2.7 branch planned also?
> 
> Thanks and regards
> Laszlo
> 
> -----Original Message-----
> From: Ben Pfaff [mailto:blp@ovn.org] 
> Sent: Friday, April 21, 2017 7:39 PM
> To: László Sürü <laszlo.suru@ericsson.com>
> Cc: ovs-dev@openvswitch.org
> Subject: Re: [ovs-dev] [PATCH] ofproto-dpif : propagate may_enable flag as link aliveness
> 
> Thanks for the revision.
> 
> I still saw the failures, so I spent some time looking at why.  It turned out to be related to the two different database transactions used to configure BFD.  When I combined the two transactions into one, e.g. changed
> 
>     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])
> 
> into
> 
>     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 -- \
>               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])
> 
> I no longer saw the failures.
> 
> I made that change in each of the BFD tests.  I also got rid of the use of the GNU grep --no-group-separator option, which BSD doesn't appear to support.
> 
> With those changes, I applied this to master.  Thanks again!
> 
> On Thu, Apr 20, 2017 at 03:41:57PM +0000, László Sürü wrote:
> > Thanks for the review and comments.
> > All unit tests were passing for me before with 'make check', I haven't seen failing unit tests.
> > It might have been a temporary misbehavior.
> > 
> > I've applied the proposed changes and successfully rerun the tests 
> > also with 'testsuite' this time based on your attached log (see attachment).
> > Also, I've adapted the tests to the new OF 1.6 test as well.
> > 
> > Please find the modified patched below in this mail.
> > 
> > Thanks and regards
> > Laszlo
> > 
> > -----Original Message-----
> > From: Ben Pfaff [mailto:blp@ovn.org]
> > Sent: Saturday, April 15, 2017 6:44 AM
> > To: László Sürü <laszlo.suru@ericsson.com>
> > Cc: ovs-dev@openvswitch.org
> > Subject: Re: [ovs-dev] [PATCH] ofproto-dpif : propagate may_enable 
> > flag as link aliveness
> > 
> > Thanks a lot for the revised patch!  It will be good to get this done properly.
> > 
> > I'm appending some changes that I suggest folding in to better match the usual OVS coding style.
> > 
> > However, when I run the testsuite, I get the failures below.  Do you see these too?  Can you take a look at them?  I'm also attaching the full testsuite.log in case it helps.
> > 
> > bfd
> > 
> >  22: bfd - liveness propagation - OF1.3              FAILED (bfd.at:847)
> >  23: bfd - liveness propagation - OF1.4              FAILED (bfd.at:920)
> >  24: bfd - liveness propagation - OF1.5              FAILED (bfd.at:993)
> > 
> > ofproto
> > 
> > 890: ofproto - mod-port (OpenFlow 1.6)               FAILED (ofproto.at:1308)
> > 
> > --8<--------------------------cut here-------------------------->8--
> > diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 
> > 218e8eb..c82640d 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 
> > 7440d5b..d41e35a 100644
> > --- a/ofproto/ofproto.c
> > +++ b/ofproto/ofproto.c
> > @@ -2473,9 +2473,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. */ @@ 
> > -2633,7 +2630,8 @@ 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)) {
> > +            bool port_changed = !ofport_equal(&port->pp, &pp);
> > +            if (port_changed) {
> >                  ofport_modified(port, &pp);
> >              }
> >  
> > @@ -2649,6 +2647,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 
> > 5c0d076..e191c49 100644
> > --- a/tests/ofproto.at
> > +++ b/tests/ofproto.at
> > @@ -1228,15 +1228,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] @@ 
> > -1259,15 +1259,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] @@ 
> > -1291,15 +1291,15 @@ AT_CLEANUP  AT_SETUP([ofproto - mod-port 
> > (OpenFlow 1.6)])  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] @@ 
> > -3520,7 +3520,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
> >  
> > @@ -3529,7 +3529,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
> >  
> > @@ -3702,7 +3702,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
> >  
> > @@ -3711,7 +3711,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
> > 
> > 
> 
> 
>

Patch hide | download patch | download mbox

diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 218e8eb..c82640d 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 7440d5b..d41e35a 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -2473,9 +2473,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. */
@@ -2633,7 +2630,8 @@  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)) {
+            bool port_changed = !ofport_equal(&port->pp, &pp);
+            if (port_changed) {
                 ofport_modified(port, &pp);
             }
 
@@ -2649,6 +2647,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 5c0d076..e191c49 100644
--- a/tests/ofproto.at
+++ b/tests/ofproto.at
@@ -1228,15 +1228,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]
@@ -1259,15 +1259,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]
@@ -1291,15 +1291,15 @@  AT_CLEANUP
 AT_SETUP([ofproto - mod-port (OpenFlow 1.6)])
 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]
@@ -3520,7 +3520,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
 
@@ -3529,7 +3529,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
 
@@ -3702,7 +3702,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
 
@@ -3711,7 +3711,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