2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 18:07:40 +00:00
ovs/tests/learn.at

330 lines
16 KiB
Plaintext
Raw Normal View History

AT_BANNER([learning action])
AT_SETUP([learning action - parsing and formatting])
AT_DATA([flows.txt], [[
actions=learn()
actions=learn(NXM_OF_VLAN_TCI[0..11], NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], output:NXM_OF_IN_PORT[], load:10->NXM_NX_REG0[5..10])
actions=learn(table=1,idle_timeout=10, hard_timeout=20, fin_idle_timeout=5, fin_hard_timeout=10, priority=10, cookie=0xfedcba9876543210, in_port=99,NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_OF_IN_PORT[]->NXM_NX_REG1[16..31])
]])
AT_CHECK([ovs-ofctl parse-flows flows.txt], [0],
[[usable protocols: any
chosen protocol: OpenFlow10-table_id
OFPT_FLOW_MOD (xid=0x1): ADD actions=learn(table=1)
OFPT_FLOW_MOD (xid=0x2): ADD actions=learn(table=1,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],output:NXM_OF_IN_PORT[],load:0xa->NXM_NX_REG0[5..10])
OFPT_FLOW_MOD (xid=0x3): ADD actions=learn(table=1,idle_timeout=10,hard_timeout=20,fin_idle_timeout=5,fin_hard_timeout=10,priority=10,cookie=0xfedcba9876543210,in_port=99,NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_OF_IN_PORT[]->NXM_NX_REG1[16..31])
]])
AT_CLEANUP
AT_SETUP([learning action - parsing and formatting - illegal in_port_oxm])
AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(table=1, in_port_oxm=123456)']],
[1], [], [stderr])
AT_CHECK([sed -e 's/.*|ofp_util|WARN|//' < stderr], [0],
[[port 123456 is outside the supported range 0 through ffff or 0xffffff00 through 0xffffffff
ovs-ofctl: 123456: port value out of range for in_port_oxm
]], [[]])
AT_CLEANUP
AT_SETUP([learning action - parsing and formatting - OXM])
AT_DATA([flows.txt], [[
actions=learn(output:OXM_OF_IN_PORT[])
actions=learn(table=1, in_port=1, load:OXM_OF_IN_PORT[]->NXM_NX_REG1[], load:0xfffffffe->OXM_OF_IN_PORT[])
]])
AT_CHECK([ovs-ofctl parse-flows flows.txt], [0],
[[usable protocols: any
chosen protocol: OpenFlow10-table_id
OFPT_FLOW_MOD (xid=0x1): ADD actions=learn(table=1,output:OXM_OF_IN_PORT[])
OFPT_FLOW_MOD (xid=0x2): ADD actions=learn(table=1,in_port=1,load:OXM_OF_IN_PORT[]->NXM_NX_REG1[],load:0xfffffffe->OXM_OF_IN_PORT[])
]])
AT_CLEANUP
AT_SETUP([learning action - examples])
AT_DATA([flows.txt], [[
# These are the examples from nicira-ext.h.
actions=learn(in_port=99,NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], load:NXM_OF_IN_PORT[]->NXM_NX_REG1[16..31])
actions=learn(NXM_OF_VLAN_TCI[0..11], NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],output:NXM_OF_IN_PORT[])
table=0 actions=learn(table=1,hard_timeout=10, NXM_OF_VLAN_TCI[0..11],output:NXM_OF_IN_PORT[]), resubmit(,1)
table=1 priority=0 actions=flood
]])
AT_CHECK([ovs-ofctl parse-flows flows.txt], [0],
[[usable protocols: OXM,OpenFlow10+table_id,NXM+table_id,OpenFlow11
chosen protocol: OpenFlow10+table_id
OFPT_FLOW_MOD (xid=0x1): ADD table:255 actions=learn(table=1,in_port=99,NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_OF_IN_PORT[]->NXM_NX_REG1[16..31])
OFPT_FLOW_MOD (xid=0x2): ADD table:255 actions=learn(table=1,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],output:NXM_OF_IN_PORT[])
OFPT_FLOW_MOD (xid=0x3): ADD actions=learn(table=1,hard_timeout=10,NXM_OF_VLAN_TCI[0..11],output:NXM_OF_IN_PORT[]),resubmit(,1)
OFPT_FLOW_MOD (xid=0x4): ADD table:1 priority=0 actions=FLOOD
]])
AT_CLEANUP
AT_SETUP([learning action - satisfied prerequisites])
AT_DATA([flows.txt],
[[actions=learn(eth_type=0x800,load:5->NXM_OF_IP_DST[])
ip,actions=learn(load:NXM_OF_IP_DST[]->NXM_NX_REG1[])
ip,actions=learn(eth_type=0x800,OXM_OF_IPV4_DST[])
]])
AT_CHECK([ovs-ofctl parse-flows flows.txt], [0],
[[usable protocols: any
chosen protocol: OpenFlow10-table_id
OFPT_FLOW_MOD (xid=0x1): ADD actions=learn(table=1,eth_type=0x800,load:0x5->NXM_OF_IP_DST[])
OFPT_FLOW_MOD (xid=0x2): ADD ip actions=learn(table=1,load:NXM_OF_IP_DST[]->NXM_NX_REG1[])
OFPT_FLOW_MOD (xid=0x3): ADD ip actions=learn(table=1,eth_type=0x800,NXM_OF_IP_DST[])
]])
AT_CLEANUP
AT_SETUP([learning action - invalid prerequisites])
AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(load:5->NXM_OF_IP_DST[])']],
[1], [], [stderr])
AT_CHECK([sed -e 's/.*|meta_flow|WARN|//' < stderr], [0],
[[destination field ip_dst lacks correct prerequisites
ovs-ofctl: actions are invalid with specified match (OFPBAC_BAD_ARGUMENT)
]], [[]])
AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(load:NXM_OF_IP_DST[]->NXM_NX_REG1[])']],
[1], [], [stderr])
AT_CHECK([sed -e 's/.*|meta_flow|WARN|//' < stderr], [0],
[[source field ip_dst lacks correct prerequisites
ovs-ofctl: actions are invalid with specified match (OFPBAC_BAD_ARGUMENT)
]])
AT_CLEANUP
AT_SETUP([learning action - standard VLAN+MAC learning])
OVS_VSWITCHD_START(
[add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1 -- \
add-port br0 p2 -- set Interface p2 type=dummy ofport_request=2 -- \
add-port br0 p3 -- set Interface p3 type=dummy ofport_request=3])
# Set up flow table for VLAN+MAC learning.
AT_DATA([flows.txt], [[
table=0 actions=learn(table=1, hard_timeout=60, NXM_OF_VLAN_TCI[0..11], NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], output:NXM_OF_IN_PORT[]), resubmit(,1)
table=1 priority=0 actions=flood
]])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
# Trace an ARP packet arriving on port 3, to create a MAC learning entry.
flow="in_port(3),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=192.168.0.1,tip=192.168.0.2,op=1,sha=50:54:00:00:00:05,tha=00:00:00:00:00:00)"
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
actual=`tail -1 stdout | sed 's/Datapath actions: //'`
expected="1,2,100"
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
mv stdout expout
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
# Check for the MAC learning entry.
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:3
table=1, priority=0 actions=FLOOD
NXST_FLOW reply:
])
# Trace a packet arrival destined for the learned MAC.
# (This will also learn a MAC.)
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:06,dst=50:54:00:00:00:05),eth_type(0x0806),arp(sip=192.168.0.2,tip=192.168.0.1,op=2,sha=50:54:00:00:00:06,tha=50:54:00:00:00:05)' -generate], [0], [stdout])
AT_CHECK([tail -1 stdout], [0], [Datapath actions: 3
])
# Check for both MAC learning entries.
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip |sort], [0], [dnl
table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:3
table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:06 actions=output:1
table=1, priority=0 actions=FLOOD
NXST_FLOW reply:
])
# Trace a packet arrival that updates the first learned MAC entry.
flow="in_port(2),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=192.168.0.1,tip=192.168.0.2,op=1,sha=50:54:00:00:00:05,tha=00:00:00:00:00:00)"
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
actual=`tail -1 stdout | sed 's/Datapath actions: //'`
expected="1,3,100"
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
mv stdout expout
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
# Check that the MAC learning entry was updated.
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:2
table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:06 actions=output:1
table=1, priority=0 actions=FLOOD
NXST_FLOW reply:
])
OVS_VSWITCHD_STOP
AT_CLEANUP
ofproto: Properly refresh rule modified time when nothing else changes. In Open vSwitch, a "modify" or "modify_strict" flow_mod is supposed to refresh the flow's last-modified time even if nothing else changes, because this interpretation makes the "learn" action more useful. As commit 308881afb (ofproto: Reinterpret meaning of OpenFlow hard timeouts with OFPFC_MODIFY.) notes: I finally found a good use for hard timeouts in OpenFlow, but they require a slight reinterpretation of the meaning of hard timeouts. Until now, a hard timeout meant that a flow would be removed the specified number of seconds after a flow was created. Intervening modifications with OFPFC_MODIFY(_STRICT) had no effect on the hard timeout; the flow would still be deleted the specified number of seconds after its original creation. This commit changes the effect of OFPFC_MODIFY(_STRICT). Now, modifying a flow resets its hard timeout counter. A flow will time out the specified number of seconds after creation or after the last time it is modified, whichever comes later. However, commit 080437614b (ofproto: Represent flow cookie changes as operations too.) broke this behavior because it incorrectly optimized out "modify" operations that didn't change the flow's actions or flow cookie. This commit fixes the problem, and adds a test to prevent future regression. Thanks to Amar Padmanabhan <amar@nicira.com> for helping to track this down. Bug #14841. Reported-by: Hiroshi Tanaka <htanaka@vmware.com> CC: Amar Padmanabhan <amar@nicira.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
2013-01-25 15:07:36 -08:00
dnl This test checks that repeated uses of a "learn" action cause the
dnl modified time of the learned flow to advance. Otherwise, the
dnl learned flow will expire after its hard timeout even though it's
dnl supposed to be refreshed. (The expiration can be hard to see since
dnl it gets re-learned again the next time a packet appears, but
dnl sometimes the expiration can cause temporary flooding etc.)
AT_SETUP([learning action - learn refreshes hard_age])
OVS_VSWITCHD_START(
[add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1 -- \
add-port br0 p2 -- set Interface p2 type=dummy ofport_request=2 -- \
add-port br0 p3 -- set Interface p3 type=dummy ofport_request=3])
ovs-appctl time/stop
# Set up flow table for MAC learning.
AT_DATA([flows.txt], [[
table=0 actions=learn(table=1, hard_timeout=10, NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], output:NXM_OF_IN_PORT[]), resubmit(,1)
table=1 priority=0 actions=flood
]])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
# Trace an ICMP packet arriving on port 3, to create a MAC learning entry.
flow="in_port(3),eth(src=50:54:00:00:00:07,dst=50:54:00:00:00:05),eth_type(0x0800),ipv4(src=192.168.0.2,dst=192.168.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=0,code=0)"
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
ofproto: Properly refresh rule modified time when nothing else changes. In Open vSwitch, a "modify" or "modify_strict" flow_mod is supposed to refresh the flow's last-modified time even if nothing else changes, because this interpretation makes the "learn" action more useful. As commit 308881afb (ofproto: Reinterpret meaning of OpenFlow hard timeouts with OFPFC_MODIFY.) notes: I finally found a good use for hard timeouts in OpenFlow, but they require a slight reinterpretation of the meaning of hard timeouts. Until now, a hard timeout meant that a flow would be removed the specified number of seconds after a flow was created. Intervening modifications with OFPFC_MODIFY(_STRICT) had no effect on the hard timeout; the flow would still be deleted the specified number of seconds after its original creation. This commit changes the effect of OFPFC_MODIFY(_STRICT). Now, modifying a flow resets its hard timeout counter. A flow will time out the specified number of seconds after creation or after the last time it is modified, whichever comes later. However, commit 080437614b (ofproto: Represent flow cookie changes as operations too.) broke this behavior because it incorrectly optimized out "modify" operations that didn't change the flow's actions or flow cookie. This commit fixes the problem, and adds a test to prevent future regression. Thanks to Amar Padmanabhan <amar@nicira.com> for helping to track this down. Bug #14841. Reported-by: Hiroshi Tanaka <htanaka@vmware.com> CC: Amar Padmanabhan <amar@nicira.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
2013-01-25 15:07:36 -08:00
actual=`tail -1 stdout | sed 's/Datapath actions: //'`
expected="1,2,100"
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
mv stdout expout
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
# Check that the MAC learning entry appeared.
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
table=1, hard_timeout=10, dl_dst=50:54:00:00:00:07 actions=output:3
table=1, priority=0 actions=FLOOD
NXST_FLOW reply:
])
# For 25 seconds, make sure that the MAC learning entry doesn't
# disappear as long as we refresh it every second.
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25; do
ovs-appctl time/warp 1000
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
ofproto: Properly refresh rule modified time when nothing else changes. In Open vSwitch, a "modify" or "modify_strict" flow_mod is supposed to refresh the flow's last-modified time even if nothing else changes, because this interpretation makes the "learn" action more useful. As commit 308881afb (ofproto: Reinterpret meaning of OpenFlow hard timeouts with OFPFC_MODIFY.) notes: I finally found a good use for hard timeouts in OpenFlow, but they require a slight reinterpretation of the meaning of hard timeouts. Until now, a hard timeout meant that a flow would be removed the specified number of seconds after a flow was created. Intervening modifications with OFPFC_MODIFY(_STRICT) had no effect on the hard timeout; the flow would still be deleted the specified number of seconds after its original creation. This commit changes the effect of OFPFC_MODIFY(_STRICT). Now, modifying a flow resets its hard timeout counter. A flow will time out the specified number of seconds after creation or after the last time it is modified, whichever comes later. However, commit 080437614b (ofproto: Represent flow cookie changes as operations too.) broke this behavior because it incorrectly optimized out "modify" operations that didn't change the flow's actions or flow cookie. This commit fixes the problem, and adds a test to prevent future regression. Thanks to Amar Padmanabhan <amar@nicira.com> for helping to track this down. Bug #14841. Reported-by: Hiroshi Tanaka <htanaka@vmware.com> CC: Amar Padmanabhan <amar@nicira.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
2013-01-25 15:07:36 -08:00
# Check that the entry is there.
AT_CHECK([ovs-ofctl dump-flows br0 table=1], [0], [stdout])
AT_CHECK([ofctl_strip < stdout | sort], [0], [dnl
table=1, hard_timeout=10, dl_dst=50:54:00:00:00:07 actions=output:3
table=1, priority=0 actions=FLOOD
NXST_FLOW reply:
])
if test $i != 1; then
# Check that hard_age has appeared. We need to do this separately
# from the above check because ofctl_strip removes it. dump-flows
# only prints hard_age when it is different from the flow's duration
# (that is, the number of seconds from the time it was created),
# so we only check for it after we've refreshed the flow once.
AT_CHECK([grep dl_dst=50:54:00:00:00:07 stdout | grep -c hard_age],
[0], [1
])
fi
done
# Make sure that 15 seconds without refreshing makes the flow time out.
ovs-appctl time/warp 5000
ovs-appctl time/warp 5000
ovs-appctl time/warp 5000
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
table=1, priority=0 actions=FLOOD
NXST_FLOW reply:
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([learning action - TCPv4 port learning])
OVS_VSWITCHD_START(
[add-port br0 p1 -- set Interface p1 type=dummy -- \
add-port br0 p2 -- set Interface p2 type=dummy -- \
add-port br0 p3 -- set Interface p3 type=dummy])
# Set up flow table for TCPv4 port learning.
AT_CHECK([[ovs-ofctl add-flow br0 'table=0 tcp actions=learn(table=1, hard_timeout=60, eth_type=0x800, nw_proto=6, NXM_OF_IP_SRC[]=NXM_OF_IP_DST[], NXM_OF_IP_DST[]=NXM_OF_IP_SRC[], NXM_OF_TCP_SRC[]=NXM_OF_TCP_DST[], NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[]), flood']])
# Trace a TCPv4 packet arriving on port 3.
flow="in_port(3),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:06),eth_type(0x0800),ipv4(src=192.168.0.2,dst=192.168.0.1,proto=6,tos=0,ttl=64,frag=no),tcp(src=40000,dst=80)"
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
actual=`tail -1 stdout | sed 's/Datapath actions: //'`
expected="1,2,100"
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
mv stdout expout
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
# Check for the learning entry.
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
table=1, hard_timeout=60, tcp,nw_src=192.168.0.1,nw_dst=192.168.0.2,tp_src=80,tp_dst=40000 actions=drop
NXST_FLOW reply:
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([learning action - TCPv6 port learning])
OVS_VSWITCHD_START(
[add-port br0 p1 -- set Interface p1 type=dummy -- \
add-port br0 p2 -- set Interface p2 type=dummy -- \
add-port br0 p3 -- set Interface p3 type=dummy])
# Set up flow table for TCPv6 port learning.
# Also add a 128-bit-wide "load" action and a 128-bit literal match to check
# that they work.
AT_CHECK([[ovs-ofctl add-flow br0 'table=0 tcp6 actions=learn(table=1, hard_timeout=60, eth_type=0x86dd, nw_proto=6, NXM_NX_IPV6_SRC[]=NXM_NX_IPV6_DST[], ipv6_dst=2001:0db8:85a3:0000:0000:8a2e:0370:7334, NXM_OF_TCP_SRC[]=NXM_OF_TCP_DST[], NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[], load(0x20010db885a308d313198a2e03707348->NXM_NX_IPV6_DST[])), flood']])
# Trace a TCPv6 packet arriving on port 3.
flow="in_port(3),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:06),eth_type(0x86dd),ipv6(src=fec0::2,dst=fec0::1,label=0,proto=6,tclass=0,hlimit=255,frag=no),tcp(src=40000,dst=80)"
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
actual=`tail -1 stdout | sed 's/Datapath actions: //'`
expected="1,2,100"
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
mv stdout expout
AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
# Check for the learning entry.
AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
table=1, hard_timeout=60, tcp6,ipv6_src=fec0::1,ipv6_dst=2001:db8:85a3::8a2e:370:7334,tp_src=80,tp_dst=40000 actions=load:0x13198a2e03707348->NXM_NX_IPV6_DST[[0..63]],load:0x20010db885a308d3->NXM_NX_IPV6_DST[[64..127]]
tcp6 actions=learn(table=1,hard_timeout=60,eth_type=0x86dd,nw_proto=6,NXM_NX_IPV6_SRC[[]]=NXM_NX_IPV6_DST[[]],ipv6_dst=2001:db8:85a3::8a2e:370:7334,NXM_OF_TCP_SRC[[]]=NXM_OF_TCP_DST[[]],NXM_OF_TCP_DST[[]]=NXM_OF_TCP_SRC[[]],load:0x20010db885a308d313198a2e03707348->NXM_NX_IPV6_DST[[]]),FLOOD
NXST_FLOW reply:
])
OVS_VSWITCHD_STOP
AT_CLEANUP
# In this use of a learn action, the first packet in the flow creates
# a new flow that changes the behavior of subsequent packets in the
# flow.
AT_SETUP([learning action - self-modifying flow])
OVS_VSWITCHD_START
ADD_OF_PORTS([br0], 1, 2, 3)
# Set up flow table for TCPv4 port learning.
AT_CHECK([[ovs-ofctl add-flow br0 'actions=load:3->NXM_NX_REG0[0..15],learn(table=0,priority=65535,NXM_OF_ETH_SRC[],NXM_OF_VLAN_TCI[0..11],output:NXM_NX_REG0[0..15]),output:2']])
# Trace some packets arriving. The particular packets don't matter.
for i in 1 2 3 4 5 6 7 8 9 10; do
ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9)'
done
# Check for the learning entry.
AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0],
[[ n_packets=1, n_bytes=60, actions=load:0x3->NXM_NX_REG0[0..15],learn(table=0,priority=65535,NXM_OF_ETH_SRC[],NXM_OF_VLAN_TCI[0..11],output:NXM_NX_REG0[0..15]),output:2
priority=65535,vlan_tci=0x0000/0x0fff,dl_src=50:54:00:00:00:05 actions=output:3
NXST_FLOW reply:
]])
# Check that the first packet went out port 2 and the rest out port 3.
AT_CHECK(
[(ovs-ofctl dump-ports br0 2; ovs-ofctl dump-ports br0 3) | STRIP_XIDS], [0],
[OFPST_PORT reply: 1 ports
port 2: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
tx pkts=1, bytes=60, drop=0, errs=0, coll=0
OFPST_PORT reply: 1 ports
port 3: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
tx pkts=9, bytes=540, drop=0, errs=0, coll=0
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([learning action - fin_timeout feature])
# This is a totally artificial use of the "learn" action. The only purpose
# is to check that specifying fin_idle_timeout or fin_hard_timeout causes
# a corresponding fin_timeout action to end up in the learned flows.
OVS_VSWITCHD_START(
[add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1])
AT_CHECK([[ovs-ofctl add-flow br0 'actions=learn(fin_hard_timeout=10, fin_idle_timeout=5, NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], output:NXM_OF_IN_PORT[])']])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=192.168.0.1,tip=192.168.0.2,op=1,sha=50:54:00:00:00:05,tha=00:00:00:00:00:00)' -generate], [0], [ignore])
AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip], [0],
[NXST_FLOW reply:
table=1, dl_dst=50:54:00:00:00:05 actions=fin_timeout(idle_timeout=5,hard_timeout=10),output:1
])
OVS_VSWITCHD_STOP
AT_CLEANUP