summaryrefslogtreecommitdiff
path: root/tests/learn.at
blob: 314baaf74568be0207ebfee6ed2f3cf317bac21c (plain)
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
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:0x000a->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 - 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: OpenFlow10+table_id,NXM+table_id
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,NXM_OF_IP_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:0x00000005->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], [],
  [[ovs-ofctl: load:5->NXM_OF_IP_DST[]: cannot specify destination field ip_dst because prerequisites are not satisfied
]])
AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(load:NXM_OF_IP_DST[]->NXM_NX_REG1[])']],
  [1], [],
  [[ovs-ofctl: load:NXM_OF_IP_DST[]->NXM_NX_REG1[]: cannot specify source field ip_dst because prerequisites are not satisfied
]])
AT_CLEANUP

AT_SETUP([learning action - standard VLAN+MAC learning])
OVS_VSWITCHD_START(
  [add-port br0 eth0 -- set Interface eth0 type=dummy -- \
   add-port br0 eth1 -- set Interface eth1 type=dummy -- \
   add-port br0 eth2 -- set Interface eth2 type=dummy])
# 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.
AT_CHECK([ovs-appctl ofproto/trace br0 '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)' -generate], [0], [stdout])
AT_CHECK([tail -1 stdout], [0], [Datapath actions: 2,0,1
])

# 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 br0 '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.
AT_CHECK([ovs-appctl ofproto/trace br0 '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)' -generate], [0], [stdout])
AT_CHECK([tail -1 stdout], [0], [Datapath actions: 3,0,1
])

# 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

AT_SETUP([learning action - TCPv4 port learning])
OVS_VSWITCHD_START(
  [add-port br0 eth0 -- set Interface eth0 type=dummy -- \
   add-port br0 eth1 -- set Interface eth1 type=dummy -- \
   add-port br0 eth2 -- set Interface eth2 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.
AT_CHECK([ovs-appctl ofproto/trace br0 '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)' -generate], [0], [stdout])
AT_CHECK([tail -1 stdout], [0], [Datapath actions: 2,0,1
])

# 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 eth0 -- set Interface eth0 type=dummy -- \
   add-port br0 eth1 -- set Interface eth1 type=dummy -- \
   add-port br0 eth2 -- set Interface eth2 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.
AT_CHECK([ovs-appctl ofproto/trace br0 '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)' -generate], [0], [stdout])
AT_CHECK([tail -1 stdout], [0], [Datapath actions: 2,0,1
])

# 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

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
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 br0 '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