backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / ofproto / oxs_fields.py
1 # Copyright (C) 2015 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 # there are two representations of value which this module deal with.
17 #
18 # "user"
19 #   the readable value which are strings.
20 #
21 # "internal"
22 #   the on-wire bytes value.
23
24 # There are two types of OXS headers.
25 #
26 # 32-bit OXS header
27 #  31                           16 15          9 8 7             0
28 # +-------------------------------+-------------+-+---------------+
29 # | class                         | field       |r| length        |
30 # +-------------------------------+-------------+-+---------------+
31 #
32 # 64-bit experimenter OXS header
33 #  31                           16 15          9 8 7             0
34 # +-------------------------------+-------------+-+---------------+
35 # | class (OFPXSC_EXPERIMENTER)   | field       |r| length        |
36 # +-------------------------------+-------------+-+---------------+
37 # | experimenter ID                                               |
38 # +---------------------------------------------------------------+
39 #
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 # +----------------------+-------+--------------------------------------------+
52
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).
56
57 from ryu.ofproto.oxx_fields import (
58     _from_user,
59     _from_user_header,
60     _to_user,
61     _to_user_header,
62     _field_desc,
63     _parse,
64     _parse_header,
65     _serialize,
66     _serialize_header)
67
68
69 OFPXSC_OPENFLOW_BASIC = 0x8002
70 OFPXSC_EXPERIMENTER = 0xFFFF
71
72
73 OFPXSC_HEADER_PACK_STR = '!I'
74 OFPXSC_EXP_HEADER_PACK_STR = '!I'
75
76
77 class _OxsClass(object):
78     # _class = OFPXSC_* must be an attribute of subclass.
79     def __init__(self, name, num, type_):
80         self.name = name
81         self.oxs_field = num
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
87         self.type = type_
88
89
90 class OpenFlowBasic(_OxsClass):
91     _class = OFPXSC_OPENFLOW_BASIC
92
93
94 class _Experimenter(_OxsClass):
95     _class = OFPXSC_EXPERIMENTER
96     # experimenter_id must be an attribute of subclass.
97
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
102
103
104 def generate(modname):
105     import sys
106     import functools
107
108     mod = sys.modules[modname]
109
110     def add_attr(k, v):
111         setattr(mod, k, v)
112
113     for i in mod.oxs_types:
114         if isinstance(i.num, tuple):
115             continue
116         if i._class != OFPXSC_OPENFLOW_BASIC:
117             continue
118         uk = i.name.upper()
119         ofpxst = i.oxs_field
120         td = i.type
121         add_attr('OFPXST_OFB_' + uk, ofpxst)
122         add_attr('OXS_OF_' + uk, mod.oxs_tlv_header(ofpxst, td.size))
123
124     # 'oxx' indicates the OpenFlow Extensible class type.
125     # eg.) 'oxs' indicates that this class is OXS class.
126     oxx = 'oxs'
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)
129
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))
149
150     add_attr('oxs_to_jsondict', _to_jsondict)
151     add_attr('oxs_from_jsondict', _from_jsondict)
152
153
154 def _to_jsondict(k, uv):
155     return {"OXSTlv": {"field": k, "value": uv}}
156
157
158 def _from_jsondict(j):
159     tlv = j['OXSTlv']
160     field = tlv['field']
161     value = tlv['value']
162     return (field, value)