1 # Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
2 # Copyright (C) 2013 YAMAMOTO Takashi <yamamoto at valinux co jp>
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 from __future__ import print_function
21 from functools import reduce
28 from nose.tools import eq_
29 from nose.tools import ok_
31 from ryu.ofproto import ofproto_v1_2
32 from ryu.ofproto import ofproto_v1_3
33 from ryu.ofproto import ofproto_v1_4
34 from ryu.ofproto import ofproto_v1_5
35 from ryu.ofproto import ofproto_v1_2_parser
36 from ryu.ofproto import ofproto_v1_3_parser
37 from ryu.ofproto import ofproto_v1_4_parser
38 from ryu.ofproto import ofproto_v1_5_parser
39 from ryu.tests import test_lib
42 class Test_Parser_OFPMatch(unittest.TestCase):
43 _ofp = {ofproto_v1_2_parser: ofproto_v1_2,
44 ofproto_v1_3_parser: ofproto_v1_3,
45 ofproto_v1_4_parser: ofproto_v1_4,
46 ofproto_v1_5_parser: ofproto_v1_5}
48 def __init__(self, methodName):
49 print('init %s' % methodName)
50 super(Test_Parser_OFPMatch, self).__init__(methodName)
58 def _test(self, name, ofpp, d, domask):
60 d = dict(self._ofp[ofpp].oxm_normalize_user(k, uv)
63 match = ofpp.OFPMatch(**d)
66 match2 = match.parser(six.binary_type(b), 0)
67 for k, v in d.items():
72 for k, v in match.iteritems():
75 for k, v in match2.iteritems():
86 def generate_mask(cls):
87 return list(cls.generate())[1]
120 yield 0x123456789abcdef0
121 yield 0xffffffffffffffff
126 yield '00:00:00:00:00:00'
127 yield 'f2:0b:a4:7d:f8:ea'
128 yield 'ff:ff:ff:ff:ff:ff'
135 yield '255.255.255.255'
141 yield 'fe80::f00b:a4ff:fed0:3f70'
142 yield 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'
150 ofpps = [ofproto_v1_2_parser, ofproto_v1_3_parser,
151 ofproto_v1_4_parser, ofproto_v1_5_parser]
155 ('in_phy_port', Int4),
173 ('icmpv4_type', Int1),
174 ('icmpv4_code', Int1),
182 ('ipv6_flabel', Int4),
183 ('icmpv6_type', Int1),
184 ('icmpv6_code', Int1),
185 ('ipv6_nd_target', IPv6),
186 ('ipv6_nd_sll', Mac),
187 ('ipv6_nd_tll', Mac),
188 ('mpls_label', Int4),
190 # Old ONF Experimenter --> OpenFlow Basic (OF1.4+)
192 # ONF Experimenter --> OpenFlow Basic (OF1.5+)
194 ('actset_output', Int4),
195 # Nicira Experimenter
196 ('eth_dst_nxm', Mac),
197 ('eth_src_nxm', Mac),
198 ('tunnel_id_nxm', Int8),
199 ('tun_ipv4_src', IPv4),
200 ('tun_ipv4_dst', IPv4),
203 ('tun_ipv6_src', IPv6),
204 ('tun_ipv6_dst', IPv6),
214 # Common Experimenter
218 L[ofproto_v1_2_parser] = common + [
219 # OF1.2 doesn't have OXM_OF_PBB_ISID.
220 # OFPXMC_OPENFLOW_BASIC = 0x8000
221 # OXM_OF_PBB_ISID = 37
222 # (OFPXMC_OPENFLOW_BASIC << 7) + OXM_OF_PBB_ISID == 4194341
223 ('field_4194341', B64),
225 L[ofproto_v1_3_parser] = common + [
226 # OpenFlow Basic (OF1.3+)
230 ('ipv6_exthdr', Int2),
232 L[ofproto_v1_4_parser] = L[ofproto_v1_3_parser]
233 L[ofproto_v1_5_parser] = L[ofproto_v1_4_parser] + [
234 # OpenFlow Basic (OF1.5+)
235 ('packet_type', Int4),
238 def flatten_one(l, i):
239 if isinstance(i, tuple):
240 return l + flatten(i)
243 flatten = lambda l: reduce(flatten_one, l, [])
246 for n in range(1, 3):
247 for C in itertools.combinations(L[ofpp], n):
252 l = itertools.product(l, cls.generate())
255 l = [flatten(x)[1:] for x in l]
256 for domask in [True, False]:
259 values = [(value, cls.generate_mask())
261 in zip(clss, values)]
262 d = dict(zip(keys, values))
263 mod = ofpp.__name__.split('.')[-1]
264 method_name = 'test_' + mod
266 method_name += '_mask'
267 for k in sorted(dict(d).keys()):
268 method_name += '_' + str(k)
269 method_name += '_' + str(d[k])
270 method_name = method_name.replace(':', '_')
271 method_name = method_name.replace('.', '_')
272 method_name = method_name.replace('(', '_')
273 method_name = method_name.replace(')', '_')
274 method_name = method_name.replace(',', '_')
275 method_name = method_name.replace("'", '_')
276 method_name = method_name.replace(' ', '_')
278 def _run(self, name, ofpp, d, domask):
279 print('processing %s ...' % name)
281 self._test(self, name, ofpp, d, domask)
283 self._test(name, ofpp, d, domask)
284 print('adding %s ...' % method_name)
285 f = functools.partial(_run, name=method_name,
286 ofpp=ofpp, d=d, domask=domask)
287 test_lib.add_method(Test_Parser_OFPMatch,