backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / tests / unit / lib / test_ofctl_action_match.py
1 # Copyright (C) 2014 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 from __future__ import print_function
17
18 import unittest
19 import logging
20 import netaddr
21 import functools
22 import inspect
23
24 from nose.tools import *
25
26 from ryu.lib import addrconv
27 from ryu.lib import ofctl_v1_0
28 from ryu.ofproto import ofproto_v1_0, ofproto_v1_0_parser
29 from ryu.lib import ofctl_v1_2
30 from ryu.ofproto import ofproto_v1_2, ofproto_v1_2_parser
31 from ryu.lib import ofctl_v1_3
32 from ryu.ofproto import ofproto_v1_3, ofproto_v1_3_parser
33 from ryu.ofproto import ofproto_protocol
34 from ryu.ofproto import inet
35 from ryu.tests import test_lib
36
37 LOG = logging.getLogger('test_ofctl_v1_2, v1_3')
38
39 """ Common Functions """
40
41
42 def _str_to_int(v):
43     try:
44         return int(v, 0)
45     except (ValueError, TypeError):
46         return v
47
48
49 def _to_match_eth(value):
50     if '/' in value:
51         value = value.split('/')
52         return value[0], value[1]
53     else:
54         return value, None
55
56
57 def _to_match_ip(value):
58     if '/' in value:
59         ip = netaddr.ip.IPNetwork(value)
60         ip_addr = str(ip.network)
61         ip_mask = str(ip.netmask)
62         return ip_addr, ip_mask
63     else:
64         return value, None
65
66
67 def _to_match_masked_int(value):
68     if isinstance(value, str) and '/' in value:
69         value = value.split('/')
70         return _str_to_int(value[0]), _str_to_int(value[1])
71     else:
72         return _str_to_int(value), None
73
74
75 def _to_masked_int_str(value):
76     v, m = _to_match_masked_int(value)
77     v &= m
78     return '%d/%d' % (v, m)
79
80
81 conv_of10_to_of12_dict = {
82     'dl_dst': 'eth_dst',
83     'dl_src': 'eth_src',
84     'dl_type': 'eth_type',
85     'dl_vlan': 'vlan_vid',
86     'nw_src': 'ipv4_src',
87     'nw_dst': 'ipv4_dst',
88     'nw_proto': 'ip_proto'
89 }
90
91
92 conv_of12_to_of10_dict = {
93     'eth_src': 'dl_src',
94     'eth_dst': 'dl_dst',
95     'eth_type': 'dl_type',
96     'ipv4_dst': 'nw_dst',
97     'ipv4_src': 'nw_src',
98     'ip_proto': 'nw_proto',
99     'vlan_vid': 'dl_vlan',
100     'tcp_src': 'tp_src',
101     'tcp_dst': 'tp_dst',
102     'udp_src': 'tp_src',
103     'udp_dst': 'tp_dst'
104 }
105
106 """ Test_ofctl """
107
108
109 class Test_ofctl(unittest.TestCase):
110
111     def __init__(self, methodName):
112         super(Test_ofctl, self).__init__(methodName)
113
114     def setUp(self):
115         pass
116
117     def tearDown(self):
118         pass
119
120     def _test_actions(self, act, test):
121         dp = ofproto_protocol.ProtocolDesc(version=test.ver)
122         act_type = act["type"]
123
124         # str -> action
125         insts = test.to_actions(dp, [act])
126
127         if test.ver == ofproto_v1_0.OFP_VERSION:
128             action = insts[0]
129             self._equal_str_to_act(action, act, act_type, test)
130         else:
131             inst = insts[0]
132             self._equal_str_to_inst(inst, act, act_type, test)
133
134         # action -> str
135         inst_str = test.actions_to_str(insts)
136         if test.ver == ofproto_v1_0.OFP_VERSION:
137             act_str = inst_str
138             self._equal_act_to_str(act_str, act, act_type, test)
139         else:
140             self._equal_inst_to_str(inst_str, act, act_type, test)
141
142     def _test_match(self, attrs, test):
143         dp = ofproto_protocol.ProtocolDesc(version=test.ver)
144
145         # str -> match
146         match = test.to_match(dp, attrs)
147
148         for key, value in attrs.items():
149             key = self._conv_key(test, key, attrs)
150             self._equal_str_to_match(key, value, match, test)
151
152         # match -> str
153         match_str = test.match_to_str(match)
154
155         for key, value in attrs.items():
156             if key in conv_of12_to_of10_dict:
157                 key_old = conv_of12_to_of10_dict[key]
158             else:
159                 key_old = key
160             self._equal_match_to_str(key_old, value, match_str, test)
161
162     def _equal_str_to_inst(self, inst, act, act_type, test):
163         if act_type in test.supported_action:
164             cls = test.supported_action[act_type]
165         else:
166             cls = None
167         if act_type == 'GOTO_TABLE':
168             ok_(isinstance(inst, cls))
169             eq_(inst.table_id, act["table_id"])
170         elif act_type == 'WRITE_METADATA':
171             ok_(isinstance(inst, cls))
172             eq_(inst.metadata, act["metadata"])
173             eq_(inst.metadata_mask, act["metadata_mask"])
174         elif act_type == 'METER':
175             ok_(isinstance(inst, cls))
176             eq_(inst.meter_id, act["meter_id"])
177         elif act_type == 'WRITE_ACTIONS':
178             ok_(isinstance(inst, cls))
179             eq_(inst.type, test._ofproto.OFPIT_WRITE_ACTIONS)
180             self._equal_str_to_act(inst.actions[0],
181                                    act["actions"][0],
182                                    act["actions"][0]["type"],
183                                    test)
184         elif act_type == 'CLEAR_ACTIONS':
185             ok_(isinstance(inst, cls))
186             eq_(inst.type, test._ofproto.OFPIT_CLEAR_ACTIONS)
187         else:
188             # APPLY_ACTIONS or Uknown Action Type
189             ok_(isinstance(inst, test._parser.OFPInstructionActions))
190             eq_(inst.type, test._ofproto.OFPIT_APPLY_ACTIONS)
191             self._equal_str_to_act(inst.actions[0], act,
192                                    act_type, test)
193
194     def _equal_str_to_act(self, action, act, act_type, test):
195         if act_type in test.supported_action:
196             cls = test.supported_action[act_type]
197         else:
198             cls = None
199         ok_(isinstance(action, cls))
200         if act_type == 'OUTPUT':
201             eq_(action.port, act["port"])
202         elif act_type == 'SET_VLAN_VID':
203             eq_(action.vlan_vid, act["vlan_vid"])
204         elif act_type == 'SET_VLAN_PCP':
205             eq_(action.vlan_pcp, act["vlan_pcp"])
206         elif act_type == 'SET_DL_SRC':
207             eq_(addrconv.mac.bin_to_text(action.dl_addr),
208                 act["dl_src"])
209         elif act_type == 'SET_DL_DST':
210             eq_(addrconv.mac.bin_to_text(action.dl_addr),
211                 act["dl_dst"])
212         elif act_type == 'SET_NW_SRC':
213             ip = netaddr.ip.IPAddress(action.nw_addr)
214             eq_(str(ip), act["nw_src"])
215         elif act_type == 'SET_NW_DST':
216             ip = netaddr.ip.IPAddress(action.nw_addr)
217             eq_(str(ip), act["nw_dst"])
218         elif act_type == 'SET_NW_TOS':
219             eq_(action.tos, act["nw_tos"])
220         elif act_type == 'SET_TP_SRC':
221             eq_(action.tp, act["tp_src"])
222         elif act_type == 'SET_TP_DST':
223             eq_(action.tp, act["tp_dst"])
224         elif act_type == 'ENQUEUE':
225             eq_(action.queue_id, act["queue_id"])
226             eq_(action.port, act["port"])
227         elif act_type == 'SET_MPLS_TTL':
228             eq_(action.mpls_ttl, act["mpls_ttl"])
229         elif act_type in ['PUSH_VLAN', 'PUSH_MPLS',
230                           'POP_MPLS', 'PUSH_PBB']:
231             eq_(action.ethertype, act["ethertype"])
232         elif act_type == 'SET_QUEUE':
233             eq_(action.queue_id, act["queue_id"])
234         elif act_type == 'GROUP':
235             eq_(action.group_id, act["group_id"])
236         elif act_type == 'SET_NW_TTL':
237             eq_(action.nw_ttl, act["nw_ttl"])
238         elif act_type == 'SET_FIELD':
239             eq_(action.key, act['field'])
240             eq_(action.value, act['value'])
241         elif act_type in ['STRIP_VLAN', 'COPY_TTL_OUT',
242                           'COPY_TTL_IN', 'DEC_MPLS_TTL',
243                           'POP_VLAN', 'DEC_NW_TTL', 'POP_PBB']:
244             pass
245         else:  # Uknown Action Type
246             assert False
247
248     def _equal_inst_to_str(self, inst_str, act, act_type, test):
249         if act_type == 'WRITE_ACTIONS':
250             act_str = inst_str[0]["WRITE_ACTIONS"]
251             act = act["actions"][0]
252             act_type = act["type"]
253             self._equal_act_to_str(act_str, act, act_type, test)
254         else:
255             inst_str_list = inst_str[0].split(':', 1)
256             eq_(inst_str_list[0], act_type)
257             if act_type == 'GOTO_TABLE':
258                 eq_(int(inst_str_list[1]), act["table_id"])
259             elif act_type == 'WRITE_METADATA':
260                 met = inst_str_list[1].split('/')
261                 eq_(int(met[0], 16), act["metadata"])
262                 eq_(int(met[1], 16), act["metadata_mask"])
263             elif act_type == 'METER':
264                 eq_(int(inst_str_list[1]), act["meter_id"])
265             elif act_type == 'CLEAR_ACTIONS':
266                 pass
267             else:
268                 # APPLY_ACTIONS
269                 act_str = inst_str
270                 self._equal_act_to_str(act_str, act, act_type, test)
271
272     def _equal_act_to_str(self, act_str, act, act_type, test):
273         act_str_list = act_str[0].split(':', 1)
274         eq_(act_str_list[0], act_type)
275         if act_type == 'OUTPUT':
276             eq_(int(act_str_list[1]), act["port"])
277         elif act_type == 'SET_VLAN_VID':
278             eq_(int(act_str_list[1]), act["vlan_vid"])
279         elif act_type == 'SET_VLAN_PCP':
280             eq_(int(act_str_list[1]), act["vlan_pcp"])
281         elif act_type == 'SET_DL_SRC':
282             eq_(act_str_list[1], act["dl_src"])
283         elif act_type == 'SET_DL_DST':
284             eq_(act_str_list[1], act["dl_dst"])
285         elif act_type == 'SET_NW_SRC':
286             eq_(act_str_list[1], act["nw_src"])
287         elif act_type == 'SET_NW_DST':
288             eq_(act_str_list[1], act["nw_dst"])
289         elif act_type == 'SET_NW_TOS':
290             eq_(int(act_str_list[1]), act["nw_tos"])
291         elif act_type == 'SET_TP_SRC':
292             eq_(int(act_str_list[1]), act["tp_src"])
293         elif act_type == 'SET_TP_DST':
294             eq_(int(act_str_list[1]), act["tp_dst"])
295         elif act_type == 'ENQUEUE':
296             enq = act_str_list[1].split(':')
297             eq_(int(enq[0], 10), act["port"])
298             eq_(int(enq[1], 10), act["queue_id"])
299         elif act_type == 'SET_MPLS_TTL':
300             eq_(int(act_str_list[1]), act["mpls_ttl"])
301         elif act_type == 'PUSH_VLAN':
302             eq_(int(act_str_list[1]), act["ethertype"])
303         elif act_type == 'PUSH_MPLS':
304             eq_(int(act_str_list[1]), act["ethertype"])
305         elif act_type == 'POP_MPLS':
306             eq_(int(act_str_list[1]), act["ethertype"])
307         elif act_type == 'SET_QUEUE':
308             eq_(int(act_str_list[1]), act["queue_id"])
309         elif act_type == 'GROUP':
310             eq_(int(act_str_list[1]), act["group_id"])
311         elif act_type == 'SET_NW_TTL':
312             eq_(int(act_str_list[1]), act["nw_ttl"])
313         elif act_type == 'SET_FIELD':
314             field, value = act_str_list[1].split(':')
315             eq_(field.strip(' {'), act["field"])
316             eq_(int(value.strip('} ')), act["value"])
317         elif act_type == 'PUSH_PBB':
318             eq_(int(act_str_list[1]), act["ethertype"])
319         elif act_type in ['STRIP_VLAN', 'COPY_TTL_OUT',
320                           'COPY_TTL_IN', 'DEC_MPLS_TTL',
321                           'POP_VLAN', 'DEC_NW_TTL', 'POP_PBB']:
322             pass
323         else:
324             assert False
325
326     def _equal_str_to_match(self, key, value, match, test):
327         field_value = self._get_field_value(test, key, match)
328
329         if key in ['eth_src', 'eth_dst', 'arp_sha', 'arp_tha']:
330             # MAC address
331             eth, mask = _to_match_eth(value)
332             if mask is not None:
333                 # with mask
334                 for i in range(0, len(mask)):
335                     if mask[i] == 'f':
336                         eq_(eth[i], field_value[0][i])
337                 eq_(mask, field_value[1])
338             else:
339                 # without mask
340                 eq_(eth, field_value)
341             return
342         elif key in ['dl_src', 'dl_dst']:
343             eth, mask = _to_match_eth(value)
344             field_value = addrconv.mac.bin_to_text(field_value)
345             eq_(eth, field_value)
346             return
347         elif key in ['ipv4_src', 'ipv4_dst', 'arp_spa', 'arp_tpa']:
348             # IPv4 address
349             ipv4, mask = _to_match_ip(value)
350             if mask is not None:
351                 # with mask
352                 eq_(ipv4, field_value[0])
353                 eq_(mask, field_value[1])
354             else:
355                 # without mask
356                 eq_(ipv4, field_value)
357             return
358         elif key in ['nw_src', 'nw_dst']:
359             # IPv4 address
360             ipv4, mask = _to_match_ip(value)
361             field_value = _to_match_ip(field_value)
362             if mask is not None:
363                 # with mask
364                 eq_(ipv4, field_value[0])
365                 eq_(mask, field_value[1])
366             else:
367                 # without mask
368                 eq_(ipv4, field_value[0])
369             return
370         elif key in ['ipv6_src', 'ipv6_dst']:
371             # IPv6 address
372             ipv6, mask = _to_match_ip(value)
373             if mask is not None:
374                 # with mask
375                 eq_(ipv6, field_value[0])
376                 eq_(mask, field_value[1])
377             else:
378                 # without mask
379                 eq_(ipv6, field_value)
380             return
381         elif key == 'vlan_vid':
382             if test.ver == ofproto_v1_0.OFP_VERSION:
383                 eq_(value, field_value)
384             else:
385                 eq_(test.expected_value['vlan_vid'][
386                     value]['to_match'], field_value)
387             return
388         else:
389             if isinstance(value, str) and '/' in value:
390                 # with mask
391                 value, mask = _to_match_masked_int(value)
392                 value &= mask
393                 eq_(value, field_value[0])
394                 eq_(mask, field_value[1])
395             else:
396                 # without mask
397                 eq_(_str_to_int(value), field_value)
398             return
399
400     def _equal_match_to_str(self, key, value, match_str, test):
401         field_value = match_str[key]
402         if key in ['dl_src', 'dl_dst', 'arp_sha', 'arp_tha']:
403             # MAC address
404             eth, mask = _to_match_eth(value)
405             if mask is not None:
406                 # with mask
407                 field_value = field_value.split('/')
408                 for i in range(0, len(mask)):
409                     if mask[i] == 'f':
410                         eq_(eth[i], field_value[0][i])
411                 eq_(mask, field_value[1])
412             else:
413                 # without mask
414                 eq_(eth, field_value)
415             return
416         elif key in['nw_src', 'nw_dst', 'arp_spa', 'arp_tpa']:
417             # IPv4 address
418             if test.ver == ofproto_v1_0.OFP_VERSION:
419                 ipv4, mask = _to_match_ip(value)
420                 field_value = _to_match_ip(field_value)
421                 if mask is not None:
422                     # with mask
423                     eq_(ipv4, field_value[0])
424                     eq_(mask, field_value[1])
425                 else:
426                     # without mask
427                     eq_(ipv4, field_value[0])
428             else:
429                 ipv4, mask = _to_match_ip(value)
430                 if mask is not None:
431                     # with mask
432                     field_value = field_value.split('/')
433                     eq_(ipv4, field_value[0])
434                     eq_(mask, field_value[1])
435                 else:
436                     # without mask
437                     eq_(ipv4, field_value)
438             return
439         elif key in ['ipv6_src', 'ipv6_dst']:
440             # IPv6 address
441             ipv6, mask = _to_match_ip(value)
442             if mask is not None:
443                 # with mask
444                 field_value = field_value.split('/')
445                 eq_(ipv6, field_value[0])
446                 eq_(mask, field_value[1])
447             else:
448                 # without mask
449                 eq_(ipv6, field_value)
450             return
451         elif key == 'dl_vlan':
452             if test.ver == ofproto_v1_0.OFP_VERSION:
453                 eq_(value, field_value)
454             else:
455                 eq_(test.expected_value['vlan_vid'][
456                     value]['to_str'], field_value)
457             return
458         else:
459             if isinstance(value, str) and '/' in value:
460                 # with mask
461                 value = _to_masked_int_str(value)
462                 eq_(value, field_value)
463             else:
464                 # without mask
465                 eq_(_str_to_int(value), field_value)
466             return
467
468     def _conv_key(self, test, key, attrs):
469         if test.ver != ofproto_v1_0.OFP_VERSION:
470             if key in conv_of10_to_of12_dict:
471                 # For old field name
472                 key = conv_of10_to_of12_dict[key]
473             elif key == 'tp_src' or key == 'tp_dst':
474                 # TCP/UDP port
475                 conv = {inet.IPPROTO_TCP: {'tp_src': 'tcp_src',
476                                            'tp_dst': 'tcp_dst'},
477                         inet.IPPROTO_UDP: {'tp_src': 'udp_src',
478                                            'tp_dst': 'udp_dst'}}
479                 ip_proto = attrs.get('nw_proto', attrs.get('ip_proto', 0))
480                 key = conv[ip_proto][key]
481
482         return key
483
484     def _get_field_value(self, test, key, match):
485         if test.ver == ofproto_v1_0.OFP_VERSION:
486             members = inspect.getmembers(match)
487             for member in members:
488                 if member[0] == key:
489                     field_value = member[1]
490                 elif member[0] == 'wildcards':
491                     wildcards = member[1]
492             if key == 'nw_src':
493                 field_value = test.nw_src_to_str(wildcards, field_value)
494             elif key == 'nw_dst':
495                 field_value = test.nw_dst_to_str(wildcards, field_value)
496         else:
497             field_value = match[key]
498
499         return field_value
500
501
502 class test_data_base(object):
503     # followings must be an attribute of subclass.
504     # _ofctl
505     # _ofproto
506
507     def __init__(self):
508         self.ver = self._ofproto.OFP_VERSION
509         self.to_match = self._ofctl.to_match
510         self.match_to_str = self._ofctl.match_to_str
511         self.to_actions = self._ofctl.to_actions
512         self.actions_to_str = self._ofctl.actions_to_str
513
514
515 class test_data_v1_0(test_data_base):
516     """ Test_data for of_v1_0 """
517     _ofctl = ofctl_v1_0
518     _ofproto = ofproto_v1_0
519     _parser = ofproto_v1_0_parser
520
521     def __init__(self):
522         super(test_data_v1_0, self).__init__()
523         self.nw_src_to_str = self._ofctl.nw_src_to_str
524         self.nw_dst_to_str = self._ofctl.nw_dst_to_str
525         self.supported_action = {}
526         self.act_list = [
527             {'type': 'OUTPUT', 'port': 3},
528             {'type': 'SET_VLAN_VID', 'vlan_vid': 5},
529             {'type': 'SET_VLAN_PCP', 'vlan_pcp': 3},
530             {'type': 'STRIP_VLAN'},
531             {'type': 'SET_DL_SRC', 'dl_src': 'aa:bb:cc:11:22:33'},
532             {'type': 'SET_DL_DST', 'dl_dst': 'aa:bb:cc:11:22:33'},
533             {'type': 'SET_NW_SRC', 'nw_src': '10.0.0.1'},
534             {'type': 'SET_NW_DST', 'nw_dst': '10.0.0.1'},
535             {'type': 'SET_NW_TOS', 'nw_tos': 184},
536             {'type': 'SET_TP_SRC', 'tp_src': 8080},
537             {'type': 'SET_TP_DST', 'tp_dst': 8080},
538             {'type': 'ENQUEUE', 'queue_id': 3, 'port': 1}
539         ]
540         self.attr_list = [
541             {'in_port': 7},
542             {'dl_src': 'aa:bb:cc:11:22:33'},
543             {'dl_dst': 'aa:bb:cc:11:22:33'},
544             {'dl_vlan': 5},
545             {'dl_vlan_pcp': 3},
546             {'dl_type': 123},
547             {'nw_tos': 16},
548             {'nw_proto': 5},
549             {'nw_src': '192.168.0.1'},
550             {'nw_src': '192.168.0.1/24'},
551             {'nw_dst': '192.168.0.1'},
552             {'nw_dst': '192.168.0.1/24'},
553             {'tp_src': 1},
554             {'tp_dst': 2}
555         ]
556         self.set_action()
557
558     def set_action(self):
559         self.supported_action.update(
560             {
561                 'OUTPUT': self._parser.OFPActionOutput,
562                 'SET_VLAN_VID': self._parser.OFPActionVlanVid,
563                 'SET_VLAN_PCP': self._parser.OFPActionVlanPcp,
564                 'STRIP_VLAN': self._parser.OFPActionStripVlan,
565                 'SET_DL_SRC': self._parser.OFPActionSetDlSrc,
566                 'SET_DL_DST': self._parser.OFPActionSetDlDst,
567                 'SET_NW_SRC': self._parser.OFPActionSetNwSrc,
568                 'SET_NW_DST': self._parser.OFPActionSetNwDst,
569                 'SET_NW_TOS': self._parser.OFPActionSetNwTos,
570                 'SET_TP_SRC': self._parser.OFPActionSetTpSrc,
571                 'SET_TP_DST': self._parser.OFPActionSetTpDst,
572                 'ENQUEUE': self._parser.OFPActionEnqueue
573             })
574
575
576 class test_data_v1_2(test_data_base):
577     """ Test_data for of_v1_2 """
578     _ofctl = ofctl_v1_2
579     _ofproto = ofproto_v1_2
580     _parser = ofproto_v1_2_parser
581
582     def __init__(self):
583         super(test_data_v1_2, self).__init__()
584         self.supported_action = {}
585         self.act_list = [
586             {'type': 'OUTPUT', 'port': 3},
587             {'type': 'COPY_TTL_OUT'},
588             {'type': 'COPY_TTL_IN'},
589             {'type': 'SET_MPLS_TTL', 'mpls_ttl': 64},
590             {'type': 'DEC_MPLS_TTL'},
591             {'type': 'PUSH_VLAN', 'ethertype': 0x0800},
592             {'type': 'POP_VLAN'},
593             {'type': 'PUSH_MPLS', 'ethertype': 0x0800},
594             {'type': 'POP_MPLS', 'ethertype': 0x0800},
595             {'type': 'SET_QUEUE', 'queue_id': 7},
596             {'type': 'GROUP', 'group_id': 5},
597             {'type': 'SET_NW_TTL', 'nw_ttl': 64},
598             {'type': 'DEC_NW_TTL'},
599             {"type": "CLEAR_ACTIONS"},
600             {"type": "WRITE_ACTIONS",
601              "actions": [{"type": "OUTPUT", "port": 4}]},
602             {'type': 'GOTO_TABLE', 'table_id': 8},
603             {'type': 'WRITE_METADATA', 'metadata': 8,
604              'metadata_mask': (1 << 64) - 1},
605         ]
606         self.attr_list = [
607             {'in_port': 7},
608             {'in_phy_port': 5, 'in_port': 3},
609             {'metadata': 12345},
610             {'metadata': '0x1212121212121212'},
611             {'metadata': '0x19af28be37fa91b/0x1010101010101010'},
612             {'dl_src': "aa:bb:cc:11:22:33"},
613             {'dl_src': "aa:bb:cc:11:22:33/00:00:00:00:ff:ff"},
614             {'dl_dst': "aa:bb:cc:11:22:33"},
615             {'dl_dst': "aa:bb:cc:11:22:33/00:00:00:00:ff:ff"},
616             {'dl_type': 123},
617             {'eth_src': "aa:bb:cc:11:22:33"},
618             {'eth_src': "aa:bb:cc:11:22:33/00:00:00:00:ff:ff"},
619             {'eth_dst': "aa:bb:cc:11:22:33"},
620             {'eth_dst': "aa:bb:cc:11:22:33/00:00:00:00:ff:ff"},
621             {'eth_type': 0x800},
622             {'dl_vlan': 0},
623             {'dl_vlan': 3},
624             {'dl_vlan': 4095},
625             {'dl_vlan': "0"},
626             {'dl_vlan': "3"},
627             {'dl_vlan': "4095"},
628             {'dl_vlan': "0x0000"},
629             {'dl_vlan': "0x0003"},
630             {'dl_vlan': "0x0fff"},
631             {'dl_vlan': "0x1000"},
632             {'dl_vlan': "0x1003"},
633             {'dl_vlan': "0x1fff"},
634             {'dl_vlan': "4096/4096"},
635             {'dl_vlan': "4096/4097"},
636             {'dl_vlan': "2744/2748"},
637             {'dl_vlan': "2748/2748"},
638             {'dl_vlan': "2748/2749"},
639             {'dl_vlan': "0x1000/0x1000"},
640             {'dl_vlan': "0x1000/0x1001"},
641             {'dl_vlan': "0x0ab8/0x0abc"},
642             {'dl_vlan': "0x0abc/0x0abc"},
643             {'dl_vlan': "0x0abc/0x0abd"},
644             {'vlan_pcp': 3, 'vlan_vid': 3},
645             {'ip_dscp': 3, 'eth_type': 0x0800},
646             {'ip_ecn': 4, 'eth_type': 0x86dd},
647             {'nw_src': "192.168.0.1", 'eth_type': 0x0800},
648             {'nw_src': "192.168.0.1/24", 'eth_type': 0x0800},
649             {'nw_src': "192.168.10.10/255.255.0.0", 'eth_type': 0x0800},
650             {'nw_dst': "192.168.0.1", 'eth_type': 0x0800},
651             {'nw_dst': "192.168.0.1/24", 'eth_type': 0x0800},
652             {'nw_dst': "192.168.10.10/255.255.255.0"},
653             {'nw_proto': 5, 'eth_type': 0x0800},
654             {'ip_proto': 5, 'eth_type': 0x86dd},
655             {'ipv4_src': "192.168.0.1", 'eth_type': 0x0800},
656             {'ipv4_src': "192.168.0.1/24", 'eth_type': 0x0800},
657             {'ipv4_src': "192.168.10.10/255.255.0.0", 'eth_type': 0x0800},
658             {'ipv4_dst': "192.168.0.1", 'eth_type': 0x0800},
659             {'ipv4_dst': "192.168.0.1/24", 'eth_type': 0x0800},
660             {'ipv4_dst': "192.168.10.10/255.255.255.0", 'eth_type': 0x0800},
661             {'tp_src': 1, 'ip_proto': 6},
662             {'tp_dst': 2, 'ip_proto': 6},
663             {'tp_src': 3, 'ip_proto': 17},
664             {'tp_dst': 4, 'ip_proto': 17},
665             {'vlan_vid': 0},
666             {'vlan_vid': 3},
667             {'vlan_vid': 4095},
668             {'vlan_vid': "0"},
669             {'vlan_vid': "3"},
670             {'vlan_vid': "4095"},
671             {'vlan_vid': "0x0000"},
672             {'vlan_vid': "0x0003"},
673             {'vlan_vid': "0x0fff"},
674             {'vlan_vid': "0x1000"},
675             {'vlan_vid': "0x1003"},
676             {'vlan_vid': "0x1fff"},
677             {'vlan_vid': "4096/4096"},
678             {'vlan_vid': "4096/4097"},
679             {'vlan_vid': "2744/2748"},
680             {'vlan_vid': "2748/2748"},
681             {'vlan_vid': "2748/2749"},
682             {'vlan_vid': "0x1000/0x1000"},
683             {'vlan_vid': "0x1000/0x1001"},
684             {'vlan_vid': "0x0ab8/0x0abc"},
685             {'vlan_vid': "0x0abc/0x0abc"},
686             {'vlan_vid': "0x0abc/0x0abd"},
687             {'tcp_src': 3, 'ip_proto': 6},
688             {'tcp_dst': 5, 'ip_proto': 6},
689             {'udp_src': 2, 'ip_proto': 17},
690             {'udp_dst': 6, 'ip_proto': 17},
691             {'sctp_src': 99, 'ip_proto': 132},
692             {'sctp_dst': 99, 'ip_proto': 132},
693             {'icmpv4_type': 5, 'ip_proto': 1},
694             {'icmpv4_code': 6, 'ip_proto': 1},
695             {'arp_op': 3, 'eth_type': 0x0806},
696             {'arp_spa': "192.168.0.11", 'eth_type': 0x0806},
697             {'arp_spa': "192.168.0.22/24", 'eth_type': 0x0806},
698             {'arp_tpa': "192.168.0.33", 'eth_type': 0x0806},
699             {'arp_tpa': "192.168.0.44/24", 'eth_type': 0x0806},
700             {'arp_sha': "aa:bb:cc:11:22:33", 'eth_type': 0x0806},
701             {'arp_sha': "aa:bb:cc:11:22:33/00:00:00:00:ff:ff",
702                 'eth_type': 0x0806},
703             {'arp_tha': "aa:bb:cc:11:22:33", 'eth_type': 0x0806},
704             {'arp_tha': "aa:bb:cc:11:22:33/00:00:00:00:ff:ff",
705                 'eth_type': 0x0806},
706             {'ipv6_src': '2001::aaaa:bbbb:cccc:1111', 'eth_type': 0x86dd},
707             {'ipv6_src': '2001::aaaa:bbbb:cccc:1111/64', 'eth_type': 0x86dd},
708             {'ipv6_dst': '2001::ffff:cccc:bbbb:1111', 'eth_type': 0x86dd},
709             {'ipv6_dst': '2001::ffff:cccc:bbbb:1111/64', 'eth_type': 0x86dd},
710             {'ipv6_flabel': 2, 'eth_type': 0x86dd},
711             {'icmpv6_type': 3, 'ip_proto': 58},
712             {'icmpv6_code': 4, 'ip_proto': 58},
713             {'ipv6_nd_target': '2001::ffff:cccc:bbbb:1111',
714                 'icmpv6_type': 135, 'ip_proto': 58},
715             {'ipv6_nd_sll': "aa:bb:cc:11:22:33",
716                 'icmpv6_type': 135, 'ip_proto': 58},
717             {'ipv6_nd_tll': "aa:bb:cc:11:22:33",
718                 'icmpv6_type': 136, 'ip_proto': 58},
719             {'mpls_label': 3, 'eth_type': 0x8848},
720             {'mpls_tc': 2, 'eth_type': 0x8848}
721         ]
722         self.supported_action.update(
723             {
724                 'OUTPUT': self._parser.OFPActionOutput,
725                 'COPY_TTL_OUT': self._parser.OFPActionCopyTtlOut,
726                 'COPY_TTL_IN': self._parser.OFPActionCopyTtlIn,
727                 'SET_MPLS_TTL': self._parser.OFPActionSetMplsTtl,
728                 'DEC_MPLS_TTL': self._parser.OFPActionDecMplsTtl,
729                 'PUSH_VLAN': self._parser.OFPActionPushVlan,
730                 'POP_VLAN': self._parser.OFPActionPopVlan,
731                 'PUSH_MPLS': self._parser.OFPActionPushMpls,
732                 'POP_MPLS': self._parser.OFPActionPopMpls,
733                 'SET_QUEUE': self._parser.OFPActionSetQueue,
734                 'GROUP': self._parser.OFPActionGroup,
735                 'SET_NW_TTL': self._parser.OFPActionSetNwTtl,
736                 'DEC_NW_TTL': self._parser.OFPActionDecNwTtl,
737                 'SET_FIELD': self._parser.OFPActionSetField,
738                 'GOTO_TABLE': self._parser.OFPInstructionGotoTable,
739                 'WRITE_METADATA': self._parser.OFPInstructionWriteMetadata,
740                 'WRITE_ACTIONS': self._parser.OFPInstructionActions,
741                 'CLEAR_ACTIONS': self._parser.OFPInstructionActions,
742             })
743         self.set_expected_value()
744
745     def set_expected_value(self):
746         vid_present = self._ofproto.OFPVID_PRESENT
747         self.expected_value = {
748             "vlan_vid": {
749                 0: {"to_match": 0 | vid_present, "to_str": "0"},
750                 3: {"to_match": 3 | vid_present, "to_str": "3"},
751                 4095: {"to_match": 4095 | vid_present, "to_str": "4095"},
752                 "0": {"to_match": 0 | vid_present, "to_str": "0"},
753                 "3": {"to_match": 3 | vid_present, "to_str": "3"},
754                 "4095": {"to_match": 4095 | vid_present, "to_str": "4095"},
755                 "0x0000": {"to_match": 0x0000, "to_str": "0x0000"},
756                 "0x0003": {"to_match": 0x0003, "to_str": "0x0003"},
757                 "0x0fff": {"to_match": 0x0fff, "to_str": "0x0fff"},
758                 "0x1000": {"to_match": 0x1000, "to_str": "0"},
759                 "0x1003": {"to_match": 0x1003, "to_str": "3"},
760                 "0x1fff": {"to_match": 0x1fff, "to_str": "4095"},
761                 "4096/4096": {"to_match": (4096, 4096),
762                               "to_str": "0x1000/0x1000"},
763                 "4096/4097": {"to_match": (4096, 4097),
764                               "to_str": "0x1000/0x1001"},
765                 "2744/2748": {"to_match": (2744, 2748),
766                               "to_str": "0x0ab8/0x0abc"},
767                 "2748/2748": {"to_match": (2748, 2748),
768                               "to_str": "0x0abc/0x0abc"},
769                 "2748/2749": {"to_match": (2748, 2749),
770                               "to_str": "0x0abc/0x0abd"},
771                 "0x1000/0x1000": {"to_match": (0x1000, 0x1000),
772                                   "to_str": "0x1000/0x1000"},
773                 "0x1000/0x1001": {"to_match": (0x1000, 0x1001),
774                                   "to_str": "0x1000/0x1001"},
775                 "0x0ab8/0x0abc": {"to_match": (0x0ab8, 0x0abc),
776                                   "to_str": "0x0ab8/0x0abc"},
777                 "0x0abc/0x0abc": {"to_match": (0x0abc, 0x0abc),
778                                   "to_str": "0x0abc/0x0abc"},
779                 "0x0abc/0x0abd": {"to_match": (0x0abc, 0x0abd),
780                                   "to_str": "0x0abc/0x0abd"}
781             }
782         }
783
784
785 class test_data_v1_3(test_data_v1_2):
786     """ Test_data for of_v1_3 """
787     _ofctl = ofctl_v1_3
788     _ofproto = ofproto_v1_3
789     _parser = ofproto_v1_3_parser
790
791     def __init__(self):
792         super(test_data_v1_3, self).__init__()
793         self.act_list.extend(
794             [
795                 {'type': 'PUSH_PBB', 'ethertype': 0x0800},
796                 {'type': 'POP_PBB'},
797                 {'type': 'METER', 'meter_id': 3},
798             ]
799         )
800         self.attr_list.extend(
801             [
802                 {'mpls_bos': 3, 'eth_type': 0x8848},
803                 {'pbb_isid': 5, 'eth_type': 0x88E7},
804                 {'pbb_isid': "0x05", 'eth_type': 0x88E7},
805                 {'pbb_isid': "0x05/0xff", 'eth_type': 0x88E7},
806                 {'tunnel_id': 7},
807                 {'tunnel_id': "0x07"},
808                 {'tunnel_id': "0x07/0xff"},
809                 {'ipv6_exthdr': 3, 'eth_type': 0x86dd},
810                 {'ipv6_exthdr': "0x40", 'eth_type': 0x86dd},
811                 {'ipv6_exthdr': "0x40/0x1F0", 'eth_type': 0x86dd},
812             ]
813         )
814         self.supported_action.update(
815             {
816                 'PUSH_PBB': self._parser.OFPActionPushPbb,
817                 'POP_PBB': self._parser.OFPActionPopPbb,
818                 'METER': self._parser.OFPInstructionMeter,
819             })
820         self.set_expected_value()
821
822
823 def _add_tests_actions(cls):
824     for act in cls.act_list:
825         method_name = 'test_' + str(cls.ver) + '_' + act["type"] + '_action'
826
827         def _run(self, name, act, cls):
828             print('processing %s ...' % name)
829             cls_ = Test_ofctl(name)
830             cls_._test_actions(act, cls)
831         print('adding %s ...' % method_name)
832         func = functools.partial(_run, name=method_name, act=act, cls=cls)
833         test_lib.add_method(Test_ofctl, method_name, func)
834
835
836 def _add_tests_match(cls):
837     for attr in cls.attr_list:
838         for key, value in attr.items():
839             method_name = 'test_' + \
840                 str(cls.ver) + '_' + key + '_' + str(
841                     value) + str(type(value)) + '_match'
842
843             def _run(self, name, attr, cls):
844                 print('processing %s ...' % name)
845                 cls_ = Test_ofctl(name)
846                 cls_._test_match(attr, cls)
847             print('adding %s ...' % method_name)
848             func = functools.partial(
849                 _run, name=method_name, attr=attr, cls=cls)
850             test_lib.add_method(Test_ofctl, method_name, func)
851
852
853 """ Test case """
854
855 # for of10
856 cls = test_data_v1_0()
857 _add_tests_actions(cls)
858 _add_tests_match(cls)
859
860 # for of12
861 cls = test_data_v1_2()
862 _add_tests_actions(cls)
863 _add_tests_match(cls)
864
865 # for of13
866 cls = test_data_v1_3()
867 _add_tests_actions(cls)
868 _add_tests_match(cls)