AT_BANNER([cfm]) m4_define([CFM_CHECK_EXTENDED], [ AT_CHECK([ovs-appctl cfm/show $1 | sed -e '/next CCM tx:/d' | sed -e '/next fault check:/d' | sed -e '/recv since check:/d'],[0], [dnl ---- $1 ---- MPID $2: extended average health: $3 opstate: $4 remote_opstate: $5 interval: $6 Remote MPID $7 opstate: $8 ]) ]) m4_define([CFM_CHECK_EXTENDED_FAULT], [ AT_CHECK([ovs-appctl cfm/show $1 | sed -e '/next CCM tx:/d' | sed -e '/next fault check:/d' | sed -e '/recv since check:/d'],[0], [dnl ---- $1 ---- MPID $2: extended fault: $3 average health: $4 opstate: $5 remote_opstate: $6 interval: $7 ]) ]) m4_define([CFM_VSCTL_LIST_IFACE], [ AT_CHECK([ovs-vsctl list interface $1 | sed -n '/$2 /p'],[0], [dnl $3 ]) ]) m4_define([CFM_CHECK_DB], [ CFM_VSCTL_LIST_IFACE([$1], [cfm_fault], [cfm_fault : $2]) CFM_VSCTL_LIST_IFACE([$1], [cfm_fault_status], [cfm_fault_status : [[$3]]]) CFM_VSCTL_LIST_IFACE([$1], [cfm_flap_count], [cfm_flap_count : $4]) CFM_VSCTL_LIST_IFACE([$1], [cfm_health], [cfm_health : [[$5]]]) CFM_VSCTL_LIST_IFACE([$1], [cfm_remote_mpids], [cfm_remote_mpids : [[$6]]]) CFM_VSCTL_LIST_IFACE([$1], [cfm_remote_opstate], [cfm_remote_opstate : $7]) ]) # These two tests check the update of cfm status at different scenarios. # Test cfm status update at startup and removal. AT_SETUP([cfm - check update ovsdb 1]) OVS_VSWITCHD_START([add-port br0 p0 -- set Interface p0 type=gre \ options:remote_ip=1.2.3.4 -- \ set Interface p0 other_config:cfm_interval=300 other_config:cfm_extended=true]) ovs-appctl time/stop AT_CHECK([ovs-appctl ofproto/list-tunnels], [0], [dnl port 1: p0 (gre: ::->1.2.3.4, key=0, legacy_l2, dp port=1, ttl=64) ]) AT_CHECK([ovs-vsctl set Interface p0 cfm_mpid=1]) # at beginning, since the first fault check timeout is not reached # cfm_fault should be false. for i in `seq 0 4`; do ovs-appctl time/warp 100 CFM_CHECK_DB([p0], [false], [], [0], [], [], [up]) done # advance clock to pass the fault check timeout and check cfm # status update in OVSDB. ovs-appctl time/warp 1500 100 CFM_CHECK_DB([p0], [true], [recv], [1], [], [], [up]) # remove the cfm on p0 and status should be all empty. AT_CHECK([ovs-vsctl remove int p0 cfm_mpid 1]) ovs-appctl time/warp 500 100 CFM_CHECK_DB([p0], [[[]]], [], [[[]]], [], [], [[[]]]) OVS_VSWITCHD_STOP AT_CLEANUP # Test cfm status update in normal case. AT_SETUP([cfm - check update ovsdb 2]) #Create 2 bridges connected by patch ports and enable cfm OVS_VSWITCHD_START([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 -- \ set Interface p0 other_config:cfm_interval=300 other_config:cfm_extended=true -- \ set Interface p1 other_config:cfm_interval=300 other_config:cfm_extended=true]) ovs-appctl time/stop AT_CHECK([ovs-vsctl set Interface p0 cfm_mpid=1]) # check cfm status update in OVSDB. ovs-appctl time/warp 1500 100 CFM_CHECK_DB([p0], [true], [recv], [1], [], [], [up]) # turn cfm on p1 on, cfm status of p0 and p1 should all go up. AT_CHECK([ovs-vsctl set interface p1 cfm_mpid=2]) ovs-appctl time/warp 1500 100 CFM_CHECK_DB([p0], [false], [], [2], [], [2], [up]) CFM_CHECK_DB([p1], [false], [], [0], [], [1], [up]) # turn cfm on p1 off, cfm status of p0 should go down again. AT_CHECK([ovs-vsctl remove int p1 cfm_mpid 2]) ovs-appctl time/warp 1500 100 CFM_CHECK_DB([p0], [true], [recv], [3], [], [], [up]) OVS_VSWITCHD_STOP AT_CLEANUP # test cfm under demand mode. AT_SETUP([cfm - demand mode]) #Create 2 bridges connected by patch ports and enable cfm OVS_VSWITCHD_START([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 -- \ set Interface p0 cfm_mpid=1 other_config:cfm_interval=300 other_config:cfm_extended=true -- \ set Interface p1 cfm_mpid=2 other_config:cfm_interval=300 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], [300ms], [2], [up]) CFM_CHECK_EXTENDED([p1], [2], [100], [up], [up], [300ms], [1], [up]) # turn on demand mode on one end. AT_CHECK([ovs-vsctl set interface p0 other_config:cfm_demand=true]) # cfm should never go down. for i in `seq 0 100` do ovs-appctl time/warp 100 CFM_CHECK_EXTENDED([p0], [1], [100], [up], [up], [300ms], [2], [up]) CFM_CHECK_EXTENDED([p1], [2], [100], [up], [up], [300ms], [1], [up]) done # turn on demand mode on the other end. AT_CHECK([ovs-vsctl set interface p1 other_config:cfm_demand=true]) for i in `seq 0 100` do ovs-appctl time/warp 100 CFM_CHECK_EXTENDED([p0], [1], [100], [up], [up], [300ms], [2], [up]) CFM_CHECK_EXTENDED([p1], [2], [100], [up], [up], [300ms], [1], [up]) done OVS_VSWITCHD_STOP AT_CLEANUP # test demand_rx_ccm under demand mode. AT_SETUP([cfm - demand_rx_ccm]) #Create 2 bridges connected by patch ports and enable cfm OVS_VSWITCHD_START([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 cfm_mpid=1 other_config:cfm_interval=300 other_config:cfm_extended=true other_config:cfm_demand=true -- \ set Interface p1 cfm_mpid=2 other_config:cfm_interval=300 other_config:cfm_extended=true other_config:cfm_demand=true]) ovs-appctl time/stop # wait for a while to stablize cfm. (need a longer time, since in demand mode # the fault interval is (MAX(ccm_interval_ms, 500) * 3.5) ms) ovs-appctl time/warp 20100 100 CFM_CHECK_EXTENDED([p0], [1], [100], [up], [up], [300ms], [2], [up]) CFM_CHECK_EXTENDED([p1], [2], [100], [up], [up], [300ms], [1], [up]) # turn off the cfm on p1. AT_CHECK([ovs-vsctl clear Interface p1 cfm_mpid]) # cfm should never go down while receiving data packets. for i in `seq 0 200` do ovs-appctl time/warp 100 AT_CHECK([ovs-ofctl packet-out br1 "in_port=3 packet=90e2ba01475000101856b2e80806000108000604000100101856b2e80202020300000000000002020202 actions=2"], [0], [stdout], []) done CFM_CHECK_EXTENDED([p0], [1], [0], [up], [up], [300ms], [2], [up]) # wait longer, since the demand_rx_ccm interval is 100 * 300 ms. # since there is no ccm received, the [recv] fault should be raised. for i in `seq 0 200` do ovs-appctl time/warp 100 AT_CHECK([ovs-ofctl packet-out br1 "in_port=3 packet=90e2ba01475000101856b2e80806000108000604000100101856b2e80202020300000000000002020202 actions=2"], [0], [stdout], []) done CFM_CHECK_EXTENDED_FAULT([p0], [1], [recv], [0], [up], [up], [300ms]) # now turn on the cfm on p1 again, AT_CHECK([ovs-vsctl set Interface p1 cfm_mpid=2]) # cfm should be up for both p0 and p1 ovs-appctl time/warp 20100 100 CFM_CHECK_EXTENDED([p0], [1], [100], [up], [up], [300ms], [2], [up]) CFM_CHECK_EXTENDED([p1], [2], [100], [up], [up], [300ms], [1], [up]) # now turn off the cfm on p1 again AT_CHECK([ovs-vsctl clear Interface p1 cfm_mpid]) # since there is no ccm received, the [recv] fault should be raised. for i in `seq 0 400` do ovs-appctl time/warp 100 AT_CHECK([ovs-ofctl packet-out br1 "in_port=3 packet=90e2ba01475000101856b2e80806000108000604000100101856b2e80202020300000000000002020202 actions=2"], [0], [stdout], []) done CFM_CHECK_EXTENDED_FAULT([p0], [1], [recv], [0], [up], [up], [300ms]) OVS_VSWITCHD_STOP AT_CLEANUP # test cfm_flap_count. AT_SETUP([cfm - flap_count]) #Create 2 bridges connected by patch ports and enable cfm OVS_VSWITCHD_START([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 -- \ 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 : [[]]]) # 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 CFM_VSCTL_LIST_IFACE([p0], [cfm_flap_count], [cfm_flap_count : 2]) OVS_VSWITCHD_STOP AT_CLEANUP AT_SETUP([cfm - fault_override]) OVS_VSWITCHD_START([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 -- \ 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]) AT_CHECK([ovs-appctl cfm/show p1 | grep 'fault_override'], [1], [ignore]) CFM_VSCTL_LIST_IFACE([p1], [cfm_fault_status], [cfm_fault_status : [[]]]) # set a fault and see that this is shown in the CFM module and the database AT_CHECK([ovs-appctl cfm/set-fault p1 true], [0], [OK ]) AT_CHECK([ovs-appctl time/warp 100], [0], [ignore]) AT_CHECK([ovs-appctl cfm/show p1 | grep 'fault_override' | sed -e 's/MPID [[0-9]]*: extended //'], [0], [dnl fault_override ]) CFM_VSCTL_LIST_IFACE([p1], [cfm_fault_status], [cfm_fault_status : [[override]]]) # reset and see that it returned to normal AT_CHECK([ovs-appctl cfm/set-fault normal], [0], [OK ]) AT_CHECK([ovs-appctl time/warp 100], [0], [ignore]) AT_CHECK([ovs-appctl cfm/show p1 | grep 'fault_override'], [1], [ignore]) CFM_VSCTL_LIST_IFACE([p1], [cfm_fault_status], [cfm_fault_status : [[]]]) OVS_VSWITCHD_STOP AT_CLEANUP AT_SETUP([cfm - check that CFM works together with RSTP]) # Create br0 with interfaces p1 # and br1 with interfaces p2 # with p1 and p2 connected via unix domain socket OVS_VSWITCHD_START( [set bridge br0 rstp_enable=true -- \ add-br br1 -- \ set bridge br1 other-config:hwaddr=aa:66:aa:66:00:00 -- \ set bridge br1 datapath-type=dummy -- \ set bridge br1 rstp_enable=true -- \ ]) AT_CHECK([ovs-vsctl add-port br0 p0 -- \ set interface p0 type=dummy options:pstream=punix:$OVS_RUNDIR/p0.sock cfm_mpid=1 other_config:cfm_interval=300 other_config:cfm_extended=true -- \ ]) AT_CHECK([ovs-vsctl add-port br1 p1 -- \ set interface p1 type=dummy options:stream=unix:$OVS_RUNDIR/p0.sock cfm_mpid=2 other_config:cfm_interval=300 other_config:cfm_extended=true -- \ ]) ovs-appctl time/stop ovs-appctl time/warp 10100 100 # Forwarding should be true CFM_CHECK_EXTENDED([p0], [1], [100], [up], [up], [300ms], [2], [up]) CFM_CHECK_EXTENDED([p1], [2], [100], [up], [up], [300ms], [1], [up]) # Disable cfm on p1, cfm should receive fault. AT_CHECK([ovs-vsctl set interface p1 other_config:cfm_extended=false]) ovs-appctl time/warp 5000 100 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 -A3 "MOD: 1(p0)"|grep -ve --]], [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 -A3 "MOD: 1(p0)"|grep -ve --]], [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 -A3 "MOD: 1(p0)"|grep -ve --]], [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