blob: af43a15c14e68341685ab7e510432c74686badd2 [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 = {
92 # version 1.0
93 of_g.VERSION_1_0:dict(
94 q_in_q = 0,
95 ),
96 # version 1.1
97 of_g.VERSION_1_1:dict(
98 q_in_q = 0,
99 ),
100 # version 1.2
101 of_g.VERSION_1_2:dict(
102 q_in_q = 0,
103 ),
104 # version 1.3
105 of_g.VERSION_1_3:dict(
106 q_in_q = 0,
107 )
108 }
109
Rich Lanea06d0c32013-03-25 08:52:03 -0700110oxm_types = {
Rich Lanea06d0c32013-03-25 08:52:03 -0700111 of_g.VERSION_1_0:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700112 of_g.VERSION_1_1:dict(),
Rich Lane4db4d042013-05-13 18:13:48 -0700113 of_g.VERSION_1_2:dict(),
114 of_g.VERSION_1_3:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700115 }
116
117hello_elem_types = {
Rich Lanea06d0c32013-03-25 08:52:03 -0700118 of_g.VERSION_1_0:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700119 of_g.VERSION_1_1:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700120 of_g.VERSION_1_2:dict(),
Rich Lane4db4d042013-05-13 18:13:48 -0700121 of_g.VERSION_1_3:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700122 }
123
124table_feature_prop_types = {
Rich Lanea06d0c32013-03-25 08:52:03 -0700125 of_g.VERSION_1_0:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700126 of_g.VERSION_1_1:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700127 of_g.VERSION_1_2:dict(),
Rich Lane4db4d042013-05-13 18:13:48 -0700128 of_g.VERSION_1_3:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700129 }
130
131meter_band_types = {
Rich Lanea06d0c32013-03-25 08:52:03 -0700132 of_g.VERSION_1_0:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700133 of_g.VERSION_1_1:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700134 of_g.VERSION_1_2:dict(),
Rich Lane4db4d042013-05-13 18:13:48 -0700135 of_g.VERSION_1_3:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700136 }
137
Rich Lane713d9282013-12-30 15:21:35 -0800138bsn_tlv_types = {
139 of_g.VERSION_1_0:dict(),
140 of_g.VERSION_1_1:dict(),
141 of_g.VERSION_1_2:dict(),
142 of_g.VERSION_1_3:dict(),
143 }
144
Rich Lanea06d0c32013-03-25 08:52:03 -0700145# All inheritance data for non-messages
146inheritance_data = dict(
147 of_instruction = instruction_types,
Rich Lane4def6972013-12-09 17:44:43 -0800148 of_instruction_id = instruction_id_types,
Rich Lanea06d0c32013-03-25 08:52:03 -0700149 of_action = action_types,
150 of_action_id = action_id_types,
151 of_oxm = oxm_types,
152 of_queue_prop = queue_prop_types,
153 of_hello_elem = hello_elem_types,
154 of_table_feature_prop = table_feature_prop_types,
Dan Talaycoc0e802e2013-05-18 23:52:39 -0700155 of_meter_band = meter_band_types,
156 # BSN specific inheritance extensions
Rich Lane713d9282013-12-30 15:21:35 -0800157 of_bsn_vport = bsn_vport_types,
158 of_bsn_tlv = bsn_tlv_types,
Rich Lanea06d0c32013-03-25 08:52:03 -0700159 )
160
Rich Lanea06d0c32013-03-25 08:52:03 -0700161def class_is_virtual(cls):
162 """
163 Returns True if cls is a virtual class
164 """
Rich Lanea06d0c32013-03-25 08:52:03 -0700165 if cls.find("header") > 0:
166 return True
167 if loxi_utils.class_is_list(cls):
168 return True
Rich Lane043a3d82013-12-10 10:57:30 -0800169 return loxi_globals.unified.class_by_name(cls).virtual
Rich Lanea06d0c32013-03-25 08:52:03 -0700170
171################################################################
172#
173# These are message types
174#
175################################################################
176
Rich Lanedf847e32013-05-29 16:57:30 -0700177# The hardcoded message types are for inheritance parents
Rich Lanea06d0c32013-03-25 08:52:03 -0700178message_types = {
179 # version 1.0
180 of_g.VERSION_1_0:dict(
Rob Vaterlausb3f49d92013-10-01 17:57:31 -0700181 error_msg = 1,
Rich Lanedf847e32013-05-29 16:57:30 -0700182 experimenter = 4,
Rich Lanea06d0c32013-03-25 08:52:03 -0700183 flow_mod = 14,
Rich Lanea06d0c32013-03-25 08:52:03 -0700184 stats_request = 16,
185 stats_reply = 17,
Rich Lanea06d0c32013-03-25 08:52:03 -0700186 ),
187
188 # version 1.1
189 of_g.VERSION_1_1:dict(
Rob Vaterlausb3f49d92013-10-01 17:57:31 -0700190 error_msg = 1,
Rich Lanedf847e32013-05-29 16:57:30 -0700191 experimenter = 4,
Rich Lanea06d0c32013-03-25 08:52:03 -0700192 flow_mod = 14,
Rich Lanee3113672013-12-06 17:09:57 -0800193 group_mod = 15,
Rich Lanea06d0c32013-03-25 08:52:03 -0700194 stats_request = 18,
195 stats_reply = 19,
Rich Lanea06d0c32013-03-25 08:52:03 -0700196 ),
197
198 # version 1.2
199 of_g.VERSION_1_2:dict(
Rob Vaterlausb3f49d92013-10-01 17:57:31 -0700200 error_msg = 1,
Rich Lanedf847e32013-05-29 16:57:30 -0700201 experimenter = 4,
Rich Lanea06d0c32013-03-25 08:52:03 -0700202 flow_mod = 14,
Rich Lanee3113672013-12-06 17:09:57 -0800203 group_mod = 15,
Rich Lanea06d0c32013-03-25 08:52:03 -0700204 stats_request = 18,
205 stats_reply = 19,
Rich Lanea06d0c32013-03-25 08:52:03 -0700206 ),
207
208 # version 1.3
209 of_g.VERSION_1_3:dict(
Rob Vaterlausb3f49d92013-10-01 17:57:31 -0700210 error_msg = 1,
Rich Lanedf847e32013-05-29 16:57:30 -0700211 experimenter = 4,
Rich Lanea06d0c32013-03-25 08:52:03 -0700212 flow_mod = 14,
Rich Lanee3113672013-12-06 17:09:57 -0800213 group_mod = 15,
Rich Lanea06d0c32013-03-25 08:52:03 -0700214 stats_request = 18, # FIXME Multipart
215 stats_reply = 19,
Rich Lanea06d0c32013-03-25 08:52:03 -0700216 )
217 }
218
219################################################################
220#
221# These are other objects that have a notion of type but are
222# not (yet) promoted to objects with inheritance
223#
224################################################################
225
226stats_types = {
227 # version 1.0
228 of_g.VERSION_1_0:dict(
229 desc = 0,
230 flow = 1,
231 aggregate = 2,
232 table = 3,
233 port = 4,
234 queue = 5,
235 experimenter = 0xffff
236 ),
237
238 # version 1.1
239 of_g.VERSION_1_1:dict(
240 desc = 0,
241 flow = 1,
242 aggregate = 2,
243 table = 3,
244 port = 4,
245 queue = 5,
246 group = 6,
247 group_desc = 7,
248 experimenter = 0xffff
249 ),
250
251 # version 1.2
252 of_g.VERSION_1_2:dict(
253 desc = 0,
254 flow = 1,
255 aggregate = 2,
256 table = 3,
257 port = 4,
258 queue = 5,
259 group = 6,
260 group_desc = 7,
261 group_features = 8,
262 experimenter = 0xffff
263 ),
264
265 # version 1.3
266 of_g.VERSION_1_3:dict(
267 desc = 0,
268 flow = 1,
269 aggregate = 2,
270 table = 3,
271 port = 4,
272 queue = 5,
273 group = 6,
274 group_desc = 7,
275 group_features = 8,
276 meter = 9,
277 meter_config = 10,
278 meter_features = 11,
279 table_features = 12,
280 port_desc = 13,
Rich Lane353a79f2013-11-13 10:39:56 -0800281 experimenter = 0xffff,
Wilson Ng45386fb2013-12-03 13:46:42 -0800282 bsn_lacp = 0xffff,
xinwu358e6162013-12-04 16:49:48 -0800283 bsn_switch_pipeline = 0xffff,
284 bsn_port_counter = 0xffff,
285 bsn_vlan_counter = 0xffff
Rich Lanea06d0c32013-03-25 08:52:03 -0700286 )
287 }
288
289common_flow_mod_types = dict(
290 add = 0,
291 modify = 1,
292 modify_strict = 2,
293 delete = 3,
294 delete_strict = 4
295 )
296
297flow_mod_types = {
298 # version 1.0
299 of_g.VERSION_1_0:common_flow_mod_types,
300 of_g.VERSION_1_1:common_flow_mod_types,
301 of_g.VERSION_1_2:common_flow_mod_types,
302 of_g.VERSION_1_3:common_flow_mod_types
303 }
304
305# These do not translate to objects (yet)
306error_types = {
307 # version 1.0
308 of_g.VERSION_1_0:dict(
309 hello_failed = 0,
310 bad_request = 1,
311 bad_action = 2,
312 flow_mod_failed = 3,
313 port_mod_failed = 4,
314 queue_op_failed = 5
315 ),
316
317 # version 1.1
318 of_g.VERSION_1_1:dict(
319 hello_failed = 0,
320 bad_request = 1,
321 bad_action = 2,
322 bad_instruction = 3,
323 bad_match = 4,
324 flow_mod_failed = 5,
325 group_mod_failed = 6,
326 port_mod_failed = 7,
327 table_mod_failed = 8,
328 queue_op_failed = 9,
329 switch_config_failed = 10
330 ),
331
332 # version 1.2
333 of_g.VERSION_1_2:dict(
334 hello_failed = 0,
335 bad_request = 1,
336 bad_action = 2,
337 bad_instruction = 3,
338 bad_match = 4,
339 flow_mod_failed = 5,
340 group_mod_failed = 6,
341 port_mod_failed = 7,
342 table_mod_failed = 8,
343 queue_op_failed = 9,
344 switch_config_failed = 10,
345 role_request_failed = 11,
346 experimenter = 0xffff
347 ),
348
349 # version 1.3
350 of_g.VERSION_1_3:dict(
351 hello_failed = 0,
352 bad_request = 1,
353 bad_action = 2,
354 bad_instruction = 3,
355 bad_match = 4,
356 flow_mod_failed = 5,
357 group_mod_failed = 6,
358 port_mod_failed = 7,
359 table_mod_failed = 8,
360 queue_op_failed = 9,
361 switch_config_failed = 10,
362 role_request_failed = 11,
363 meter_mod_failed = 12,
364 table_features_failed= 13,
365 experimenter = 0xffff
366 )
367 }
368
Rich Lanee3113672013-12-06 17:09:57 -0800369group_mod_types = {
370 # version 1.0
371 of_g.VERSION_1_0:dict(),
372
373 # version 1.1
374 of_g.VERSION_1_1:dict(
375 add = 0,
376 modify = 1,
377 delete = 2
378 ),
379
380 # version 1.2
381 of_g.VERSION_1_2:dict(
382 add = 0,
383 modify = 1,
384 delete = 2
385 ),
386
387 # version 1.3
388 of_g.VERSION_1_3:dict(
389 add = 0,
390 modify = 1,
391 delete = 2
392 )
393 }
394
Rich Lanea06d0c32013-03-25 08:52:03 -0700395################################################################
396#
Andreas Wundsam53256162013-05-02 14:05:53 -0700397# type_val is the primary data structure that maps an
Rich Lanea06d0c32013-03-25 08:52:03 -0700398# (class_name, version) pair to the wire data type value
399#
400################################################################
401
402type_val = dict()
Rich Lane6bb28dd2013-05-13 15:19:14 -0700403inheritance_map = dict()
Rich Lanea06d0c32013-03-25 08:52:03 -0700404
Rich Lane6bb28dd2013-05-13 15:19:14 -0700405def generate_maps():
406 for parent, versioned in inheritance_data.items():
407 inheritance_map[parent] = set()
408 for ver, subclasses in versioned.items():
409 for subcls in subclasses:
410 inheritance_map[parent].add(subcls)
Rich Lanea06d0c32013-03-25 08:52:03 -0700411
Rich Lane6bb28dd2013-05-13 15:19:14 -0700412 for version, classes in message_types.items():
413 for cls in classes:
414 name = "of_" + cls
415 type_val[(name, version)] = classes[cls]
Rich Lanea06d0c32013-03-25 08:52:03 -0700416
Rich Lane6bb28dd2013-05-13 15:19:14 -0700417 for parent, versioned in inheritance_data.items():
418 for version, subclasses in versioned.items():
419 for subcls, value in subclasses.items():
420 name = parent + "_" + subcls
421 type_val[(name, version)] = value
422
423 # Special case OF-1.2 match type
Rich Lanea72c98e2013-07-12 16:40:06 -0700424 type_val[("of_match_v3", of_g.VERSION_1_2)] = 1
425 type_val[("of_match_v3", of_g.VERSION_1_3)] = 1
Rich Lanea06d0c32013-03-25 08:52:03 -0700426
427# Utility function
428def dict_to_array(d, m_val, def_val=-1):
429 """
430 Given a dictionary, d, with each value a small integer,
431 produce an array indexed by the integer whose value is the key.
432 @param d The dictionary
433 @param m_val Ignore values greater than m_val
434 @param def_val The default value (for indices not in range of d)
435 """
436
437 # Get the max value in range for hash
438 max_val = 0
439 for key in d:
440 if (d[key] > max_val) and (d[key] < m_val):
441 max_val = d[key]
442 ar = []
443 for x in range(0, max_val + 1):
444 ar.append(def_val)
445 for key in d:
446 if (d[key] < m_val):
447 ar[d[key]] = key
448 return ar
449
450def type_array_len(version_indexed, max_val):
451 """
452 Given versioned information about a type, calculate how long
453 the unified array should be.
454
Andreas Wundsam53256162013-05-02 14:05:53 -0700455 @param version_indexed A dict indexed by version. Each value is a
Rich Lanea06d0c32013-03-25 08:52:03 -0700456 dict indexed by a name and whose value is an integer
457 @param max_val Ignore values greater than this for length calcs
458 """
459 # First, find the max length of all arrays
460 arr_len = 0
461 for version, val_dict in version_indexed.items():
462 ar = dict_to_array(val_dict, max_val, invalid_type)
463 if arr_len < len(ar):
464 arr_len = len(ar)
465 return arr_len
466
Rich Lanea06d0c32013-03-25 08:52:03 -0700467def sub_class_map(base_type, version):
468 """
469 Returns an iterable object giving the instance nameys and subclass types
470 for the base_type, version values
471 """
472 rv = []
473 if base_type not in inheritance_map:
474 return rv
475
476 for instance in inheritance_map[base_type]:
477 subcls = loxi_utils.instance_to_class(instance, base_type)
478 if not loxi_utils.class_in_version(subcls, version):
479 continue
480 rv.append((instance, subcls))
481
482 return rv
483
484################################################################
485#
486# Extension related data and functions
487#
488################################################################
489
490# Per OF Version, per experimenter, map exp msg type (subtype) to object IDs
491# @fixme Generate defines for OF_<exp>_SUBTYPE_<msg> for the values below?
492extension_message_subtype = {
493 # version 1.0
494 of_g.VERSION_1_0:dict( # Version 1.0 extensions
495 bsn = { # BSN extensions; indexed by class name, value is subtype
Rich Lanea06d0c32013-03-25 08:52:03 -0700496 },
497 nicira = { # Nicira extensions, value is subtype
Rich Lanea06d0c32013-03-25 08:52:03 -0700498 },
499 ),
500 of_g.VERSION_1_1:dict( # Version 1.0 extensions
501 bsn = { # BSN extensions; indexed by class name, value is subtype
Rich Lanea06d0c32013-03-25 08:52:03 -0700502 },
503 ),
504 of_g.VERSION_1_2:dict( # Version 1.0 extensions
505 bsn = { # BSN extensions; indexed by class name, value is subtype
Rich Lanea06d0c32013-03-25 08:52:03 -0700506 },
507 ),
508 of_g.VERSION_1_3:dict( # Version 1.0 extensions
509 bsn = { # BSN extensions; indexed by class name, value is subtype
Rich Lanea06d0c32013-03-25 08:52:03 -0700510 },
511 ),
512}
513
514# Set to empty dict if no extension actions defined
515# Per OF Version, per experimenter, map actions to subtype
516extension_action_subtype = {
517 # version 1.0
518 of_g.VERSION_1_0: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_1: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 of_g.VERSION_1_2:dict( # Version 1.0 extensions
531 bsn = { # of_action_bsn_
Rich Lanea06d0c32013-03-25 08:52:03 -0700532 },
533 nicira = { # of_action_nicira_
Rich Lanea06d0c32013-03-25 08:52:03 -0700534 }
535 ),
536 of_g.VERSION_1_3:dict( # Version 1.0 extensions
537 bsn = { # of_action_bsn_
Rich Lanea06d0c32013-03-25 08:52:03 -0700538 },
539 nicira = { # of_action_nicira_
Rich Lanea06d0c32013-03-25 08:52:03 -0700540 }
541 ),
542}
543
544# Set to empty dict if no extension actions defined
545# Per OF Version, per experimenter, map actions to subtype
546extension_action_id_subtype = {
547 # version 1.0
548 of_g.VERSION_1_0:dict(),
549 of_g.VERSION_1_1:dict(),
550 of_g.VERSION_1_2:dict(),
551 of_g.VERSION_1_3:dict( # Version 1.3 extensions
552 bsn = { # of_action_bsn_
Rich Lanea06d0c32013-03-25 08:52:03 -0700553 },
554 nicira = { # of_action_nicira_
Rich Lanea06d0c32013-03-25 08:52:03 -0700555 }
556 ),
557}
558
559# Set to empty dict if no extension instructions defined
Rich Laneef7b9942013-11-18 16:29:28 -0800560extension_instruction_subtype = {
561 # version 1.0
562 of_g.VERSION_1_0:dict(),
563 of_g.VERSION_1_1:dict(),
564 of_g.VERSION_1_2:dict(),
565 of_g.VERSION_1_3:dict(
566 bsn = { # of_instruction_bsn_
567 },
568 nicira = { # of_instruction_nicira_
569 }
570 ),
571}