blob: 6cbb3a51dfe5a674dc098b906b49d6cb0d457aaf [file] [log] [blame]
Rich Lanea06d0c32013-03-25 08:52:03 -07001# Copyright 2013, Big Switch Networks, Inc.
2#
3# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
4# the following special exception:
5#
6# LOXI Exception
7#
8# As a special exception to the terms of the EPL, you may distribute libraries
9# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
10# that copyright and licensing notices generated by LoxiGen are not altered or removed
11# from the LoxiGen Libraries and the notice provided below is (i) included in
12# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
13# documentation for the LoxiGen Libraries, if distributed in binary form.
14#
15# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
16#
17# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
18# a copy of the EPL at:
19#
20# http://www.eclipse.org/legal/epl-v10.html
21#
22# Unless required by applicable law or agreed to in writing, software
23# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
24# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
25# EPL for the specific language governing permissions and limitations
26# under the EPL.
27
28#
29# Miscellaneous type information
30#
31# Define the map between sub-class types and wire values. In each
32# case, an array indexed by wire version gives a hash from identifier
33# to wire value.
34#
35
Andreas Wundsam542a13c2013-11-15 13:28:55 -080036import c_gen.of_g_legacy as of_g
Rich Lanea06d0c32013-03-25 08:52:03 -070037import sys
38from generic_utils import *
Rich Lanea06d0c32013-03-25 08:52:03 -070039import loxi_utils.loxi_utils as loxi_utils
Andreas Wundsam542a13c2013-11-15 13:28:55 -080040import c_gen.loxi_utils_legacy as loxi_utils
Rich Lane043a3d82013-12-10 10:57:30 -080041import loxi_globals
Rich Lanea06d0c32013-03-25 08:52:03 -070042
43invalid_type = "invalid_type"
Rich Lanea06d0c32013-03-25 08:52:03 -070044
45################################################################
46#
47# Define type data for inheritance classes:
48# instructions, actions, queue properties and OXM
49#
50# Messages are not in this group; they're treated specially for now
51#
52# These are indexed by wire protocol number
53#
54################################################################
55
56instruction_types = {
Rich Lanea06d0c32013-03-25 08:52:03 -070057 of_g.VERSION_1_0:dict(),
Rich Lane4db4d042013-05-13 18:13:48 -070058 of_g.VERSION_1_1:dict(),
59 of_g.VERSION_1_2:dict(),
60 of_g.VERSION_1_3:dict()
Rich Lanea06d0c32013-03-25 08:52:03 -070061 }
62
Rich Lane4def6972013-12-09 17:44:43 -080063instruction_id_types = {
64 of_g.VERSION_1_0:dict(),
65 of_g.VERSION_1_1:dict(),
66 of_g.VERSION_1_2:dict(),
67 of_g.VERSION_1_3:dict()
68 }
Rich Lanea06d0c32013-03-25 08:52:03 -070069
Rich Lanea06d0c32013-03-25 08:52:03 -070070action_types = {
Rich Lane4db4d042013-05-13 18:13:48 -070071 of_g.VERSION_1_0:dict(),
72 of_g.VERSION_1_1:dict(),
73 of_g.VERSION_1_2:dict(),
Rich Lane4def6972013-12-09 17:44:43 -080074 of_g.VERSION_1_3:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -070075 }
76
77action_id_types = {
Rich Lanea06d0c32013-03-25 08:52:03 -070078 of_g.VERSION_1_0:dict(),
79 of_g.VERSION_1_1:dict(),
80 of_g.VERSION_1_2:dict(),
Rich Lane4def6972013-12-09 17:44:43 -080081 of_g.VERSION_1_3:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -070082 }
83
84queue_prop_types = {
Rich Lane4db4d042013-05-13 18:13:48 -070085 of_g.VERSION_1_0:dict(),
86 of_g.VERSION_1_1:dict(),
87 of_g.VERSION_1_2:dict(),
88 of_g.VERSION_1_3:dict()
Rich Lanea06d0c32013-03-25 08:52:03 -070089 }
90
Dan Talaycoc0e802e2013-05-18 23:52:39 -070091bsn_vport_types = {
Wilson Ngc349e352014-04-14 17:06:32 -070092 of_g.VERSION_1_0:dict(),
93 of_g.VERSION_1_1:dict(),
94 of_g.VERSION_1_2:dict(),
95 of_g.VERSION_1_3:dict(),
Dan Talaycoc0e802e2013-05-18 23:52:39 -070096 }
97
Rich Lanea06d0c32013-03-25 08:52:03 -070098oxm_types = {
Rich Lanea06d0c32013-03-25 08:52:03 -070099 of_g.VERSION_1_0:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700100 of_g.VERSION_1_1:dict(),
Rich Lane4db4d042013-05-13 18:13:48 -0700101 of_g.VERSION_1_2:dict(),
102 of_g.VERSION_1_3:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700103 }
104
105hello_elem_types = {
Rich Lanea06d0c32013-03-25 08:52:03 -0700106 of_g.VERSION_1_0:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700107 of_g.VERSION_1_1:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700108 of_g.VERSION_1_2:dict(),
Rich Lane4db4d042013-05-13 18:13:48 -0700109 of_g.VERSION_1_3:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700110 }
111
112table_feature_prop_types = {
Rich Lanea06d0c32013-03-25 08:52:03 -0700113 of_g.VERSION_1_0:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700114 of_g.VERSION_1_1:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700115 of_g.VERSION_1_2:dict(),
Rich Lane4db4d042013-05-13 18:13:48 -0700116 of_g.VERSION_1_3:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700117 }
118
119meter_band_types = {
Rich Lanea06d0c32013-03-25 08:52:03 -0700120 of_g.VERSION_1_0:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700121 of_g.VERSION_1_1:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700122 of_g.VERSION_1_2:dict(),
Rich Lane4db4d042013-05-13 18:13:48 -0700123 of_g.VERSION_1_3:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700124 }
125
Rich Lane713d9282013-12-30 15:21:35 -0800126bsn_tlv_types = {
127 of_g.VERSION_1_0:dict(),
128 of_g.VERSION_1_1:dict(),
129 of_g.VERSION_1_2:dict(),
130 of_g.VERSION_1_3:dict(),
131 }
132
Rich Lanea06d0c32013-03-25 08:52:03 -0700133# All inheritance data for non-messages
134inheritance_data = dict(
135 of_instruction = instruction_types,
Rich Lane4def6972013-12-09 17:44:43 -0800136 of_instruction_id = instruction_id_types,
Rich Lanea06d0c32013-03-25 08:52:03 -0700137 of_action = action_types,
138 of_action_id = action_id_types,
139 of_oxm = oxm_types,
140 of_queue_prop = queue_prop_types,
141 of_hello_elem = hello_elem_types,
142 of_table_feature_prop = table_feature_prop_types,
Dan Talaycoc0e802e2013-05-18 23:52:39 -0700143 of_meter_band = meter_band_types,
144 # BSN specific inheritance extensions
Rich Lane713d9282013-12-30 15:21:35 -0800145 of_bsn_vport = bsn_vport_types,
146 of_bsn_tlv = bsn_tlv_types,
Rich Lanea06d0c32013-03-25 08:52:03 -0700147 )
148
Rich Lanea06d0c32013-03-25 08:52:03 -0700149def class_is_virtual(cls):
150 """
151 Returns True if cls is a virtual class
152 """
Harshmeet Singh19d566b2014-10-06 14:08:06 -0700153 if cls.endswith("header"):
Rich Lanea06d0c32013-03-25 08:52:03 -0700154 return True
155 if loxi_utils.class_is_list(cls):
156 return True
Rich Lane043a3d82013-12-10 10:57:30 -0800157 return loxi_globals.unified.class_by_name(cls).virtual
Rich Lanea06d0c32013-03-25 08:52:03 -0700158
159################################################################
160#
161# These are message types
162#
163################################################################
164
Rich Lanedf847e32013-05-29 16:57:30 -0700165# The hardcoded message types are for inheritance parents
Rich Lanea06d0c32013-03-25 08:52:03 -0700166message_types = {
167 # version 1.0
168 of_g.VERSION_1_0:dict(
Rob Vaterlausb3f49d92013-10-01 17:57:31 -0700169 error_msg = 1,
Rich Lanedf847e32013-05-29 16:57:30 -0700170 experimenter = 4,
Rich Lanea06d0c32013-03-25 08:52:03 -0700171 flow_mod = 14,
Rich Lanea06d0c32013-03-25 08:52:03 -0700172 stats_request = 16,
173 stats_reply = 17,
Rich Lanea06d0c32013-03-25 08:52:03 -0700174 ),
175
176 # version 1.1
177 of_g.VERSION_1_1:dict(
Rob Vaterlausb3f49d92013-10-01 17:57:31 -0700178 error_msg = 1,
Rich Lanedf847e32013-05-29 16:57:30 -0700179 experimenter = 4,
Rich Lanea06d0c32013-03-25 08:52:03 -0700180 flow_mod = 14,
Rich Lanee3113672013-12-06 17:09:57 -0800181 group_mod = 15,
Rich Lanea06d0c32013-03-25 08:52:03 -0700182 stats_request = 18,
183 stats_reply = 19,
Rich Lanea06d0c32013-03-25 08:52:03 -0700184 ),
185
186 # version 1.2
187 of_g.VERSION_1_2:dict(
Rob Vaterlausb3f49d92013-10-01 17:57:31 -0700188 error_msg = 1,
Rich Lanedf847e32013-05-29 16:57:30 -0700189 experimenter = 4,
Rich Lanea06d0c32013-03-25 08:52:03 -0700190 flow_mod = 14,
Rich Lanee3113672013-12-06 17:09:57 -0800191 group_mod = 15,
Rich Lanea06d0c32013-03-25 08:52:03 -0700192 stats_request = 18,
193 stats_reply = 19,
Rich Lanea06d0c32013-03-25 08:52:03 -0700194 ),
195
196 # version 1.3
197 of_g.VERSION_1_3:dict(
Rob Vaterlausb3f49d92013-10-01 17:57:31 -0700198 error_msg = 1,
Rich Lanedf847e32013-05-29 16:57:30 -0700199 experimenter = 4,
Rich Lanea06d0c32013-03-25 08:52:03 -0700200 flow_mod = 14,
Rich Lanee3113672013-12-06 17:09:57 -0800201 group_mod = 15,
Rich Lanea06d0c32013-03-25 08:52:03 -0700202 stats_request = 18, # FIXME Multipart
203 stats_reply = 19,
Rich Lanea06d0c32013-03-25 08:52:03 -0700204 )
205 }
206
207################################################################
208#
209# These are other objects that have a notion of type but are
210# not (yet) promoted to objects with inheritance
211#
212################################################################
213
214stats_types = {
215 # version 1.0
216 of_g.VERSION_1_0:dict(
217 desc = 0,
218 flow = 1,
219 aggregate = 2,
220 table = 3,
221 port = 4,
222 queue = 5,
223 experimenter = 0xffff
224 ),
225
226 # version 1.1
227 of_g.VERSION_1_1:dict(
228 desc = 0,
229 flow = 1,
230 aggregate = 2,
231 table = 3,
232 port = 4,
233 queue = 5,
234 group = 6,
235 group_desc = 7,
236 experimenter = 0xffff
237 ),
238
239 # version 1.2
240 of_g.VERSION_1_2:dict(
241 desc = 0,
242 flow = 1,
243 aggregate = 2,
244 table = 3,
245 port = 4,
246 queue = 5,
247 group = 6,
248 group_desc = 7,
249 group_features = 8,
250 experimenter = 0xffff
251 ),
252
253 # version 1.3
254 of_g.VERSION_1_3:dict(
255 desc = 0,
256 flow = 1,
257 aggregate = 2,
258 table = 3,
259 port = 4,
260 queue = 5,
261 group = 6,
262 group_desc = 7,
263 group_features = 8,
264 meter = 9,
265 meter_config = 10,
266 meter_features = 11,
267 table_features = 12,
268 port_desc = 13,
Rich Lane353a79f2013-11-13 10:39:56 -0800269 experimenter = 0xffff,
Wilson Ng45386fb2013-12-03 13:46:42 -0800270 bsn_lacp = 0xffff,
xinwu358e6162013-12-04 16:49:48 -0800271 bsn_switch_pipeline = 0xffff,
272 bsn_port_counter = 0xffff,
273 bsn_vlan_counter = 0xffff
Rich Lanea06d0c32013-03-25 08:52:03 -0700274 )
275 }
276
277common_flow_mod_types = dict(
278 add = 0,
279 modify = 1,
280 modify_strict = 2,
281 delete = 3,
282 delete_strict = 4
283 )
284
285flow_mod_types = {
286 # version 1.0
287 of_g.VERSION_1_0:common_flow_mod_types,
288 of_g.VERSION_1_1:common_flow_mod_types,
289 of_g.VERSION_1_2:common_flow_mod_types,
290 of_g.VERSION_1_3:common_flow_mod_types
291 }
292
293# These do not translate to objects (yet)
294error_types = {
295 # version 1.0
296 of_g.VERSION_1_0:dict(
297 hello_failed = 0,
298 bad_request = 1,
299 bad_action = 2,
300 flow_mod_failed = 3,
301 port_mod_failed = 4,
302 queue_op_failed = 5
303 ),
304
305 # version 1.1
306 of_g.VERSION_1_1:dict(
307 hello_failed = 0,
308 bad_request = 1,
309 bad_action = 2,
310 bad_instruction = 3,
311 bad_match = 4,
312 flow_mod_failed = 5,
313 group_mod_failed = 6,
314 port_mod_failed = 7,
315 table_mod_failed = 8,
316 queue_op_failed = 9,
317 switch_config_failed = 10
318 ),
319
320 # version 1.2
321 of_g.VERSION_1_2:dict(
322 hello_failed = 0,
323 bad_request = 1,
324 bad_action = 2,
325 bad_instruction = 3,
326 bad_match = 4,
327 flow_mod_failed = 5,
328 group_mod_failed = 6,
329 port_mod_failed = 7,
330 table_mod_failed = 8,
331 queue_op_failed = 9,
332 switch_config_failed = 10,
333 role_request_failed = 11,
334 experimenter = 0xffff
335 ),
336
337 # version 1.3
338 of_g.VERSION_1_3:dict(
339 hello_failed = 0,
340 bad_request = 1,
341 bad_action = 2,
342 bad_instruction = 3,
343 bad_match = 4,
344 flow_mod_failed = 5,
345 group_mod_failed = 6,
346 port_mod_failed = 7,
347 table_mod_failed = 8,
348 queue_op_failed = 9,
349 switch_config_failed = 10,
350 role_request_failed = 11,
351 meter_mod_failed = 12,
352 table_features_failed= 13,
353 experimenter = 0xffff
354 )
355 }
356
Rich Lanee3113672013-12-06 17:09:57 -0800357group_mod_types = {
358 # version 1.0
359 of_g.VERSION_1_0:dict(),
360
361 # version 1.1
362 of_g.VERSION_1_1:dict(
363 add = 0,
364 modify = 1,
365 delete = 2
366 ),
367
368 # version 1.2
369 of_g.VERSION_1_2:dict(
370 add = 0,
371 modify = 1,
372 delete = 2
373 ),
374
375 # version 1.3
376 of_g.VERSION_1_3:dict(
377 add = 0,
378 modify = 1,
379 delete = 2
380 )
381 }
382
Rich Lanea06d0c32013-03-25 08:52:03 -0700383################################################################
384#
Andreas Wundsam53256162013-05-02 14:05:53 -0700385# type_val is the primary data structure that maps an
Rich Lanea06d0c32013-03-25 08:52:03 -0700386# (class_name, version) pair to the wire data type value
387#
388################################################################
389
390type_val = dict()
Rich Lane6bb28dd2013-05-13 15:19:14 -0700391inheritance_map = dict()
Rich Lanea06d0c32013-03-25 08:52:03 -0700392
Rich Lane6bb28dd2013-05-13 15:19:14 -0700393def generate_maps():
394 for parent, versioned in inheritance_data.items():
395 inheritance_map[parent] = set()
396 for ver, subclasses in versioned.items():
397 for subcls in subclasses:
398 inheritance_map[parent].add(subcls)
Rich Lanea06d0c32013-03-25 08:52:03 -0700399
Rich Lane6bb28dd2013-05-13 15:19:14 -0700400 for version, classes in message_types.items():
401 for cls in classes:
402 name = "of_" + cls
403 type_val[(name, version)] = classes[cls]
Rich Lanea06d0c32013-03-25 08:52:03 -0700404
Rich Lane6bb28dd2013-05-13 15:19:14 -0700405 for parent, versioned in inheritance_data.items():
406 for version, subclasses in versioned.items():
407 for subcls, value in subclasses.items():
408 name = parent + "_" + subcls
409 type_val[(name, version)] = value
410
411 # Special case OF-1.2 match type
Rich Lanea72c98e2013-07-12 16:40:06 -0700412 type_val[("of_match_v3", of_g.VERSION_1_2)] = 1
413 type_val[("of_match_v3", of_g.VERSION_1_3)] = 1
Rich Lanea06d0c32013-03-25 08:52:03 -0700414
415# Utility function
416def dict_to_array(d, m_val, def_val=-1):
417 """
418 Given a dictionary, d, with each value a small integer,
419 produce an array indexed by the integer whose value is the key.
420 @param d The dictionary
421 @param m_val Ignore values greater than m_val
422 @param def_val The default value (for indices not in range of d)
423 """
424
425 # Get the max value in range for hash
426 max_val = 0
427 for key in d:
428 if (d[key] > max_val) and (d[key] < m_val):
429 max_val = d[key]
430 ar = []
431 for x in range(0, max_val + 1):
432 ar.append(def_val)
433 for key in d:
434 if (d[key] < m_val):
435 ar[d[key]] = key
436 return ar
437
438def type_array_len(version_indexed, max_val):
439 """
440 Given versioned information about a type, calculate how long
441 the unified array should be.
442
Andreas Wundsam53256162013-05-02 14:05:53 -0700443 @param version_indexed A dict indexed by version. Each value is a
Rich Lanea06d0c32013-03-25 08:52:03 -0700444 dict indexed by a name and whose value is an integer
445 @param max_val Ignore values greater than this for length calcs
446 """
447 # First, find the max length of all arrays
448 arr_len = 0
449 for version, val_dict in version_indexed.items():
450 ar = dict_to_array(val_dict, max_val, invalid_type)
451 if arr_len < len(ar):
452 arr_len = len(ar)
453 return arr_len
454
Rich Lanea06d0c32013-03-25 08:52:03 -0700455def sub_class_map(base_type, version):
456 """
457 Returns an iterable object giving the instance nameys and subclass types
458 for the base_type, version values
459 """
460 rv = []
461 if base_type not in inheritance_map:
462 return rv
463
464 for instance in inheritance_map[base_type]:
465 subcls = loxi_utils.instance_to_class(instance, base_type)
466 if not loxi_utils.class_in_version(subcls, version):
467 continue
468 rv.append((instance, subcls))
469
470 return rv
471
472################################################################
473#
474# Extension related data and functions
475#
476################################################################
477
478# Per OF Version, per experimenter, map exp msg type (subtype) to object IDs
479# @fixme Generate defines for OF_<exp>_SUBTYPE_<msg> for the values below?
480extension_message_subtype = {
481 # version 1.0
482 of_g.VERSION_1_0:dict( # Version 1.0 extensions
483 bsn = { # BSN extensions; indexed by class name, value is subtype
Rich Lanea06d0c32013-03-25 08:52:03 -0700484 },
485 nicira = { # Nicira extensions, value is subtype
Rich Lanea06d0c32013-03-25 08:52:03 -0700486 },
487 ),
488 of_g.VERSION_1_1:dict( # Version 1.0 extensions
489 bsn = { # BSN extensions; indexed by class name, value is subtype
Rich Lanea06d0c32013-03-25 08:52:03 -0700490 },
491 ),
492 of_g.VERSION_1_2:dict( # Version 1.0 extensions
493 bsn = { # BSN extensions; indexed by class name, value is subtype
Rich Lanea06d0c32013-03-25 08:52:03 -0700494 },
495 ),
496 of_g.VERSION_1_3:dict( # Version 1.0 extensions
497 bsn = { # BSN extensions; indexed by class name, value is subtype
Rich Lanea06d0c32013-03-25 08:52:03 -0700498 },
499 ),
500}
501
502# Set to empty dict if no extension actions defined
503# Per OF Version, per experimenter, map actions to subtype
504extension_action_subtype = {
505 # version 1.0
506 of_g.VERSION_1_0:dict( # Version 1.0 extensions
507 bsn = { # of_action_bsn_
Rich Lanea06d0c32013-03-25 08:52:03 -0700508 },
509 nicira = { # of_action_nicira_
Rich Lanea06d0c32013-03-25 08:52:03 -0700510 }
511 ),
512 of_g.VERSION_1_1:dict( # Version 1.0 extensions
513 bsn = { # of_action_bsn_
Rich Lanea06d0c32013-03-25 08:52:03 -0700514 },
515 nicira = { # of_action_nicira_
Rich Lanea06d0c32013-03-25 08:52:03 -0700516 }
517 ),
518 of_g.VERSION_1_2:dict( # Version 1.0 extensions
519 bsn = { # of_action_bsn_
Rich Lanea06d0c32013-03-25 08:52:03 -0700520 },
521 nicira = { # of_action_nicira_
Rich Lanea06d0c32013-03-25 08:52:03 -0700522 }
523 ),
524 of_g.VERSION_1_3:dict( # Version 1.0 extensions
525 bsn = { # of_action_bsn_
Rich Lanea06d0c32013-03-25 08:52:03 -0700526 },
527 nicira = { # of_action_nicira_
Rich Lanea06d0c32013-03-25 08:52:03 -0700528 }
529 ),
530}
531
532# Set to empty dict if no extension actions defined
533# Per OF Version, per experimenter, map actions to subtype
534extension_action_id_subtype = {
535 # version 1.0
536 of_g.VERSION_1_0:dict(),
537 of_g.VERSION_1_1:dict(),
538 of_g.VERSION_1_2:dict(),
539 of_g.VERSION_1_3:dict( # Version 1.3 extensions
540 bsn = { # of_action_bsn_
Rich Lanea06d0c32013-03-25 08:52:03 -0700541 },
542 nicira = { # of_action_nicira_
Rich Lanea06d0c32013-03-25 08:52:03 -0700543 }
544 ),
545}
546
547# Set to empty dict if no extension instructions defined
Rich Laneef7b9942013-11-18 16:29:28 -0800548extension_instruction_subtype = {
549 # version 1.0
550 of_g.VERSION_1_0:dict(),
551 of_g.VERSION_1_1:dict(),
552 of_g.VERSION_1_2:dict(),
553 of_g.VERSION_1_3:dict(
554 bsn = { # of_instruction_bsn_
555 },
556 nicira = { # of_instruction_nicira_
557 }
558 ),
559}