backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / tests / integrated / test_request_reply_v12.py
1 # Copyright (C) 2012 Nippon Telegraph and Telephone Corporation.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #    http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 # implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 # vim: tabstop=4 shiftwidth=4 softtabstop=4
17
18 import time
19 import logging
20
21 from ryu.controller import ofp_event
22 from ryu.controller.handler import MAIN_DISPATCHER
23 from ryu.controller.handler import set_ev_cls
24 from ryu.ofproto import ofproto_v1_2
25 from ryu.tests.integrated import tester
26
27 LOG = logging.getLogger(__name__)
28
29
30 class RunTest(tester.TestFlowBase):
31     """ Test case for Request-Reply messages.
32
33         Some tests need attached port to switch.
34         If use the OVS, can do it with the following commands.
35             # ip link add <port> type dummy
36             # ovs-vsctl add-port <bridge> <port>
37     """
38
39     OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION]
40
41     def __init__(self, *args, **kwargs):
42         super(RunTest, self).__init__(*args, **kwargs)
43
44         self._verify = None
45         self.n_tables = ofproto_v1_2.OFPTT_MAX
46
47     def start_next_test(self, dp):
48         self._verify = None
49         self.delete_all_flows(dp)
50         dp.send_barrier()
51         if len(self.pending):
52             t = self.pending.pop()
53             if self.is_supported(t):
54                 LOG.info(tester.LOG_TEST_START, t)
55                 self.current = t
56                 getattr(self, t)(dp)
57             else:
58                 self.results[t] = 'SKIP (unsupported)'
59                 self.unclear -= 1
60                 self.start_next_test(dp)
61         else:
62             self.print_results()
63
64     def run_verify(self, ev):
65         msg = ev.msg
66         dp = msg.datapath
67
68         verify_func = self.verify_default
69         v = "verify" + self.current[4:]
70         if v in dir(self):
71             verify_func = getattr(self, v)
72
73         result = verify_func(dp, msg)
74         if result is True:
75             self.unclear -= 1
76
77         self.results[self.current] = result
78         self.start_next_test(dp)
79
80     def verify_default(self, dp, msg):
81         type_ = self._verify
82
83         if msg.msg_type == dp.ofproto.OFPT_STATS_REPLY:
84             return self.verify_stats(dp, msg.body, type_)
85         elif msg.msg_type == type_:
86             return True
87         else:
88             return 'Reply msg_type %s expected %s' \
89                    % (msg.msg_type, type_)
90
91     def verify_stats(self, dp, stats, type_):
92         stats_types = dp.ofproto_parser.OFPStatsReply._STATS_TYPES
93         expect = stats_types.get(type_).__name__
94
95         if isinstance(stats, list):
96             for s in stats:
97                 if expect == s.__class__.__name__:
98                     return True
99         else:
100             if expect == stats.__class__.__name__:
101                 return True
102         return 'Reply msg has not \'%s\' class.\n%s' % (expect, stats)
103
104     def mod_flow(self, dp, cookie=0, cookie_mask=0, table_id=0,
105                  command=None, idle_timeout=0, hard_timeout=0,
106                  priority=0xff, buffer_id=0xffffffff, match=None,
107                  actions=None, inst_type=None, out_port=None,
108                  out_group=None, flags=0, inst=None):
109
110         if command is None:
111             command = dp.ofproto.OFPFC_ADD
112
113         if inst is None:
114             if inst_type is None:
115                 inst_type = dp.ofproto.OFPIT_APPLY_ACTIONS
116
117             inst = []
118             if actions is not None:
119                 inst = [dp.ofproto_parser.OFPInstructionActions(
120                         inst_type, actions)]
121
122         if match is None:
123             match = dp.ofproto_parser.OFPMatch()
124
125         if out_port is None:
126             out_port = dp.ofproto.OFPP_ANY
127
128         if out_group is None:
129             out_group = dp.ofproto.OFPG_ANY
130
131         m = dp.ofproto_parser.OFPFlowMod(dp, cookie, cookie_mask,
132                                          table_id, command,
133                                          idle_timeout, hard_timeout,
134                                          priority, buffer_id,
135                                          out_port, out_group,
136                                          flags, match, inst)
137
138         dp.send_msg(m)
139
140     def get_port(self, dp):
141         for port_no, port in dp.ports.items():
142             if port_no != dp.ofproto.OFPP_LOCAL:
143                 return port
144         return None
145
146     # Test for Reply message type
147     def test_desc_stats_request(self, dp):
148         self._verify = dp.ofproto.OFPST_DESC
149         m = dp.ofproto_parser.OFPDescStatsRequest(dp)
150         dp.send_msg(m)
151
152     def test_flow_stats_request(self, dp):
153         self._verify = dp.ofproto.OFPST_FLOW
154         self.mod_flow(dp)
155         self.send_flow_stats(dp)
156
157     def test_aggregate_stats_request(self, dp):
158         self._verify = dp.ofproto.OFPST_AGGREGATE
159         match = dp.ofproto_parser.OFPMatch()
160         m = dp.ofproto_parser.OFPAggregateStatsRequest(
161             dp, dp.ofproto.OFPTT_ALL, dp.ofproto.OFPP_ANY,
162             dp.ofproto.OFPG_ANY, 0, 0, match)
163         dp.send_msg(m)
164
165     def test_table_stats_request(self, dp):
166         self._verify = dp.ofproto.OFPST_TABLE
167         m = dp.ofproto_parser.OFPTableStatsRequest(dp)
168         dp.send_msg(m)
169
170     def test_port_stats_request(self, dp):
171         self._verify = dp.ofproto.OFPST_PORT
172         m = dp.ofproto_parser.OFPPortStatsRequest(dp, dp.ofproto.OFPP_ANY)
173         dp.send_msg(m)
174
175     def test_echo_request(self, dp):
176         self._verify = dp.ofproto.OFPT_ECHO_REPLY
177         m = dp.ofproto_parser.OFPEchoRequest(dp)
178         dp.send_msg(m)
179
180     def test_features_request(self, dp):
181         self._verify = dp.ofproto.OFPT_FEATURES_REPLY
182         m = dp.ofproto_parser.OFPFeaturesRequest(dp)
183         dp.send_msg(m)
184
185     def test_get_config_request(self, dp):
186         self._verify = dp.ofproto.OFPT_GET_CONFIG_REPLY
187         m = dp.ofproto_parser.OFPGetConfigRequest(dp)
188         dp.send_msg(m)
189
190     def test_barrier_request(self, dp):
191         self._verify = dp.ofproto.OFPT_BARRIER_REPLY
192         dp.send_barrier()
193
194     def test_error_reply(self, dp):
195         ports = [0]
196         for p in dp.ports:
197             if p != dp.ofproto.OFPP_LOCAL:
198                 ports.append(p)
199
200         port_no = max(ports) + 1
201         self._verify = dp.ofproto.OFPT_ERROR
202         m = dp.ofproto_parser.OFPPortMod(
203             dp, port_no, 'ff:ff:ff:ff:ff:ff', 0, 0, 0)
204         dp.send_msg(m)
205
206     # Test for reply value
207     def test_flow_stats_none(self, dp):
208         self.send_flow_stats(dp)
209
210     def verify_flow_stats_none(self, dp, msg):
211         stats = msg.body
212         if len(stats):
213             return 'Reply msg has body. %s' % (stats, )
214         return True
215
216     def test_flow_stats_reply_value(self, dp):
217         self._verify = []
218         c = 0
219         while c < self.n_tables:
220             # value = (talbe_id, cookie, idle_timeout, hard_timeout, priority)
221             v = (c, c + 1, c + 2, c + 3, c + 4)
222             self._verify.append(v)
223             self.mod_flow(dp, table_id=v[0], cookie=v[1],
224                           idle_timeout=v[2], hard_timeout=v[3], priority=v[4])
225             c += 1
226         dp.send_barrier()
227         self.send_flow_stats(dp)
228
229     def verify_flow_stats_reply_value(self, dp, msg):
230         c = 0
231         for f in msg.body:
232             f_value = (f.table_id, f.cookie, f.idle_timeout,
233                        f.hard_timeout, f.priority, )
234             if f_value != self._verify[c]:
235                 return 'param is mismatched. verify=%s, reply=%s' \
236                        % (self._verify[c], f_value,)
237             c += 1
238         return len(msg.body) == self.n_tables
239
240     def test_echo_request_has_data(self, dp):
241         data = 'test'
242         self._verify = data
243         m = dp.ofproto_parser.OFPEchoRequest(dp)
244         m.data = data
245         dp.send_msg(m)
246
247     def verify_echo_request_has_data(self, dp, msg):
248         data = msg.data
249         return self._verify == data
250
251     def test_aggregate_stats_flow_count(self, dp):
252         c = 0
253         while c < self.n_tables:
254             self.mod_flow(dp, table_id=c)
255             c += 1
256         dp.send_barrier()
257         match = dp.ofproto_parser.OFPMatch()
258         m = dp.ofproto_parser.OFPAggregateStatsRequest(
259             dp, dp.ofproto.OFPTT_ALL, dp.ofproto.OFPP_ANY,
260             dp.ofproto.OFPG_ANY, 0, 0, match)
261         dp.send_msg(m)
262
263     def verify_aggregate_stats_flow_count(self, dp, msg):
264         stats = msg.body
265         return stats.flow_count == self.n_tables
266
267     def test_aggregate_stats_flow_count_out_port(self, dp):
268         actions = [dp.ofproto_parser.OFPActionOutput(1, 1500)]
269         self.mod_flow(dp, table_id=1, actions=actions)
270
271         actions = [dp.ofproto_parser.OFPActionOutput(2, 1500)]
272         self.mod_flow(dp, table_id=2, actions=actions)
273         dp.send_barrier()
274
275         out_port = 2
276         match = dp.ofproto_parser.OFPMatch()
277         m = dp.ofproto_parser.OFPAggregateStatsRequest(
278             dp, dp.ofproto.OFPTT_ALL, out_port,
279             dp.ofproto.OFPG_ANY, 0, 0, match)
280         dp.send_msg(m)
281
282     def verify_aggregate_stats_flow_count_out_port(self, dp, msg):
283         stats = msg.body
284         return stats.flow_count == 1
285
286     def test_aggregate_stats_packet_count(self, dp):
287         in_port = 1
288         data = 'test'
289         self._verify = {'packet_count': 1,
290                         'byte_count': len(data)}
291
292         # add flow
293         match = dp.ofproto_parser.OFPMatch()
294         match.set_in_port(in_port)
295         self.mod_flow(dp, table_id=0, match=match)
296
297         # packet out
298         output = dp.ofproto.OFPP_TABLE
299         actions = [dp.ofproto_parser.OFPActionOutput(output, 0)]
300         m = dp.ofproto_parser.OFPPacketOut(dp, 0xffffffff, in_port,
301                                            actions, data)
302         dp.send_msg(m)
303         dp.send_barrier()
304
305         match = dp.ofproto_parser.OFPMatch()
306         m = dp.ofproto_parser.OFPAggregateStatsRequest(
307             dp, dp.ofproto.OFPTT_ALL, dp.ofproto.OFPP_ANY,
308             dp.ofproto.OFPG_ANY, 0, 0, match)
309         dp.send_msg(m)
310
311     def verify_aggregate_stats_packet_count(self, dp, msg):
312         for name, val in self._verify.items():
313             r_val = getattr(msg.body, name)
314             if val != r_val:
315                 return '%s is mismatched. verify=%s, reply=%s' \
316                     % (name, val, r_val)
317         return True
318
319     def test_set_config_nomal(self, dp):
320         flags = dp.ofproto.OFPC_FRAG_NORMAL
321         self._verify = flags
322         m = dp.ofproto_parser.OFPSetConfig(dp, flags, 0)
323         dp.send_msg(m)
324         dp.send_barrier()
325
326         m = dp.ofproto_parser.OFPGetConfigRequest(dp)
327         dp.send_msg(m)
328
329     def verify_set_config_nomal(self, dp, msg):
330         return self._verify == msg.flags
331
332     def test_set_config_drop(self, dp):
333         flags = dp.ofproto.OFPC_FRAG_DROP
334         self._verify = flags
335         m = dp.ofproto_parser.OFPSetConfig(dp, flags, 0)
336         dp.send_msg(m)
337         dp.send_barrier()
338
339         m = dp.ofproto_parser.OFPGetConfigRequest(dp)
340         dp.send_msg(m)
341
342     def verify_set_config_drop(self, dp, msg):
343         return self._verify == msg.flags
344
345     def test_set_config_mask(self, dp):
346         flags = dp.ofproto.OFPC_FRAG_MASK
347         self._verify = flags
348         m = dp.ofproto_parser.OFPSetConfig(dp, flags, 0)
349         dp.send_msg(m)
350         dp.send_barrier()
351
352         m = dp.ofproto_parser.OFPGetConfigRequest(dp)
353         dp.send_msg(m)
354
355     def verify_set_config_mask(self, dp, msg):
356         return self._verify == msg.flags
357
358     def test_set_config_ttl_to_controller(self, dp):
359         flags = dp.ofproto.OFPC_INVALID_TTL_TO_CONTROLLER
360         self._verify = flags
361         m = dp.ofproto_parser.OFPSetConfig(dp, flags, 0)
362         dp.send_msg(m)
363         dp.send_barrier()
364
365         m = dp.ofproto_parser.OFPGetConfigRequest(dp)
366         dp.send_msg(m)
367
368     def verify_set_config_ttl_to_controller(self, dp, msg):
369         return self._verify == msg.flags
370
371     def test_set_config_miss_send_len(self, dp):
372         flags = dp.ofproto.OFPC_FRAG_NORMAL
373         ms_len = 256
374         self._verify = ms_len
375         m = dp.ofproto_parser.OFPSetConfig(dp, flags, ms_len)
376         dp.send_msg(m)
377         dp.send_barrier()
378
379         m = dp.ofproto_parser.OFPGetConfigRequest(dp)
380         dp.send_msg(m)
381
382     def verify_set_config_miss_send_len(self, dp, msg):
383         return self._verify == msg.miss_send_len
384
385     def test_set_config_miss_send_len_max(self, dp):
386         flags = dp.ofproto.OFPC_FRAG_NORMAL
387         ms_len = dp.ofproto.OFPCML_MAX
388         self._verify = ms_len
389         m = dp.ofproto_parser.OFPSetConfig(dp, flags, ms_len)
390         dp.send_msg(m)
391         dp.send_barrier()
392
393         m = dp.ofproto_parser.OFPGetConfigRequest(dp)
394         dp.send_msg(m)
395
396     def verify_set_config_miss_send_len_max(self, dp, msg):
397         return self._verify == msg.miss_send_len
398
399     def test_set_config_no_buffer(self, dp):
400         flags = dp.ofproto.OFPC_FRAG_NORMAL
401         ms_len = dp.ofproto.OFPCML_NO_BUFFER
402         self._verify = ms_len
403         m = dp.ofproto_parser.OFPSetConfig(dp, flags, ms_len)
404         dp.send_msg(m)
405         dp.send_barrier()
406
407         m = dp.ofproto_parser.OFPGetConfigRequest(dp)
408         dp.send_msg(m)
409
410     def verify_set_config_no_buffer(self, dp, msg):
411         return self._verify == msg.miss_send_len
412
413     def _verify_flow_inst_type(self, dp, msg):
414         inst_type = self._verify
415         stats = msg.body
416
417         for s in stats:
418             for i in s.instructions:
419                 if i.type == inst_type:
420                     return True
421         return 'not found inst_type[%s]' % (inst_type, )
422
423     def test_flow_add_apply_actions(self, dp):
424         inst_type = dp.ofproto.OFPIT_APPLY_ACTIONS
425         self._verify = inst_type
426
427         actions = [dp.ofproto_parser.OFPActionOutput(1, 1500)]
428         self.mod_flow(dp, actions=actions, inst_type=inst_type)
429         self.send_flow_stats(dp)
430
431     def verify_flow_add_apply_actions(self, dp, msg):
432         return self._verify_flow_inst_type(dp, msg)
433
434     def test_flow_add_goto_table(self, dp):
435         self._verify = dp.ofproto.OFPIT_GOTO_TABLE
436
437         inst = [dp.ofproto_parser.OFPInstructionGotoTable(1), ]
438         self.mod_flow(dp, inst=inst)
439         self.send_flow_stats(dp)
440
441     def verify_flow_add_goto_table(self, dp, msg):
442         return self._verify_flow_inst_type(dp, msg)
443
444     def _verify_flow_value(self, dp, msg):
445         stats = msg.body
446         verify = self._verify
447
448         if len(verify) != len(stats):
449             return 'flow_count is mismatched. verify=%s stats=%s' \
450                    % (len(verify), len(stats))
451
452         for s in stats:
453             v_port = -1
454             v = verify.get(s.table_id, None)
455             if v:
456                 v_port = v[3].port
457
458             s_port = s.instructions[0].actions[0].port
459
460             if v_port != s_port:
461                 return 'port is mismatched. table_id=%s verify=%s, stats=%s' \
462                        % (s.table_id, v_port, s_port)
463         return True
464
465     def _add_flow_for_flow_mod_tests(self, dp):
466         a1 = dp.ofproto_parser.OFPActionOutput(1, 1500)
467         a2 = dp.ofproto_parser.OFPActionOutput(2, 1500)
468
469         # table_id, cookie, priority, dl_dst, action)
470         tables = {0: [0xffff, 10, b'\xee' * 6, a1],
471                   1: [0xff00, 10, b'\xee' * 6, a2],
472                   2: [0xf000, 100, b'\xee' * 6, a1],
473                   3: [0x0000, 10, b'\xff' * 6, a1]}
474
475         self._verify = tables
476         for table_id, val in tables.items():
477             match = dp.ofproto_parser.OFPMatch()
478             match.set_dl_dst(val[2])
479             self.mod_flow(dp, match=match, actions=[val[3]],
480                           table_id=table_id, cookie=val[0], priority=val[1])
481         dp.send_barrier()
482
483     def test_flow_mod_table_id(self, dp):
484         self._add_flow_for_flow_mod_tests(dp)
485
486         # modify flow of table_id=3
487         action = dp.ofproto_parser.OFPActionOutput(3, 1500)
488         self._verify[3][3] = action
489
490         table_id = 3
491         self.mod_flow(dp, command=dp.ofproto.OFPFC_MODIFY,
492                       actions=[action], table_id=table_id)
493
494         dp.send_barrier()
495         self.send_flow_stats(dp)
496
497     def verify_flow_mod_table_id(self, dp, msg):
498         return self._verify_flow_value(dp, msg)
499
500     def test_flow_mod_cookie(self, dp):
501         self._add_flow_for_flow_mod_tests(dp)
502
503         # modify flow of table_id=1
504         action = dp.ofproto_parser.OFPActionOutput(3, 1500)
505         self._verify[1][3] = action
506
507         cookie = 0xff00
508         cookie_mask = 0xffff
509         table_id = 1
510         self.mod_flow(dp, command=dp.ofproto.OFPFC_MODIFY,
511                       actions=[action], table_id=table_id,
512                       cookie=cookie, cookie_mask=cookie_mask)
513
514         dp.send_barrier()
515         self.send_flow_stats(dp)
516
517     def verify_flow_mod_cookie(self, dp, msg):
518         return self._verify_flow_value(dp, msg)
519
520     def test_flow_mod_cookie_mask(self, dp):
521         self._add_flow_for_flow_mod_tests(dp)
522
523         # modify flow of table_id=0,1
524         action = dp.ofproto_parser.OFPActionOutput(3, 1500)
525         self._verify[0][3] = action
526         self._verify[1][3] = action
527
528         cookie = 0xffff
529         cookie_mask = 0xff00
530         for table_id in range(2):
531             self.mod_flow(dp, command=dp.ofproto.OFPFC_MODIFY,
532                           actions=[action], table_id=table_id,
533                           cookie=cookie, cookie_mask=cookie_mask)
534
535         dp.send_barrier()
536         self.send_flow_stats(dp)
537
538     def verify_flow_mod_cookie_mask(self, dp, msg):
539         return self._verify_flow_value(dp, msg)
540
541     def test_flow_mod_match(self, dp):
542         self._add_flow_for_flow_mod_tests(dp)
543
544         # modify flow of table_id=3
545         action = dp.ofproto_parser.OFPActionOutput(3, 1500)
546         self._verify[3][3] = action
547
548         match = dp.ofproto_parser.OFPMatch()
549         match.set_dl_dst(b'\xff' * 6)
550         table_id = 3
551         self.mod_flow(dp, command=dp.ofproto.OFPFC_MODIFY,
552                       actions=[action], table_id=table_id, match=match)
553
554         dp.send_barrier()
555         self.send_flow_stats(dp)
556
557     def verify_flow_mod_match(self, dp, msg):
558         return self._verify_flow_value(dp, msg)
559
560     def test_flow_mod_strict(self, dp):
561         self._add_flow_for_flow_mod_tests(dp)
562
563         # modify flow of table_id=2
564         action = dp.ofproto_parser.OFPActionOutput(3, 1500)
565         self._verify[2][3] = action
566
567         match = dp.ofproto_parser.OFPMatch()
568         match.set_dl_dst(b'\xee' * 6)
569         priority = 100
570         table_id = 2
571         self.mod_flow(dp, command=dp.ofproto.OFPFC_MODIFY_STRICT,
572                       actions=[action], table_id=table_id,
573                       match=match, priority=priority)
574
575         dp.send_barrier()
576         self.send_flow_stats(dp)
577
578     def verify_flow_mod_strict(self, dp, msg):
579         return self._verify_flow_value(dp, msg)
580
581     def test_flow_del_table_id(self, dp):
582         self._add_flow_for_flow_mod_tests(dp)
583
584         # delete flow of table_id=3
585         del self._verify[3]
586
587         table_id = 3
588         self.mod_flow(dp, command=dp.ofproto.OFPFC_DELETE,
589                       table_id=table_id)
590
591         dp.send_barrier()
592         self.send_flow_stats(dp)
593
594     def verify_flow_del_table_id(self, dp, msg):
595         return self._verify_flow_value(dp, msg)
596
597     def test_flow_del_table_id_all(self, dp):
598         self._add_flow_for_flow_mod_tests(dp)
599
600         # delete all flows
601         self._verify = {}
602
603         self.mod_flow(dp, command=dp.ofproto.OFPFC_DELETE,
604                       table_id=dp.ofproto.OFPTT_ALL)
605
606         dp.send_barrier()
607         self.send_flow_stats(dp)
608
609     def verify_flow_del_table_id_all(self, dp, msg):
610         return self._verify_flow_value(dp, msg)
611
612     def test_flow_del_cookie(self, dp):
613         self._add_flow_for_flow_mod_tests(dp)
614
615         # delete flow of table_id=1
616         del self._verify[1]
617
618         cookie = 0xff00
619         cookie_mask = 0xffff
620         self.mod_flow(dp, command=dp.ofproto.OFPFC_DELETE,
621                       table_id=dp.ofproto.OFPTT_ALL,
622                       cookie=cookie, cookie_mask=cookie_mask)
623
624         dp.send_barrier()
625         self.send_flow_stats(dp)
626
627     def verify_flow_del_cookie(self, dp, msg):
628         return self._verify_flow_value(dp, msg)
629
630     def test_flow_del_cookie_mask(self, dp):
631         self._add_flow_for_flow_mod_tests(dp)
632
633         # delete flow of table_id=0,1
634         del self._verify[0]
635         del self._verify[1]
636
637         cookie = 0xffff
638         cookie_mask = 0xff00
639         self.mod_flow(dp, command=dp.ofproto.OFPFC_DELETE,
640                       table_id=dp.ofproto.OFPTT_ALL,
641                       cookie=cookie, cookie_mask=cookie_mask)
642
643         dp.send_barrier()
644         self.send_flow_stats(dp)
645
646     def verify_flow_del_cookie_mask(self, dp, msg):
647         return self._verify_flow_value(dp, msg)
648
649     def test_flow_del_match(self, dp):
650         self._add_flow_for_flow_mod_tests(dp)
651
652         # delete flow of table_id=3
653         del self._verify[3]
654
655         match = dp.ofproto_parser.OFPMatch()
656         match.set_dl_dst(b'\xff' * 6)
657         self.mod_flow(dp, command=dp.ofproto.OFPFC_DELETE,
658                       table_id=dp.ofproto.OFPTT_ALL, match=match)
659
660         dp.send_barrier()
661         self.send_flow_stats(dp)
662
663     def verify_flow_del_match(self, dp, msg):
664         return self._verify_flow_value(dp, msg)
665
666     def test_flow_del_out_port(self, dp):
667         self._add_flow_for_flow_mod_tests(dp)
668
669         # delete flow of table_id=1
670         del self._verify[1]
671
672         out_port = 2
673         self.mod_flow(dp, command=dp.ofproto.OFPFC_DELETE,
674                       table_id=dp.ofproto.OFPTT_ALL, out_port=out_port)
675
676         dp.send_barrier()
677         self.send_flow_stats(dp)
678
679     def verify_flow_del_out_port(self, dp, msg):
680         return self._verify_flow_value(dp, msg)
681
682     def test_flow_del_strict(self, dp):
683         self._add_flow_for_flow_mod_tests(dp)
684
685         # delete flow of table_id=2
686         del self._verify[2]
687
688         match = dp.ofproto_parser.OFPMatch()
689         match.set_dl_dst(b'\xee' * 6)
690         priority = 100
691         self.mod_flow(dp, command=dp.ofproto.OFPFC_DELETE_STRICT,
692                       table_id=dp.ofproto.OFPTT_ALL,
693                       match=match, priority=priority)
694
695         dp.send_barrier()
696         self.send_flow_stats(dp)
697
698     def verify_flow_del_strict(self, dp, msg):
699         return self._verify_flow_value(dp, msg)
700
701     def _send_port_mod(self, dp, config, mask):
702         p = self.get_port(dp)
703         if not p:
704             err = 'need attached port to switch.'
705             self.results[self.current] = err
706             self.start_next_test(dp)
707             return
708
709         self._verify = [p.port_no, config & mask]
710         m = dp.ofproto_parser.OFPPortMod(dp, p.port_no, p.hw_addr,
711                                          config, mask, 0)
712         dp.send_msg(m)
713         dp.send_barrier()
714
715         # TODO: waiting to port UP|DOWN.
716         time.sleep(1)
717         m = dp.ofproto_parser.OFPFeaturesRequest(dp)
718         dp.send_msg(m)
719
720     def _verify_port_mod_config(self, dp, msg):
721         port_no = self._verify[0]
722         config = self._verify[1]
723
724         port = msg.ports[port_no]
725         if config != port.config:
726             return "config is mismatched. verify=%s, stats=%s" \
727                 % (bin(config), bin(port.config))
728         return True
729
730     def test_port_mod_config_01_all(self, dp):
731         config = 0b1100101
732         mask = 0b1111111
733         self._send_port_mod(dp, config, mask)
734
735     def verify_port_mod_config_01_all(self, dp, msg):
736         return self._verify_port_mod_config(dp, msg)
737
738     def test_port_mod_config_02_none(self, dp):
739         config = 0
740         mask = 0b1111111
741         self._send_port_mod(dp, config, mask)
742
743     def verify_port_mod_config_02_none(self, dp, msg):
744         return self._verify_port_mod_config(dp, msg)
745
746     def test_port_mod_config_03_mask(self, dp):
747         config = 0b1100101
748         mask = 0b1111000
749         self._send_port_mod(dp, config, mask)
750
751     def verify_port_mod_config_03_mask(self, dp, msg):
752         res = self._verify_port_mod_config(dp, msg)
753         # reset port config
754         port_no = self._verify[0]
755         p = msg.ports[port_no]
756         m = dp.ofproto_parser.OFPPortMod(dp, p.port_no, p.hw_addr,
757                                          0, 0b1111111, 0)
758         dp.send_msg(m)
759         dp.send_barrier()
760         return res
761
762     def test_port_stats_port_no(self, dp):
763         p = self.get_port(dp)
764         if not p:
765             err = 'need attached port to switch.'
766             self.results[self.current] = err
767             self.start_next_test(dp)
768             return
769
770         self._verify = p.port_no
771         m = dp.ofproto_parser.OFPPortStatsRequest(dp, p.port_no)
772         dp.send_msg(m)
773
774     def verify_port_stats_port_no(self, dp, msg):
775         ports = msg.body
776         if len(ports) > 1:
777             return 'reply some ports.\n%s' % (ports)
778
779         if ports[0].port_no != self._verify:
780             return 'port_no is mismatched. request=%s reply=%s' \
781                 % (self._verify, ports[0].port_no)
782
783         return True
784
785     def _add_flow_flow_removed(self, dp, reason, table_id=0,
786                                cookie=0xff, priority=100, in_port=1,
787                                idle_timeout=0, hard_timeout=0):
788         self._verify = {}
789         self._verify['params'] = {'reason': reason,
790                                   'table_id': table_id,
791                                   'cookie': cookie,
792                                   'priority': priority}
793         self._verify['in_port'] = in_port
794         self._verify['timeout'] = idle_timeout
795         if hard_timeout:
796             if (idle_timeout == 0 or idle_timeout > hard_timeout):
797                 self._verify['timeout'] = hard_timeout
798
799         match = dp.ofproto_parser.OFPMatch()
800         match.set_in_port(in_port)
801         self.mod_flow(dp, match=match, cookie=cookie,
802                       priority=priority, table_id=table_id,
803                       idle_timeout=idle_timeout, hard_timeout=hard_timeout,
804                       flags=dp.ofproto.OFPFF_SEND_FLOW_REM)
805
806     def _verify_flow_removed(self, dp, msg):
807         params = self._verify['params']
808         in_port = self._verify['in_port']
809         timeout = self._verify['timeout']
810
811         if timeout:
812             duration_nsec = (msg.duration_sec * 10 ** 9) + msg.duration_nsec
813             timeout_nsec = timeout * 10 ** 9
814
815             # grace of -0.5 and +1.5 second to timeout.
816             l = (timeout - 0.5) * 10 ** 9
817             h = (timeout + 1.5) * 10 ** 9
818             if not l < duration_nsec < h:
819                 return 'bad duration time. set=%s(nsec), duration=%s(nsec)' \
820                     % (timeout_nsec, duration_nsec)
821
822         for name, val in params.items():
823             r_val = getattr(msg, name)
824             if val != r_val:
825                 return '%s is mismatched. verify=%s, reply=%s' \
826                     % (name, val, r_val)
827
828         for f in msg.match.fields:
829             if f.header == ofproto_v1_2.OXM_OF_IN_PORT:
830                 if f.value != in_port:
831                     return 'in_port is mismatched. verify=%s, reply=%s' \
832                         % (in_port, f.value)
833         return True
834
835     def test_flow_removed_idle_timeout(self, dp):
836         reason = dp.ofproto.OFPRR_IDLE_TIMEOUT
837         idle_timeout = 2
838         self._add_flow_flow_removed(dp, reason,
839                                     idle_timeout=idle_timeout)
840
841     def verify_flow_removed_idle_timeout(self, dp, msg):
842         return self._verify_flow_removed(dp, msg)
843
844     def test_flow_removed_idle_timeout_hit(self, dp):
845         reason = dp.ofproto.OFPRR_IDLE_TIMEOUT
846         idle_timeout = 5
847         in_port = 1
848         sleep = 2
849
850         # add target flow
851         self._add_flow_flow_removed(dp, reason, in_port=in_port,
852                                     idle_timeout=idle_timeout)
853         self._verify['timeout'] = idle_timeout + sleep
854
855         # sleep
856         time.sleep(sleep)
857
858         # packet out
859         output = dp.ofproto.OFPP_TABLE
860         actions = [dp.ofproto_parser.OFPActionOutput(output, 0)]
861         m = dp.ofproto_parser.OFPPacketOut(dp, 0xffffffff, in_port,
862                                            actions, None)
863         dp.send_msg(m)
864
865     def verify_flow_removed_idle_timeout_hit(self, dp, msg):
866         return self._verify_flow_removed(dp, msg)
867
868     def test_flow_removed_hard_timeout(self, dp):
869         reason = dp.ofproto.OFPRR_HARD_TIMEOUT
870         hard_timeout = 2
871         self._add_flow_flow_removed(dp, reason,
872                                     hard_timeout=hard_timeout)
873
874     def verify_flow_removed_hard_timeout(self, dp, msg):
875         return self._verify_flow_removed(dp, msg)
876
877     def test_flow_removed_hard_timeout_hit(self, dp):
878         reason = dp.ofproto.OFPRR_HARD_TIMEOUT
879         hard_timeout = 5
880         in_port = 1
881         sleep = 2
882
883         self._add_flow_flow_removed(dp, reason, in_port=in_port,
884                                     hard_timeout=hard_timeout)
885         dp.send_barrier()
886
887         # sleep
888         time.sleep(sleep)
889
890         # packet out
891         output = dp.ofproto.OFPP_TABLE
892         actions = [dp.ofproto_parser.OFPActionOutput(output, 0)]
893         m = dp.ofproto_parser.OFPPacketOut(dp, 0xffffffff, in_port,
894                                            actions, None)
895         dp.send_msg(m)
896
897     def verify_flow_removed_hard_timeout_hit(self, dp, msg):
898         return self._verify_flow_removed(dp, msg)
899
900     def test_flow_removed_delete(self, dp):
901         reason = dp.ofproto.OFPRR_DELETE
902         self._add_flow_flow_removed(dp, reason)
903         dp.send_barrier()
904         self.delete_all_flows(dp)
905
906     def verify_flow_removed_delete(self, dp, msg):
907         return self._verify_flow_removed(dp, msg)
908
909     def test_flow_removed_table_id(self, dp):
910         reason = dp.ofproto.OFPRR_DELETE
911         table_id = 1
912         self._add_flow_flow_removed(dp, reason, table_id=table_id)
913         dp.send_barrier()
914         self.delete_all_flows(dp)
915
916     def verify_flow_removed_table_id(self, dp, msg):
917         return self._verify_flow_removed(dp, msg)
918
919     def _send_packet_out(self, dp, buffer_id=0xffffffff,
920                          in_port=None, output=None, data=''):
921         if in_port is None:
922             in_port = dp.ofproto.OFPP_LOCAL
923
924         if output is None:
925             output = dp.ofproto.OFPP_CONTROLLER
926
927         self._verify['in_port'] = in_port
928         self._verify['data'] = data
929
930         actions = [dp.ofproto_parser.OFPActionOutput(output, len(data))]
931         m = dp.ofproto_parser.OFPPacketOut(dp, buffer_id, in_port,
932                                            actions, data)
933         dp.send_msg(m)
934
935     def _verify_packet_in(self, dp, msg):
936         for name, val in self._verify.items():
937             if name == 'in_port':
938                 for f in msg.match.fields:
939                     if f.header == ofproto_v1_2.OXM_OF_IN_PORT:
940                         r_val = f.value
941             else:
942                 r_val = getattr(msg, name)
943
944             if val != r_val:
945                 return '%s is mismatched. verify=%s, reply=%s' \
946                     % (name, val, r_val)
947         return True
948
949     def test_packet_in_action(self, dp):
950         self._verify = {}
951         self._verify['reason'] = dp.ofproto.OFPR_ACTION
952         self._send_packet_out(dp)
953
954     def verify_packet_in_action(self, dp, msg):
955         return self._verify_packet_in(dp, msg)
956
957     def test_packet_in_data(self, dp):
958         self._verify = {}
959         self._verify['reason'] = dp.ofproto.OFPR_ACTION
960         data = 'test'
961         self._send_packet_out(dp, data=data)
962
963     def verify_packet_in_data(self, dp, msg):
964         return self._verify_packet_in(dp, msg)
965
966     def test_packet_in_table_id(self, dp):
967         in_port = 1
968         table_id = 2
969         output = dp.ofproto.OFPP_TABLE
970
971         self._verify = {}
972         self._verify['reason'] = dp.ofproto.OFPR_ACTION
973         self._verify['table_id'] = table_id
974
975         # add flow (goto_table)
976         match = dp.ofproto_parser.OFPMatch()
977         match.set_in_port(in_port)
978         inst = [dp.ofproto_parser.OFPInstructionGotoTable(table_id)]
979         self.mod_flow(dp, inst=inst, match=match)
980
981         # add flow (output)
982         match = dp.ofproto_parser.OFPMatch()
983         match.set_in_port(in_port)
984         out = dp.ofproto.OFPP_CONTROLLER
985         actions = [dp.ofproto_parser.OFPActionOutput(out, 0)]
986         self.mod_flow(dp, actions=actions, match=match, table_id=table_id)
987         dp.send_barrier()
988
989         # packet out
990         self._send_packet_out(dp, in_port=in_port, output=output)
991
992     def verify_packet_in_table_id(self, dp, msg):
993         return self._verify_packet_in(dp, msg)
994
995     # handler
996     @set_ev_cls(ofp_event.EventOFPEchoReply, MAIN_DISPATCHER)
997     def echo_replay_handler(self, ev):
998         if self.current.find('echo_request') > 0:
999             self.run_verify(ev)
1000
1001     @set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER)
1002     def stats_reply_handler(self, ev):
1003         if self.current is None:
1004             msg = ev.msg
1005             dp = msg.datapath
1006             if self._verify == dp.ofproto.OFPST_TABLE:
1007                 self.table_stats = msg.body
1008             self.start_next_test(dp)
1009         else:
1010             self.run_verify(ev)
1011
1012     @set_ev_cls(ofp_event.EventOFPSwitchFeatures, MAIN_DISPATCHER)
1013     def features_replay_handler(self, ev):
1014         if self.current is None:
1015             pass
1016         else:
1017             self.run_verify(ev)
1018
1019     @set_ev_cls(ofp_event.EventOFPGetConfigReply, MAIN_DISPATCHER)
1020     def get_config_replay_handler(self, ev):
1021         self.run_verify(ev)
1022
1023     @set_ev_cls(ofp_event.EventOFPBarrierReply, MAIN_DISPATCHER)
1024     def barrier_replay_handler(self, ev):
1025         if self.current == 'test_barrier_request':
1026             self.run_verify(ev)
1027
1028     @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER)
1029     def port_status_handler(self, ev):
1030         pass
1031
1032     @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
1033     def packet_in_handler(self, ev):
1034         if self.current.find('packet_in'):
1035             self.run_verify(ev)
1036
1037     @set_ev_cls(ofp_event.EventOFPFlowRemoved, MAIN_DISPATCHER)
1038     def flow_removed_handler(self, ev):
1039         if self.current.find('flow_removed') > 0:
1040             self.run_verify(ev)
1041
1042     @set_ev_cls(ofp_event.EventOFPErrorMsg, MAIN_DISPATCHER)
1043     def error_handler(self, ev):
1044         if self.current.find('error') > 0:
1045             self.run_verify(ev)
1046
1047     def is_supported(self, t):
1048         unsupported = [
1049         ]
1050         for u in unsupported:
1051             if t.find(u) != -1:
1052                 return False
1053
1054         return True