1 # Copyright (C) 2015 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 # there are two representations of value which this module deal with.
19 # the readable value which are strings.
22 # the on-wire bytes value.
24 # There are two types of OXS headers.
28 # +-------------------------------+-------------+-+---------------+
29 # | class | field |r| length |
30 # +-------------------------------+-------------+-+---------------+
32 # 64-bit experimenter OXS header
34 # +-------------------------------+-------------+-+---------------+
35 # | class (OFPXSC_EXPERIMENTER) | field |r| length |
36 # +-------------------------------+-------------+-+---------------+
38 # +---------------------------------------------------------------+
40 # Description of OXS header fields
41 # +----------------------+-------+--------------------------------------------+
42 # | Name | Width | Usage |
43 # +----------+-----------+-------+--------------------------------------------+
44 # | oxs_type | oxs_class | 16 | Stat class: member class or reserved class |
45 # | +-----------+-------+--------------------------------------------+
46 # | | oxs_field | 7 | Stat field within the class |
47 # +----------+-----------+-------+--------------------------------------------+
48 # | reserved | 1 | Reserved for future use |
49 # +----------------------+-------+--------------------------------------------+
50 # | length | 8 | Length of OXS payload |
51 # +----------------------+-------+--------------------------------------------+
53 # Assumption: The followings can be applied for OXSs too.
54 # OpenFlow Spec 1.5 mandates that Experimenter OXMs encode the experimenter
55 # type in the oxm_field field of the OXM header (EXT-380).
57 from ryu.ofproto.oxx_fields import (
69 OFPXSC_OPENFLOW_BASIC = 0x8002
70 OFPXSC_EXPERIMENTER = 0xFFFF
73 OFPXSC_HEADER_PACK_STR = '!I'
74 OFPXSC_EXP_HEADER_PACK_STR = '!I'
77 class _OxsClass(object):
78 # _class = OFPXSC_* must be an attribute of subclass.
79 def __init__(self, name, num, type_):
82 self.oxs_type = num | (self._class << 7)
83 # 'num' has not corresponding field in the specification.
84 # This is specific to this implementation and used to retrieve
85 # _OxsClass subclass from 'num_to_field' dictionary.
86 self.num = self.oxs_type
90 class OpenFlowBasic(_OxsClass):
91 _class = OFPXSC_OPENFLOW_BASIC
94 class _Experimenter(_OxsClass):
95 _class = OFPXSC_EXPERIMENTER
96 # experimenter_id must be an attribute of subclass.
98 def __init__(self, name, num, type_):
99 super(_Experimenter, self).__init__(name, num, type_)
100 self.num = (self.experimenter_id, self.oxs_type)
101 self.exp_type = self.oxs_field
104 def generate(modname):
108 mod = sys.modules[modname]
113 for i in mod.oxs_types:
114 if isinstance(i.num, tuple):
116 if i._class != OFPXSC_OPENFLOW_BASIC:
121 add_attr('OFPXST_OFB_' + uk, ofpxst)
122 add_attr('OXS_OF_' + uk, mod.oxs_tlv_header(ofpxst, td.size))
124 # 'oxx' indicates the OpenFlow Extensible class type.
125 # eg.) 'oxs' indicates that this class is OXS class.
127 name_to_field = dict((f.name, f) for f in mod.oxs_types)
128 num_to_field = dict((f.num, f) for f in mod.oxs_types)
130 # create functions by using oxx_fields module.
131 add_attr('oxs_from_user',
132 functools.partial(_from_user, oxx, name_to_field))
133 add_attr('oxs_from_user_header',
134 functools.partial(_from_user_header, oxx, name_to_field))
135 add_attr('oxs_to_user',
136 functools.partial(_to_user, oxx, num_to_field))
137 add_attr('oxs_to_user_header',
138 functools.partial(_to_user_header, oxx, num_to_field))
139 add_attr('_oxs_field_desc', # oxx is not required
140 functools.partial(_field_desc, num_to_field))
141 add_attr('oxs_parse', # oxx is not required
142 functools.partial(_parse, mod))
143 add_attr('oxs_parse_header', # oxx is not required
144 functools.partial(_parse_header, mod))
145 add_attr('oxs_serialize',
146 functools.partial(_serialize, oxx, mod))
147 add_attr('oxs_serialize_header',
148 functools.partial(_serialize_header, oxx, mod))
150 add_attr('oxs_to_jsondict', _to_jsondict)
151 add_attr('oxs_from_jsondict', _from_jsondict)
154 def _to_jsondict(k, uv):
155 return {"OXSTlv": {"field": k, "value": uv}}
158 def _from_jsondict(j):
162 return (field, value)