1 # Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
16 from __future__ import print_function
24 from nose.tools import *
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
37 LOG = logging.getLogger('test_ofctl_v1_2, v1_3')
39 """ Common Functions """
45 except (ValueError, TypeError):
49 def _to_match_eth(value):
51 value = value.split('/')
52 return value[0], value[1]
57 def _to_match_ip(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
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])
72 return _str_to_int(value), None
75 def _to_masked_int_str(value):
76 v, m = _to_match_masked_int(value)
78 return '%d/%d' % (v, m)
81 conv_of10_to_of12_dict = {
84 'dl_type': 'eth_type',
85 'dl_vlan': 'vlan_vid',
88 'nw_proto': 'ip_proto'
92 conv_of12_to_of10_dict = {
95 'eth_type': 'dl_type',
98 'ip_proto': 'nw_proto',
99 'vlan_vid': 'dl_vlan',
109 class Test_ofctl(unittest.TestCase):
111 def __init__(self, methodName):
112 super(Test_ofctl, self).__init__(methodName)
120 def _test_actions(self, act, test):
121 dp = ofproto_protocol.ProtocolDesc(version=test.ver)
122 act_type = act["type"]
125 insts = test.to_actions(dp, [act])
127 if test.ver == ofproto_v1_0.OFP_VERSION:
129 self._equal_str_to_act(action, act, act_type, test)
132 self._equal_str_to_inst(inst, act, act_type, test)
135 inst_str = test.actions_to_str(insts)
136 if test.ver == ofproto_v1_0.OFP_VERSION:
138 self._equal_act_to_str(act_str, act, act_type, test)
140 self._equal_inst_to_str(inst_str, act, act_type, test)
142 def _test_match(self, attrs, test):
143 dp = ofproto_protocol.ProtocolDesc(version=test.ver)
146 match = test.to_match(dp, attrs)
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)
153 match_str = test.match_to_str(match)
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]
160 self._equal_match_to_str(key_old, value, match_str, test)
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]
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],
182 act["actions"][0]["type"],
184 elif act_type == 'CLEAR_ACTIONS':
185 ok_(isinstance(inst, cls))
186 eq_(inst.type, test._ofproto.OFPIT_CLEAR_ACTIONS)
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,
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]
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),
209 elif act_type == 'SET_DL_DST':
210 eq_(addrconv.mac.bin_to_text(action.dl_addr),
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']:
245 else: # Uknown Action Type
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)
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':
270 self._equal_act_to_str(act_str, act, act_type, test)
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']:
326 def _equal_str_to_match(self, key, value, match, test):
327 field_value = self._get_field_value(test, key, match)
329 if key in ['eth_src', 'eth_dst', 'arp_sha', 'arp_tha']:
331 eth, mask = _to_match_eth(value)
334 for i in range(0, len(mask)):
336 eq_(eth[i], field_value[0][i])
337 eq_(mask, field_value[1])
340 eq_(eth, field_value)
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)
347 elif key in ['ipv4_src', 'ipv4_dst', 'arp_spa', 'arp_tpa']:
349 ipv4, mask = _to_match_ip(value)
352 eq_(ipv4, field_value[0])
353 eq_(mask, field_value[1])
356 eq_(ipv4, field_value)
358 elif key in ['nw_src', 'nw_dst']:
360 ipv4, mask = _to_match_ip(value)
361 field_value = _to_match_ip(field_value)
364 eq_(ipv4, field_value[0])
365 eq_(mask, field_value[1])
368 eq_(ipv4, field_value[0])
370 elif key in ['ipv6_src', 'ipv6_dst']:
372 ipv6, mask = _to_match_ip(value)
375 eq_(ipv6, field_value[0])
376 eq_(mask, field_value[1])
379 eq_(ipv6, field_value)
381 elif key == 'vlan_vid':
382 if test.ver == ofproto_v1_0.OFP_VERSION:
383 eq_(value, field_value)
385 eq_(test.expected_value['vlan_vid'][
386 value]['to_match'], field_value)
389 if isinstance(value, str) and '/' in value:
391 value, mask = _to_match_masked_int(value)
393 eq_(value, field_value[0])
394 eq_(mask, field_value[1])
397 eq_(_str_to_int(value), field_value)
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']:
404 eth, mask = _to_match_eth(value)
407 field_value = field_value.split('/')
408 for i in range(0, len(mask)):
410 eq_(eth[i], field_value[0][i])
411 eq_(mask, field_value[1])
414 eq_(eth, field_value)
416 elif key in['nw_src', 'nw_dst', 'arp_spa', 'arp_tpa']:
418 if test.ver == ofproto_v1_0.OFP_VERSION:
419 ipv4, mask = _to_match_ip(value)
420 field_value = _to_match_ip(field_value)
423 eq_(ipv4, field_value[0])
424 eq_(mask, field_value[1])
427 eq_(ipv4, field_value[0])
429 ipv4, mask = _to_match_ip(value)
432 field_value = field_value.split('/')
433 eq_(ipv4, field_value[0])
434 eq_(mask, field_value[1])
437 eq_(ipv4, field_value)
439 elif key in ['ipv6_src', 'ipv6_dst']:
441 ipv6, mask = _to_match_ip(value)
444 field_value = field_value.split('/')
445 eq_(ipv6, field_value[0])
446 eq_(mask, field_value[1])
449 eq_(ipv6, field_value)
451 elif key == 'dl_vlan':
452 if test.ver == ofproto_v1_0.OFP_VERSION:
453 eq_(value, field_value)
455 eq_(test.expected_value['vlan_vid'][
456 value]['to_str'], field_value)
459 if isinstance(value, str) and '/' in value:
461 value = _to_masked_int_str(value)
462 eq_(value, field_value)
465 eq_(_str_to_int(value), field_value)
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:
472 key = conv_of10_to_of12_dict[key]
473 elif key == 'tp_src' or key == 'tp_dst':
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]
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:
489 field_value = member[1]
490 elif member[0] == 'wildcards':
491 wildcards = member[1]
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)
497 field_value = match[key]
502 class test_data_base(object):
503 # followings must be an attribute of subclass.
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
515 class test_data_v1_0(test_data_base):
516 """ Test_data for of_v1_0 """
518 _ofproto = ofproto_v1_0
519 _parser = ofproto_v1_0_parser
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 = {}
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}
542 {'dl_src': 'aa:bb:cc:11:22:33'},
543 {'dl_dst': 'aa:bb:cc:11:22:33'},
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'},
558 def set_action(self):
559 self.supported_action.update(
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
576 class test_data_v1_2(test_data_base):
577 """ Test_data for of_v1_2 """
579 _ofproto = ofproto_v1_2
580 _parser = ofproto_v1_2_parser
583 super(test_data_v1_2, self).__init__()
584 self.supported_action = {}
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},
608 {'in_phy_port': 5, 'in_port': 3},
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"},
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"},
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},
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",
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",
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}
722 self.supported_action.update(
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,
743 self.set_expected_value()
745 def set_expected_value(self):
746 vid_present = self._ofproto.OFPVID_PRESENT
747 self.expected_value = {
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"}
785 class test_data_v1_3(test_data_v1_2):
786 """ Test_data for of_v1_3 """
788 _ofproto = ofproto_v1_3
789 _parser = ofproto_v1_3_parser
792 super(test_data_v1_3, self).__init__()
793 self.act_list.extend(
795 {'type': 'PUSH_PBB', 'ethertype': 0x0800},
797 {'type': 'METER', 'meter_id': 3},
800 self.attr_list.extend(
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},
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},
814 self.supported_action.update(
816 'PUSH_PBB': self._parser.OFPActionPushPbb,
817 'POP_PBB': self._parser.OFPActionPopPbb,
818 'METER': self._parser.OFPInstructionMeter,
820 self.set_expected_value()
823 def _add_tests_actions(cls):
824 for act in cls.act_list:
825 method_name = 'test_' + str(cls.ver) + '_' + act["type"] + '_action'
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)
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'
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)
856 cls = test_data_v1_0()
857 _add_tests_actions(cls)
858 _add_tests_match(cls)
861 cls = test_data_v1_2()
862 _add_tests_actions(cls)
863 _add_tests_match(cls)
866 cls = test_data_v1_3()
867 _add_tests_actions(cls)
868 _add_tests_match(cls)