classifier: Add support for conjunctive matches.
[cascardo/ovs.git] / tests / classifier.at
1 AT_BANNER([flow classifier unit tests])
2 m4_foreach(
3   [testname],
4   [[empty],
5    [destroy-null],
6    [single-rule],
7    [rule-replacement],
8    [many-rules-in-one-list],
9    [many-rules-in-one-table],
10    [many-rules-in-two-tables],
11    [many-rules-in-five-tables]],
12   [AT_SETUP([flow classifier - m4_bpatsubst(testname, [-], [ ])])
13    AT_CHECK([ovstest test-classifier testname], [0], [], [])
14    AT_CLEANUP])])
15
16 AT_BANNER([miniflow unit tests])
17 m4_foreach(
18   [testname],
19   [[miniflow],
20    [minimask_has_extra],
21    [minimask_combine]],
22   [AT_SETUP([miniflow - m4_bpatsubst(testname, [-], [ ])])
23    AT_CHECK([ovstest test-classifier testname], [0], [], [])
24    AT_CLEANUP])])
25
26 AT_BANNER([flow classifier lookup segmentation])
27 AT_SETUP([flow classifier - lookup segmentation])
28 OVS_VSWITCHD_START
29 ADD_OF_PORTS([br0], [1], [2], [3])
30 AT_DATA([flows.txt], [dnl
31 table=0 in_port=1 priority=16,tcp,nw_dst=10.1.0.0/255.255.0.0,action=output(3)
32 table=0 in_port=1 priority=32,tcp,nw_dst=10.1.2.15,action=output(2)
33 table=0 in_port=1 priority=33,tcp,nw_dst=10.1.2.15,tp_dst=80,action=drop
34 table=0 in_port=1 priority=0,ip,action=drop
35 table=0 in_port=2 priority=16,tcp,nw_dst=192.168.0.0/255.255.0.0,action=output(1)
36 table=0 in_port=2 priority=0,ip,action=drop
37 table=0 in_port=3 priority=16,tcp,nw_src=10.1.0.0/255.255.0.0,action=output(1)
38 table=0 in_port=3 priority=0,ip,action=drop
39 ])
40 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
41 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=2,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
42 AT_CHECK([tail -2 stdout], [0],
43   [Megaflow: recirc_id=0,tcp,in_port=2,nw_dst=192.168.0.0/16,nw_frag=no
44 Datapath actions: 1
45 ])
46 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=11.1.2.15,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
47 AT_CHECK([tail -2 stdout], [0],
48   [Megaflow: recirc_id=0,ip,in_port=1,nw_dst=1.0.0.0/1.0.0.0,nw_frag=no
49 Datapath actions: drop
50 ])
51 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=10.1.2.15,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
52 AT_CHECK([tail -2 stdout], [0],
53   [Megaflow: recirc_id=0,tcp,in_port=1,nw_dst=10.1.2.15,nw_frag=no,tp_dst=80
54 Datapath actions: drop
55 ])
56 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=10.1.2.15,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=79'], [0], [stdout])
57 AT_CHECK([tail -2 stdout], [0],
58   [Megaflow: recirc_id=0,tcp,in_port=1,nw_dst=10.1.2.15,nw_frag=no,tp_dst=0x1/0x1
59 Datapath actions: 2
60 ])
61 OVS_VSWITCHD_STOP
62 AT_CLEANUP
63
64 AT_BANNER([flow classifier prefix lookup])
65 AT_SETUP([flow classifier - prefix lookup])
66 OVS_VSWITCHD_START
67 ADD_OF_PORTS([br0], [1], [2], [3])
68 AT_CHECK([ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- --id=@N1 create Flow_Table name=t0], [0], [ignore], [])
69 AT_DATA([flows.txt], [dnl
70 table=0 in_port=1 priority=16,tcp,nw_dst=10.1.0.0/255.255.0.0,action=output(3)
71 table=0 in_port=1 priority=32,tcp,nw_dst=10.1.2.0/255.255.255.0,tp_src=79,action=output(2)
72 table=0 in_port=1 priority=33,tcp,nw_dst=10.1.2.15,tp_dst=80,action=drop
73 table=0 in_port=1 priority=33,tcp,nw_dst=10.1.2.15,tp_dst=8080,action=output(2)
74 table=0 in_port=1 priority=33,tcp,nw_dst=10.1.2.15,tp_dst=192,action=output(2)
75 table=0 in_port=1 priority=0,ip,action=drop
76 table=0 in_port=2 priority=16,tcp,nw_dst=192.168.0.0/255.255.0.0,action=output(1)
77 table=0 in_port=2 priority=0,ip,action=drop
78 table=0 in_port=3 priority=16,tcp,nw_src=10.1.0.0/255.255.0.0,action=output(1)
79 table=0 in_port=3 priority=0,ip,action=drop
80 ])
81 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
82
83 # nw_dst and nw_src should be on by default
84 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
85 AT_CHECK([tail -2 stdout], [0],
86   [Megaflow: recirc_id=0,ip,in_port=1,nw_dst=192.168.0.0/16,nw_frag=no
87 Datapath actions: drop
88 ])
89
90 AT_CHECK([ovs-vsctl set Flow_Table t0 prefixes=ipv6_label], [0])
91 AT_CHECK([ovs-vsctl set Flow_Table t0 prefixes=nw_dst,nw_src,tun_dst,tun_src], [1], [],
92 [ovs-vsctl: nw_dst,nw_src,tun_dst,tun_src: 4 value(s) specified but the maximum number is 3
93 ])
94 AT_CHECK([ovs-vsctl set Flow_Table t0 prefixes=nw_dst,nw_dst], [1], [],
95 [ovs-vsctl: nw_dst,nw_dst: set contains duplicate value
96 ])
97
98 AT_CHECK([ovs-vsctl set Flow_Table t0 prefixes=nw_dst], [0])
99 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
100 AT_CHECK([tail -2 stdout], [0],
101   [Megaflow: recirc_id=0,ip,in_port=1,nw_dst=192.168.0.0/16,nw_frag=no
102 Datapath actions: drop
103 ])
104 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=2,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
105 AT_CHECK([tail -2 stdout], [0],
106   [Megaflow: recirc_id=0,tcp,in_port=2,nw_dst=192.168.0.0/16,nw_frag=no
107 Datapath actions: 1
108 ])
109 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=10.1.2.15,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
110 AT_CHECK([tail -2 stdout], [0],
111   [Megaflow: recirc_id=0,tcp,in_port=1,nw_dst=10.1.2.15,nw_frag=no,tp_dst=80
112 Datapath actions: drop
113 ])
114 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=10.1.2.15,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=79'], [0], [stdout])
115 AT_CHECK([tail -2 stdout], [0],
116   [Megaflow: recirc_id=0,tcp,in_port=1,nw_dst=10.1.2.15,nw_frag=no,tp_src=0x0/0x1,tp_dst=0x40/0xfff0
117 Datapath actions: 3
118 ])
119 AT_CHECK([ovs-vsctl set Flow_Table t0 prefixes=none], [0])
120 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=10.1.3.16,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=79'], [0], [stdout])
121 AT_CHECK([tail -2 stdout], [0],
122   [Megaflow: recirc_id=0,tcp,in_port=1,nw_dst=10.1.3.16,nw_frag=no
123 Datapath actions: 3
124 ])
125 OVS_VSWITCHD_STOP(["/'prefixes' with incompatible field: ipv6_label/d"])
126 AT_CLEANUP
127
128 AT_BANNER([conjunctive match])
129
130 AT_SETUP([single conjunctive match])
131 OVS_VSWITCHD_START
132 ADD_OF_PORTS([br0], 1, 2, 3, 4, 5)
133 AT_DATA([flows.txt], [dnl
134 conj_id=1,actions=3
135 priority=100,ip,ip_src=10.0.0.1,actions=conjunction(1,1/2)
136 priority=100,ip,ip_src=10.0.0.4,actions=conjunction(1,1/2)
137 priority=100,ip,ip_src=10.0.0.6,actions=conjunction(1,1/2)
138 priority=100,ip,ip_src=10.0.0.7,actions=conjunction(1,1/2)
139 priority=100,ip,ip_dst=10.0.0.2,actions=conjunction(1,2/2)
140 priority=100,ip,ip_dst=10.0.0.5,actions=conjunction(1,2/2)
141 priority=100,ip,ip_dst=10.0.0.7,actions=conjunction(1,2/2)
142 priority=100,ip,ip_dst=10.0.0.8,actions=conjunction(1,2/2)
143 priority=100,ip,ip_src=10.0.0.1,ip_dst=10.0.0.4,actions=4
144 priority=100,ip,ip_src=10.0.0.3,ip_dst=10.0.0.5,actions=5
145
146 priority=0 actions=2
147 ])
148 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
149 for src in 0 1 2 3 4 5 6 7; do
150     for dst in 0 1 2 3 4 5 6 7; do
151         if test $src$dst = 14; then
152             out=4
153         elif test $src$dst = 35; then
154             out=5
155         else
156             out=2
157             case $src in [[1467]]) case $dst in [[2578]]) out=3 ;; esac ;; esac
158         fi
159         AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=1,dl_type=0x0800,nw_src=10.0.0.$src,nw_dst=10.0.0.$dst"], [0], [stdout])
160         AT_CHECK_UNQUOTED([tail -1 stdout], [0], [Datapath actions: $out
161 ])
162     done
163 done
164 OVS_VSWITCHD_STOP
165 AT_CLEANUP
166
167 AT_SETUP([multiple conjunctive match])
168 OVS_VSWITCHD_START
169 ADD_OF_PORTS([br0], 1, 2, 3, 4, 5)
170 AT_DATA([flows.txt], [dnl
171 conj_id=1,actions=1
172 conj_id=2,actions=2
173 conj_id=3,actions=3
174
175 priority=5,ip,ip_src=20.0.0.0/8,actions=conjunction(1,1/2),conjunction(2,1/2)
176 priority=5,ip,ip_src=10.1.0.0/16,actions=conjunction(1,1/2),conjunction(3,2/3)
177 priority=5,ip,ip_src=10.2.0.0/16,actions=conjunction(1,1/2),conjunction(2,1/2)
178 priority=5,ip,ip_src=10.1.3.0/24,actions=conjunction(1,1/2),conjunction(3,2/3)
179 priority=5,ip,ip_src=10.1.4.5/32,actions=conjunction(1,1/2),conjunction(2,1/2)
180
181 priority=5,ip,ip_dst=20.0.0.0/8,actions=conjunction(1,2/2)
182 priority=5,ip,ip_dst=10.1.0.0/16,actions=conjunction(1,2/2)
183 priority=5,ip,ip_dst=10.2.0.0/16,actions=conjunction(1,2/2)
184 priority=5,ip,ip_dst=10.1.3.0/24,actions=conjunction(1,2/2)
185 priority=5,ip,ip_dst=10.1.4.5/32,actions=conjunction(1,2/2)
186 priority=5,ip,ip_dst=30.0.0.0/8,actions=conjunction(2,2/2),conjunction(3,1/3)
187 priority=5,ip,ip_dst=40.5.0.0/16,actions=conjunction(2,2/2),conjunction(3,1/3)
188
189 priority=5,tcp,tcp_dst=80,actions=conjunction(3,3/3)
190 priority=5,tcp,tcp_dst=443,actions=conjunction(3,3/3)
191
192 priority=5,tcp,tcp_src=80,actions=conjunction(3,3/3)
193 priority=5,tcp,tcp_src=443,actions=conjunction(3,3/3)
194
195 priority=0,actions=4
196 ])
197 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
198 for a0 in \
199     '1 20.0.0.1' \
200     '2 10.1.0.1' \
201     '3 10.2.0.1' \
202     '4 10.1.3.1' \
203     '5 10.1.4.5' \
204     '6 1.2.3.4'
205 do
206     for b0 in \
207         '1 20.0.0.1' \
208         '2 10.1.0.1' \
209         '3 10.2.0.1' \
210         '4 10.1.3.1' \
211         '5 10.1.4.5' \
212         '6 30.0.0.1' \
213         '7 40.5.0.1' \
214         '8 1.2.3.4'
215     do
216         for c0 in '1 80' '2 443' '3 8080'; do
217             for d0 in '1 80' '2 443' '3 8080'; do
218                 set $a0; a=$1 ip_src=$2
219                 set $b0; b=$1 ip_dst=$2
220                 set $c0; c=$1 tcp_src=$2
221                 set $d0; d=$1 tcp_dst=$2
222                 case $a$b$c$d in
223                     [[12345]][[12345]]??) out=1 ;;
224                     [[135]][[67]]??) out=2 ;;
225                     [[24]][[67]][[12]]? | [[24]][[67]]?[[12]]) out=3 ;;
226                     *) out=4
227                 esac
228                 AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=5,dl_type=0x0800,nw_proto=6,nw_src=$ip_src,nw_dst=$ip_dst,tcp_src=$tcp_src,tcp_dst=$tcp_dst"], [0], [stdout])
229                 AT_CHECK_UNQUOTED([tail -1 stdout], [0], [Datapath actions: $out
230 ])
231             done
232         done
233     done
234 done
235 OVS_VSWITCHD_STOP
236 AT_CLEANUP
237
238 # In conjunctive match, we can find some soft matches that turn out not to be a
239 # real match.  Usually, that's the end of the road--there is no real match.
240 # But if there is a flow identical to one of the flows that was a soft match,
241 # except with a lower priority, then we have to try again with that lower
242 # priority flow.  This test checks this special case.
243 AT_SETUP([conjunctive match priority fallback])
244 OVS_VSWITCHD_START
245 ADD_OF_PORTS([br0], 1, 2, 3, 4, 5, 6, 7)
246 AT_DATA([flows.txt], [dnl
247 conj_id=1,actions=1
248 conj_id=3,actions=3
249
250 priority=5,ip,ip_src=10.0.0.1,actions=conjunction(1,1/2)
251 priority=5,ip,ip_src=10.0.0.2,actions=conjunction(1,1/2)
252 priority=5,ip,ip_dst=10.0.0.1,actions=conjunction(1,2/2)
253 priority=5,ip,ip_dst=10.0.0.2,actions=conjunction(1,2/2)
254 priority=5,ip,ip_dst=10.0.0.3,actions=conjunction(1,2/2)
255
256 priority=4,ip,ip_src=10.0.0.3,ip_dst=10.0.0.2,actions=2
257
258 priority=3,ip,ip_src=10.0.0.1,actions=conjunction(3,1/2)
259 priority=3,ip,ip_src=10.0.0.3,actions=conjunction(3,1/2)
260 priority=3,ip,ip_dst=10.0.0.2,actions=conjunction(3,2/2)
261 priority=3,ip,ip_dst=10.0.0.3,actions=conjunction(3,2/2)
262 priority=3,ip,ip_dst=10.0.0.4,actions=conjunction(3,2/2)
263
264 priority=2,ip,ip_dst=10.0.0.1,actions=4
265
266 priority=1,ip,ip_src=10.0.0.1,ip_dst=10.0.0.5,actions=5
267
268 priority=0,actions=6
269 ])
270 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
271 for src in 0 1 2 3; do
272     for dst in 0 1 2 3 4 5; do
273         case $src$dst in
274             [[12]][[123]]) out=1 ;;
275             32) out=2 ;;
276             [[13]][[234]]) out=3 ;;
277             ?1) out=4 ;;
278             15) out=5 ;;
279             *) out=6
280         esac
281         AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=7,dl_type=0x0800,nw_src=10.0.0.$src,nw_dst=10.0.0.$dst"], [0], [stdout])
282         AT_CHECK_UNQUOTED([tail -1 stdout], [0], [Datapath actions: $out
283 ])
284     done
285 done
286 OVS_VSWITCHD_STOP
287 AT_CLEANUP