backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / ofproto / oxm_fields.py
1 # Copyright (C) 2013-2015 Nippon Telegraph and Telephone Corporation.
2 # Copyright (C) 2013-2015 YAMAMOTO Takashi <yamamoto at valinux co jp>
3 #
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
7 #
8 #    http://www.apache.org/licenses/LICENSE-2.0
9 #
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
13 # implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # there are two representations of value and mask this module deal with.
18 #
19 # "user"
20 #   (value, mask) or value.  the latter means no mask.
21 #   value and mask are strings.
22 #
23 # "internal"
24 #   value and mask are on-wire bytes.
25 #   mask is None if no mask.
26
27 # There are two types of OXM/NXM headers.
28 #
29 # 32-bit OXM/NXM header
30 # +-------------------------------+-------------+-+---------------+
31 # | class                         | field       |m| length        |
32 # +-------------------------------+-------------+-+---------------+
33 #
34 # 64-bit experimenter OXM header
35 # +-------------------------------+-------------+-+---------------+
36 # | class (OFPXMC_EXPERIMENTER)   | field       |m| length        |
37 # +-------------------------------+-------------+-+---------------+
38 # | experimenter ID                                               |
39 # +---------------------------------------------------------------+
40
41 # NOTE: OpenFlow Spec 1.5 mandates that Experimenter OXMs encode
42 # the experimenter type in the oxm_field field of the OXM header
43 # (EXT-380).
44
45 # NOTE: EXT-256 had a variation of experimenter OXM header.
46 # It has been rectified since then.  Currently this implementation
47 # supports only the old version.
48 #
49 # ONF EXT-256 (old, exp_type = 2560)
50 # +-------------------------------+-------------+-+---------------+
51 # | class (OFPXMC_EXPERIMENTER)   | ?????       |m| length        |
52 # +-------------------------------+-------------+-+---------------+
53 # | experimenter ID (ONF_EXPERIMENTER_ID)                         |
54 # +-------------------------------+---------------+---------------+
55 # | exp_type (PBB_UCA=2560)       | pbb_uca       |
56 # +-------------------------------+---------------+
57 #
58 # ONF EXT-256 (new, oxm_field = 41)
59 # +-------------------------------+-------------+-+---------------+
60 # | class (OFPXMC_EXPERIMENTER)   | PBB_UCA=41  |m| length        |
61 # +-------------------------------+-------------+-+---------------+
62 # | experimenter ID (ONF_EXPERIMENTER_ID)                         |
63 # +-------------------------------+---------------+---------------+
64 # | reserved, should be zero      | pbb_uca       |
65 # +-------------------------------+---------------+
66
67 from ryu.ofproto.oxx_fields import (
68     _get_field_info_by_name,
69     _from_user,
70     _from_user_header,
71     _to_user,
72     _to_user_header,
73     _field_desc,
74     _normalize_user,
75     _parse,
76     _parse_header,
77     _serialize,
78     _serialize_header)
79 from ryu.ofproto import ofproto_common
80
81
82 OFPXMC_NXM_0 = 0  # Nicira Extended Match (NXM_OF_)
83 OFPXMC_NXM_1 = 1  # Nicira Extended Match (NXM_NX_)
84 OFPXMC_OPENFLOW_BASIC = 0x8000
85 OFPXMC_PACKET_REGS = 0x8001
86 OFPXMC_EXPERIMENTER = 0xffff
87
88
89 class _OxmClass(object):
90     def __init__(self, name, num, type_):
91         self.name = name
92         self.oxm_field = num
93         self.oxm_type = num | (self._class << 7)
94         # TODO(yamamoto): Clean this up later.
95         # Probably when we drop EXT-256 style experimenter OXMs.
96         self.num = self.oxm_type
97         self.type = type_
98
99
100 class OpenFlowBasic(_OxmClass):
101     _class = OFPXMC_OPENFLOW_BASIC
102
103
104 class PacketRegs(_OxmClass):
105     _class = OFPXMC_PACKET_REGS
106
107
108 class _Experimenter(_OxmClass):
109     _class = OFPXMC_EXPERIMENTER
110
111     def __init__(self, name, num, type_):
112         super(_Experimenter, self).__init__(name, num, type_)
113         self.num = (self.experimenter_id, self.oxm_type)
114         self.exp_type = self.oxm_field
115
116
117 class ONFExperimenter(_Experimenter):
118     experimenter_id = ofproto_common.ONF_EXPERIMENTER_ID
119
120
121 class OldONFExperimenter(_Experimenter):
122     # This class is for the old version of EXT-256
123     experimenter_id = ofproto_common.ONF_EXPERIMENTER_ID
124
125     def __init__(self, name, num, type_):
126         super(OldONFExperimenter, self).__init__(name, 0, type_)
127         self.num = (self.experimenter_id, num)
128         self.exp_type = 2560
129
130
131 class NiciraExperimenter(_Experimenter):
132     experimenter_id = ofproto_common.NX_EXPERIMENTER_ID
133
134
135 class NiciraNshExperimenter(_Experimenter):
136     experimenter_id = ofproto_common.NX_NSH_EXPERIMENTER_ID
137
138
139 class NiciraExtended0(_OxmClass):
140     """Nicira Extended Match (NXM_0)
141
142     NXM header format is same as 32-bit (non-experimenter) OXMs.
143     """
144
145     _class = OFPXMC_NXM_0
146
147
148 class NiciraExtended1(_OxmClass):
149     """Nicira Extended Match (NXM_1)
150
151     NXM header format is same as 32-bit (non-experimenter) OXMs.
152     """
153
154     _class = OFPXMC_NXM_1
155
156
157 def generate(modname):
158     import sys
159     import functools
160
161     mod = sys.modules[modname]
162
163     def add_attr(k, v):
164         setattr(mod, k, v)
165
166     for i in mod.oxm_types:
167         if isinstance(i.num, tuple):
168             continue
169         if i._class != OFPXMC_OPENFLOW_BASIC:
170             continue
171         uk = i.name.upper()
172         ofpxmt = i.oxm_field
173         td = i.type
174         add_attr('OFPXMT_OFB_' + uk, ofpxmt)
175         add_attr('OXM_OF_' + uk, mod.oxm_tlv_header(ofpxmt, td.size))
176         add_attr('OXM_OF_' + uk + '_W', mod.oxm_tlv_header_w(ofpxmt, td.size))
177
178     # 'oxx' indicates the OpenFlow Extensible class type.
179     # eg.) 'oxm' indicates that this class is OXM class.
180     oxx = 'oxm'
181     name_to_field = dict((f.name, f) for f in mod.oxm_types)
182     num_to_field = dict((f.num, f) for f in mod.oxm_types)
183
184     # create functions by using oxx_fields module.
185     add_attr('oxm_get_field_info_by_name',
186              functools.partial(_get_field_info_by_name, oxx, name_to_field))
187     add_attr('oxm_from_user',
188              functools.partial(_from_user, oxx, name_to_field))
189     add_attr('oxm_from_user_header',
190              functools.partial(_from_user_header, oxx, name_to_field))
191     add_attr('oxm_to_user',
192              functools.partial(_to_user, oxx, num_to_field))
193     add_attr('oxm_to_user_header',
194              functools.partial(_to_user_header, oxx, num_to_field))
195     add_attr('_oxm_field_desc',  # oxx is not required
196              functools.partial(_field_desc, num_to_field))
197     add_attr('oxm_normalize_user',
198              functools.partial(_normalize_user, oxx, mod))
199     add_attr('oxm_parse',  # oxx is not required
200              functools.partial(_parse, mod))
201     add_attr('oxm_parse_header',  # oxx is not required
202              functools.partial(_parse_header, mod))
203     add_attr('oxm_serialize',
204              functools.partial(_serialize, oxx, mod))
205     add_attr('oxm_serialize_header',
206              functools.partial(_serialize_header, oxx, mod))
207
208     add_attr('oxm_to_jsondict', _to_jsondict)
209     add_attr('oxm_from_jsondict', _from_jsondict)
210
211
212 def _to_jsondict(k, uv):
213     if isinstance(uv, tuple):
214         (value, mask) = uv
215     else:
216         value = uv
217         mask = None
218     return {"OXMTlv": {"field": k, "value": value, "mask": mask}}
219
220
221 def _from_jsondict(j):
222     tlv = j['OXMTlv']
223     field = tlv['field']
224     value = tlv['value']
225     mask = tlv.get('mask')
226     if mask is None:
227         uv = value
228     else:
229         uv = (value, mask)
230     return (field, uv)