blob: a479cc3b5d9b9ae1c037c68081185faaa5977a9c [file] [log] [blame]
Andreas Wundsamd30c1072013-11-15 13:36:57 -08001## List of mixed data types
2#
3# This is a list of data types which require special treatment
4# because the underlying datatype has changed between versions.
5# The main example is port which went from 16 to 32 bits. We
6# define per-version accessors for these types and those are
7# used in place of the normal ones.
8#
9# The wire protocol number is used to identify versions. For now,
10# the value is the name of the type to use for that version
11#
12# This is the map between the external type (like of_port_no_t)
13# which is used by customers of this code and the internal
14# datatypes (like uint16_t) that appear on the wire for a
15# particular version.
16#
17from collections import namedtuple
18import logging
19
20import loxi_front_end.frontend_ir as fe
21import loxi_ir.ir
22
23ofp_constants = dict(
24 OF_MAX_TABLE_NAME_LEN = 32,
25 OF_MAX_PORT_NAME_LEN = 16,
26 OF_ETH_ALEN = 6,
27 OF_DESC_STR_LEN = 256,
Praseed Balakrishnan7f718782014-09-18 17:02:48 -070028 OF_SERIAL_NUM_LEN = 32,
Murat Parlakisikf95672c2016-12-05 00:53:17 -080029 OF_APP_CODE_LEN = 15,
30 OF_CONTROLLER_URI_LEN = 32
Andreas Wundsamd30c1072013-11-15 13:36:57 -080031)
32
33
34of_mixed_types = dict(
35 of_port_no_t = {
36 1: "uint16_t",
37 2: "uint32_t",
38 3: "uint32_t",
39 4: "uint32_t",
alshabib9f50e482014-08-23 17:10:57 -050040 5: "uint32_t",
Murat Parlakisikf95672c2016-12-05 00:53:17 -080041 6: "uint32_t",
Andreas Wundsamd30c1072013-11-15 13:36:57 -080042 "short_name":"port_no"
43 },
44 of_port_desc_t = {
45 1: "of_port_desc_t",
46 2: "of_port_desc_t",
47 3: "of_port_desc_t",
48 4: "of_port_desc_t",
alshabib9f50e482014-08-23 17:10:57 -050049 5: "of_port_desc_t",
Murat Parlakisikf95672c2016-12-05 00:53:17 -080050 6: "of_port_desc_t",
Andreas Wundsamd30c1072013-11-15 13:36:57 -080051 "short_name":"port_desc"
52 },
53 of_bsn_vport_t = {
54 1: "of_bsn_vport_t",
55 2: "of_bsn_vport_t",
56 3: "of_bsn_vport_t",
57 4: "of_bsn_vport_t",
alshabib9f50e482014-08-23 17:10:57 -050058 5: "of_bsn_vport_t",
Murat Parlakisikf95672c2016-12-05 00:53:17 -080059 6: "of_bsn_vport_t",
Andreas Wundsamd30c1072013-11-15 13:36:57 -080060 "short_name":"bsn_vport"
61 },
62 of_fm_cmd_t = { # Flow mod command went from u16 to u8
63 1: "uint16_t",
64 2: "uint8_t",
65 3: "uint8_t",
66 4: "uint8_t",
alshabib9f50e482014-08-23 17:10:57 -050067 5: "uint8_t",
Murat Parlakisikf95672c2016-12-05 00:53:17 -080068 6: "uint8_t",
Andreas Wundsamd30c1072013-11-15 13:36:57 -080069 "short_name":"fm_cmd"
70 },
71 of_wc_bmap_t = { # Wildcard bitmap
72 1: "uint32_t",
73 2: "uint32_t",
74 3: "uint64_t",
75 4: "uint64_t",
alshabib9f50e482014-08-23 17:10:57 -050076 5: "uint64_t",
Murat Parlakisikf95672c2016-12-05 00:53:17 -080077 6: "uint64_t",
Andreas Wundsamd30c1072013-11-15 13:36:57 -080078 "short_name":"wc_bmap"
79 },
80 of_match_bmap_t = { # Match bitmap
81 1: "uint32_t",
82 2: "uint32_t",
83 3: "uint64_t",
84 4: "uint64_t",
alshabib9f50e482014-08-23 17:10:57 -050085 5: "uint64_t",
Murat Parlakisikf95672c2016-12-05 00:53:17 -080086 6: "uint64_t",
Andreas Wundsamd30c1072013-11-15 13:36:57 -080087 "short_name":"match_bmap"
88 },
89 of_match_t = { # Match object
90 1: "of_match_v1_t",
91 2: "of_match_v2_t",
92 3: "of_match_v3_t",
93 4: "of_match_v3_t", # Currently uses same match as 1.2 (v3).
alshabib9f50e482014-08-23 17:10:57 -050094 5: "of_match_v3_t", # Currently uses same match as 1.2 (v3).
Murat Parlakisikf95672c2016-12-05 00:53:17 -080095 6: "of_match_v3_t",
Andreas Wundsamd30c1072013-11-15 13:36:57 -080096 "short_name":"match"
97 },
Murat Parlakisikf95672c2016-12-05 00:53:17 -080098 of_stat_t = { #Statistics object
99 6: "of_stat_v6_t",
100 "short_name":"stat"
101 },
102 of_time_t = { # time object
103 6: "of_time_t",
104 "short_name":"time"
105 }
Andreas Wundsamd30c1072013-11-15 13:36:57 -0800106)
107
108## basic lengths
109of_base_lengths = dict(
110 char = (1, True),
111 uint8_t = (1, True),
112 uint16_t = (2, True),
113 uint32_t = (4, True),
114 uint64_t = (8, True),
115 of_mac_addr_t = (6, True),
116 of_ipv4_t = (4, True),
117 of_ipv6_t = (16, True),
118 of_port_name_t = (ofp_constants["OF_MAX_PORT_NAME_LEN"], True),
119 of_table_name_t = (ofp_constants["OF_MAX_TABLE_NAME_LEN"], True),
120 of_desc_str_t = (ofp_constants["OF_DESC_STR_LEN"], True),
121 of_serial_num_t = (ofp_constants["OF_SERIAL_NUM_LEN"], True),
Murat Parlakisikf95672c2016-12-05 00:53:17 -0800122 of_controller_uri_t = (ofp_constants["OF_CONTROLLER_URI_LEN"], True),
Rich Lanef8a3d002014-03-19 13:33:52 -0700123 of_str64_t = (64, True),
Brian O'Connor58a73e32015-05-28 11:51:27 -0700124 of_str32_t = (32, True),
125 of_str6_t = (6, True),
Andreas Wundsamd30c1072013-11-15 13:36:57 -0800126 of_match_v1_t = (40, True),
127 of_match_v2_t = (88, True),
128 of_match_v3_t = (8, False),
Murat Parlakisikf95672c2016-12-05 00:53:17 -0800129 of_stat_v6_t = (8, False),
Andreas Wundsamd30c1072013-11-15 13:36:57 -0800130 of_octets_t = (0, False),
131 of_bitmap_128_t = (16, True),
Rich Lane51833982013-12-03 13:02:45 -0800132 of_checksum_128_t = (16, True),
Praseed Balakrishnan7f718782014-09-18 17:02:48 -0700133 of_app_code_t = (15,True),
Praseed Balakrishnan2ed6da02014-09-18 17:02:48 -0700134 of_sig_id_t = (6, True),
Jimmy Jin646d1222016-05-13 10:47:24 -0700135 of_bitmap_256_t = (32, True),
Rich Lane931eab32014-11-13 15:42:29 -0800136 of_bitmap_512_t = (64, True),
Yafit Hadarf8caac02015-08-25 10:21:44 +0300137 of_odu_sig_id_t = (16, True),
138 of_och_sig_id_t = (6, True),
Murat Parlakisikf95672c2016-12-05 00:53:17 -0800139 of_time_t = (16, True)
Andreas Wundsamd30c1072013-11-15 13:36:57 -0800140)
141
142def type_dec_to_count_base(m_type):
143 """
144 Resolve a type declaration like uint8_t[4] to a count (4) and base_type
145 (uint8_t)
146
147 @param m_type The string type declaration to process
148 """
149 count = 1
150 chk_ar = m_type.split('[')
151 if len(chk_ar) > 1:
152 count_str = chk_ar[1].split(']')[0]
153 if count_str in ofp_constants:
154 count = ofp_constants[count_str]
155 else:
156 count = int(count_str)
157 base_type = chk_ar[0]
158 else:
159 base_type = m_type
160 return count, base_type
161
162
163LengthInfo = namedtuple("LengthInfo", ("offset", "base_length", "is_fixed_length"))
164
165def calc_lengths(version, fe_class, existing_classes, existing_enums):
166 offset_fixed = True
167 offset = 0
168
169 member_infos = {}
170 for member in fe_class.members:
171 member_offset = offset if offset_fixed else None
172
173 if isinstance(member, fe.OFPadMember):
174 member_base_length = member.length
175 member_fixed_length = True
176 else:
177 m_type = member.oftype
178 name = member.name
179
180 member_base_length = 0
181 if m_type.find("list(") == 0:
182 member_fixed_length = False
183 elif m_type.find("struct") == 0:
184 raise Exception("Error: recursive struct found: {}, {}"
185 .format(fe_class.name, name))
186 elif m_type == "octets":
187 member_fixed_length = False
188 else:
189 member_base_length, member_fixed_length = member_length(version, fe_class, member, existing_classes, existing_enums)
190
191 if not member_fixed_length:
192 offset_fixed = False
193
194 member_infos[member] = LengthInfo(member_offset, member_base_length,
195 member_fixed_length)
196 offset += member_base_length
197
198 base_length = offset
199 fixed_length = offset_fixed if not fe_class.virtual else False
200 return (base_length, fixed_length, member_infos)
201
202def member_length(version, fe_class, fe_member, existing_classes, existing_enums):
203 """
204 return the length of an ir member.
205
206 @return tuple (base_length, length_fixed)
207 """
208 count, base_type = type_dec_to_count_base(fe_member.oftype)
209
Andreas Wundsamd30c1072013-11-15 13:36:57 -0800210 if base_type in of_mixed_types:
211 base_type = of_mixed_types[base_type][version.wire_version]
212
213 base_class = base_type[:-2]
214 if base_class in existing_classes:
215 member_ir_class = existing_classes[base_class]
216 bytes = member_ir_class.base_length
217 length_fixed = member_ir_class.is_fixed_length
Rich Lane824c0882014-10-16 14:26:53 -0700218 if member_ir_class.has_external_alignment:
219 bytes = (bytes + 7) & ~7
Andreas Wundsamd30c1072013-11-15 13:36:57 -0800220 else:
221 if base_type in existing_enums:
222 enum = existing_enums[base_type]
223 base_type = enum.wire_type
224
225 if base_type in of_base_lengths:
226 bytes, length_fixed = of_base_lengths[base_type]
227 else:
228 raise Exception("Unknown type for {}.{}: {}".format(fe_class.name, fe_member.name, base_type))
229
230 return (count * bytes), length_fixed