blob: 875a34ec83fa352ce4f1beefc3b28a8d14d4aaff [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"
44invalid_value = "0xeeee" # Note, as a string
45
46################################################################
47#
48# Define type data for inheritance classes:
49# instructions, actions, queue properties and OXM
50#
51# Messages are not in this group; they're treated specially for now
52#
53# These are indexed by wire protocol number
54#
55################################################################
56
57instruction_types = {
Rich Lanea06d0c32013-03-25 08:52:03 -070058 of_g.VERSION_1_0:dict(),
Rich Lane4db4d042013-05-13 18:13:48 -070059 of_g.VERSION_1_1:dict(),
60 of_g.VERSION_1_2:dict(),
61 of_g.VERSION_1_3:dict()
Rich Lanea06d0c32013-03-25 08:52:03 -070062 }
63
Rich Lane4def6972013-12-09 17:44:43 -080064instruction_id_types = {
65 of_g.VERSION_1_0:dict(),
66 of_g.VERSION_1_1:dict(),
67 of_g.VERSION_1_2:dict(),
68 of_g.VERSION_1_3:dict()
69 }
Rich Lanea06d0c32013-03-25 08:52:03 -070070
Rich Lanea06d0c32013-03-25 08:52:03 -070071action_types = {
Rich Lane4db4d042013-05-13 18:13:48 -070072 of_g.VERSION_1_0:dict(),
73 of_g.VERSION_1_1:dict(),
74 of_g.VERSION_1_2:dict(),
Rich Lane4def6972013-12-09 17:44:43 -080075 of_g.VERSION_1_3:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -070076 }
77
78action_id_types = {
Rich Lanea06d0c32013-03-25 08:52:03 -070079 of_g.VERSION_1_0:dict(),
80 of_g.VERSION_1_1:dict(),
81 of_g.VERSION_1_2:dict(),
Rich Lane4def6972013-12-09 17:44:43 -080082 of_g.VERSION_1_3:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -070083 }
84
85queue_prop_types = {
Rich Lane4db4d042013-05-13 18:13:48 -070086 of_g.VERSION_1_0:dict(),
87 of_g.VERSION_1_1:dict(),
88 of_g.VERSION_1_2:dict(),
89 of_g.VERSION_1_3:dict()
Rich Lanea06d0c32013-03-25 08:52:03 -070090 }
91
Dan Talaycoc0e802e2013-05-18 23:52:39 -070092bsn_vport_types = {
93 # version 1.0
94 of_g.VERSION_1_0:dict(
95 q_in_q = 0,
96 ),
97 # version 1.1
98 of_g.VERSION_1_1:dict(
99 q_in_q = 0,
100 ),
101 # version 1.2
102 of_g.VERSION_1_2:dict(
103 q_in_q = 0,
104 ),
105 # version 1.3
106 of_g.VERSION_1_3:dict(
107 q_in_q = 0,
108 )
109 }
110
Rich Lanea06d0c32013-03-25 08:52:03 -0700111oxm_types = {
Rich Lanea06d0c32013-03-25 08:52:03 -0700112 of_g.VERSION_1_0:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700113 of_g.VERSION_1_1:dict(),
Rich Lane4db4d042013-05-13 18:13:48 -0700114 of_g.VERSION_1_2:dict(),
115 of_g.VERSION_1_3:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700116 }
117
118hello_elem_types = {
Rich Lanea06d0c32013-03-25 08:52:03 -0700119 of_g.VERSION_1_0:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700120 of_g.VERSION_1_1:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700121 of_g.VERSION_1_2:dict(),
Rich Lane4db4d042013-05-13 18:13:48 -0700122 of_g.VERSION_1_3:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700123 }
124
125table_feature_prop_types = {
Rich Lanea06d0c32013-03-25 08:52:03 -0700126 of_g.VERSION_1_0:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700127 of_g.VERSION_1_1:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700128 of_g.VERSION_1_2:dict(),
Rich Lane4db4d042013-05-13 18:13:48 -0700129 of_g.VERSION_1_3:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700130 }
131
132meter_band_types = {
Rich Lanea06d0c32013-03-25 08:52:03 -0700133 of_g.VERSION_1_0:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700134 of_g.VERSION_1_1:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700135 of_g.VERSION_1_2:dict(),
Rich Lane4db4d042013-05-13 18:13:48 -0700136 of_g.VERSION_1_3:dict(),
Rich Lanea06d0c32013-03-25 08:52:03 -0700137 }
138
Rich Lane713d9282013-12-30 15:21:35 -0800139bsn_tlv_types = {
140 of_g.VERSION_1_0:dict(),
141 of_g.VERSION_1_1:dict(),
142 of_g.VERSION_1_2:dict(),
143 of_g.VERSION_1_3:dict(),
144 }
145
Rich Lanea06d0c32013-03-25 08:52:03 -0700146# All inheritance data for non-messages
147inheritance_data = dict(
148 of_instruction = instruction_types,
Rich Lane4def6972013-12-09 17:44:43 -0800149 of_instruction_id = instruction_id_types,
Rich Lanea06d0c32013-03-25 08:52:03 -0700150 of_action = action_types,
151 of_action_id = action_id_types,
152 of_oxm = oxm_types,
153 of_queue_prop = queue_prop_types,
154 of_hello_elem = hello_elem_types,
155 of_table_feature_prop = table_feature_prop_types,
Dan Talaycoc0e802e2013-05-18 23:52:39 -0700156 of_meter_band = meter_band_types,
157 # BSN specific inheritance extensions
Rich Lane713d9282013-12-30 15:21:35 -0800158 of_bsn_vport = bsn_vport_types,
159 of_bsn_tlv = bsn_tlv_types,
Rich Lanea06d0c32013-03-25 08:52:03 -0700160 )
161
Rich Lanea06d0c32013-03-25 08:52:03 -0700162def class_is_virtual(cls):
163 """
164 Returns True if cls is a virtual class
165 """
Rich Lanea06d0c32013-03-25 08:52:03 -0700166 if cls.find("header") > 0:
167 return True
168 if loxi_utils.class_is_list(cls):
169 return True
Rich Lane043a3d82013-12-10 10:57:30 -0800170 return loxi_globals.unified.class_by_name(cls).virtual
Rich Lanea06d0c32013-03-25 08:52:03 -0700171
172################################################################
173#
174# These are message types
175#
176################################################################
177
Rich Lanedf847e32013-05-29 16:57:30 -0700178# The hardcoded message types are for inheritance parents
Rich Lanea06d0c32013-03-25 08:52:03 -0700179message_types = {
180 # version 1.0
181 of_g.VERSION_1_0:dict(
Rob Vaterlausb3f49d92013-10-01 17:57:31 -0700182 error_msg = 1,
Rich Lanedf847e32013-05-29 16:57:30 -0700183 experimenter = 4,
Rich Lanea06d0c32013-03-25 08:52:03 -0700184 flow_mod = 14,
Rich Lanea06d0c32013-03-25 08:52:03 -0700185 stats_request = 16,
186 stats_reply = 17,
Rich Lanea06d0c32013-03-25 08:52:03 -0700187 ),
188
189 # version 1.1
190 of_g.VERSION_1_1:dict(
Rob Vaterlausb3f49d92013-10-01 17:57:31 -0700191 error_msg = 1,
Rich Lanedf847e32013-05-29 16:57:30 -0700192 experimenter = 4,
Rich Lanea06d0c32013-03-25 08:52:03 -0700193 flow_mod = 14,
Rich Lanee3113672013-12-06 17:09:57 -0800194 group_mod = 15,
Rich Lanea06d0c32013-03-25 08:52:03 -0700195 stats_request = 18,
196 stats_reply = 19,
Rich Lanea06d0c32013-03-25 08:52:03 -0700197 ),
198
199 # version 1.2
200 of_g.VERSION_1_2:dict(
Rob Vaterlausb3f49d92013-10-01 17:57:31 -0700201 error_msg = 1,
Rich Lanedf847e32013-05-29 16:57:30 -0700202 experimenter = 4,
Rich Lanea06d0c32013-03-25 08:52:03 -0700203 flow_mod = 14,
Rich Lanee3113672013-12-06 17:09:57 -0800204 group_mod = 15,
Rich Lanea06d0c32013-03-25 08:52:03 -0700205 stats_request = 18,
206 stats_reply = 19,
Rich Lanea06d0c32013-03-25 08:52:03 -0700207 ),
208
209 # version 1.3
210 of_g.VERSION_1_3:dict(
Rob Vaterlausb3f49d92013-10-01 17:57:31 -0700211 error_msg = 1,
Rich Lanedf847e32013-05-29 16:57:30 -0700212 experimenter = 4,
Rich Lanea06d0c32013-03-25 08:52:03 -0700213 flow_mod = 14,
Rich Lanee3113672013-12-06 17:09:57 -0800214 group_mod = 15,
Rich Lanea06d0c32013-03-25 08:52:03 -0700215 stats_request = 18, # FIXME Multipart
216 stats_reply = 19,
Rich Lanea06d0c32013-03-25 08:52:03 -0700217 )
218 }
219
220################################################################
221#
222# These are other objects that have a notion of type but are
223# not (yet) promoted to objects with inheritance
224#
225################################################################
226
227stats_types = {
228 # version 1.0
229 of_g.VERSION_1_0:dict(
230 desc = 0,
231 flow = 1,
232 aggregate = 2,
233 table = 3,
234 port = 4,
235 queue = 5,
236 experimenter = 0xffff
237 ),
238
239 # version 1.1
240 of_g.VERSION_1_1: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 experimenter = 0xffff
250 ),
251
252 # version 1.2
253 of_g.VERSION_1_2:dict(
254 desc = 0,
255 flow = 1,
256 aggregate = 2,
257 table = 3,
258 port = 4,
259 queue = 5,
260 group = 6,
261 group_desc = 7,
262 group_features = 8,
263 experimenter = 0xffff
264 ),
265
266 # version 1.3
267 of_g.VERSION_1_3:dict(
268 desc = 0,
269 flow = 1,
270 aggregate = 2,
271 table = 3,
272 port = 4,
273 queue = 5,
274 group = 6,
275 group_desc = 7,
276 group_features = 8,
277 meter = 9,
278 meter_config = 10,
279 meter_features = 11,
280 table_features = 12,
281 port_desc = 13,
Rich Lane353a79f2013-11-13 10:39:56 -0800282 experimenter = 0xffff,
Wilson Ng45386fb2013-12-03 13:46:42 -0800283 bsn_lacp = 0xffff,
xinwu358e6162013-12-04 16:49:48 -0800284 bsn_switch_pipeline = 0xffff,
285 bsn_port_counter = 0xffff,
286 bsn_vlan_counter = 0xffff
Rich Lanea06d0c32013-03-25 08:52:03 -0700287 )
288 }
289
290common_flow_mod_types = dict(
291 add = 0,
292 modify = 1,
293 modify_strict = 2,
294 delete = 3,
295 delete_strict = 4
296 )
297
298flow_mod_types = {
299 # version 1.0
300 of_g.VERSION_1_0:common_flow_mod_types,
301 of_g.VERSION_1_1:common_flow_mod_types,
302 of_g.VERSION_1_2:common_flow_mod_types,
303 of_g.VERSION_1_3:common_flow_mod_types
304 }
305
306# These do not translate to objects (yet)
307error_types = {
308 # version 1.0
309 of_g.VERSION_1_0:dict(
310 hello_failed = 0,
311 bad_request = 1,
312 bad_action = 2,
313 flow_mod_failed = 3,
314 port_mod_failed = 4,
315 queue_op_failed = 5
316 ),
317
318 # version 1.1
319 of_g.VERSION_1_1:dict(
320 hello_failed = 0,
321 bad_request = 1,
322 bad_action = 2,
323 bad_instruction = 3,
324 bad_match = 4,
325 flow_mod_failed = 5,
326 group_mod_failed = 6,
327 port_mod_failed = 7,
328 table_mod_failed = 8,
329 queue_op_failed = 9,
330 switch_config_failed = 10
331 ),
332
333 # version 1.2
334 of_g.VERSION_1_2:dict(
335 hello_failed = 0,
336 bad_request = 1,
337 bad_action = 2,
338 bad_instruction = 3,
339 bad_match = 4,
340 flow_mod_failed = 5,
341 group_mod_failed = 6,
342 port_mod_failed = 7,
343 table_mod_failed = 8,
344 queue_op_failed = 9,
345 switch_config_failed = 10,
346 role_request_failed = 11,
347 experimenter = 0xffff
348 ),
349
350 # version 1.3
351 of_g.VERSION_1_3:dict(
352 hello_failed = 0,
353 bad_request = 1,
354 bad_action = 2,
355 bad_instruction = 3,
356 bad_match = 4,
357 flow_mod_failed = 5,
358 group_mod_failed = 6,
359 port_mod_failed = 7,
360 table_mod_failed = 8,
361 queue_op_failed = 9,
362 switch_config_failed = 10,
363 role_request_failed = 11,
364 meter_mod_failed = 12,
365 table_features_failed= 13,
366 experimenter = 0xffff
367 )
368 }
369
Rich Lanee3113672013-12-06 17:09:57 -0800370group_mod_types = {
371 # version 1.0
372 of_g.VERSION_1_0:dict(),
373
374 # version 1.1
375 of_g.VERSION_1_1:dict(
376 add = 0,
377 modify = 1,
378 delete = 2
379 ),
380
381 # version 1.2
382 of_g.VERSION_1_2:dict(
383 add = 0,
384 modify = 1,
385 delete = 2
386 ),
387
388 # version 1.3
389 of_g.VERSION_1_3:dict(
390 add = 0,
391 modify = 1,
392 delete = 2
393 )
394 }
395
Rich Lanea06d0c32013-03-25 08:52:03 -0700396##
397# These are the objects whose length is specified by an external
398# reference, specifically another data member in the class.
Andreas Wundsam53256162013-05-02 14:05:53 -0700399#
Rich Lanea06d0c32013-03-25 08:52:03 -0700400#external_length_spec = {
401# ("of_packet_out", "actions", OF_VERSION_1_0) : "actions_len",
402# ("of_packet_out", "actions", OF_VERSION_1_1) : "actions_len",
403# ("of_packet_out", "actions", OF_VERSION_1_2) : "actions_len",
404# ("of_packet_out", "actions", OF_VERSION_1_3) : "actions_len"
405#}
406
407
408################################################################
409#
Andreas Wundsam53256162013-05-02 14:05:53 -0700410# type_val is the primary data structure that maps an
Rich Lanea06d0c32013-03-25 08:52:03 -0700411# (class_name, version) pair to the wire data type value
412#
413################################################################
414
415type_val = dict()
Rich Lane6bb28dd2013-05-13 15:19:14 -0700416inheritance_map = dict()
Rich Lanea06d0c32013-03-25 08:52:03 -0700417
Rich Lane6bb28dd2013-05-13 15:19:14 -0700418def generate_maps():
419 for parent, versioned in inheritance_data.items():
420 inheritance_map[parent] = set()
421 for ver, subclasses in versioned.items():
422 for subcls in subclasses:
423 inheritance_map[parent].add(subcls)
Rich Lanea06d0c32013-03-25 08:52:03 -0700424
Rich Lane6bb28dd2013-05-13 15:19:14 -0700425 for version, classes in message_types.items():
426 for cls in classes:
427 name = "of_" + cls
428 type_val[(name, version)] = classes[cls]
Rich Lanea06d0c32013-03-25 08:52:03 -0700429
Rich Lane6bb28dd2013-05-13 15:19:14 -0700430 for parent, versioned in inheritance_data.items():
431 for version, subclasses in versioned.items():
432 for subcls, value in subclasses.items():
433 name = parent + "_" + subcls
434 type_val[(name, version)] = value
435
436 # Special case OF-1.2 match type
Rich Lanea72c98e2013-07-12 16:40:06 -0700437 type_val[("of_match_v3", of_g.VERSION_1_2)] = 1
438 type_val[("of_match_v3", of_g.VERSION_1_3)] = 1
Rich Lanea06d0c32013-03-25 08:52:03 -0700439
440# Utility function
441def dict_to_array(d, m_val, def_val=-1):
442 """
443 Given a dictionary, d, with each value a small integer,
444 produce an array indexed by the integer whose value is the key.
445 @param d The dictionary
446 @param m_val Ignore values greater than m_val
447 @param def_val The default value (for indices not in range of d)
448 """
449
450 # Get the max value in range for hash
451 max_val = 0
452 for key in d:
453 if (d[key] > max_val) and (d[key] < m_val):
454 max_val = d[key]
455 ar = []
456 for x in range(0, max_val + 1):
457 ar.append(def_val)
458 for key in d:
459 if (d[key] < m_val):
460 ar[d[key]] = key
461 return ar
462
463def type_array_len(version_indexed, max_val):
464 """
465 Given versioned information about a type, calculate how long
466 the unified array should be.
467
Andreas Wundsam53256162013-05-02 14:05:53 -0700468 @param version_indexed A dict indexed by version. Each value is a
Rich Lanea06d0c32013-03-25 08:52:03 -0700469 dict indexed by a name and whose value is an integer
470 @param max_val Ignore values greater than this for length calcs
471 """
472 # First, find the max length of all arrays
473 arr_len = 0
474 for version, val_dict in version_indexed.items():
475 ar = dict_to_array(val_dict, max_val, invalid_type)
476 if arr_len < len(ar):
477 arr_len = len(ar)
478 return arr_len
479
Rich Lanea06d0c32013-03-25 08:52:03 -0700480def sub_class_map(base_type, version):
481 """
482 Returns an iterable object giving the instance nameys and subclass types
483 for the base_type, version values
484 """
485 rv = []
486 if base_type not in inheritance_map:
487 return rv
488
489 for instance in inheritance_map[base_type]:
490 subcls = loxi_utils.instance_to_class(instance, base_type)
491 if not loxi_utils.class_in_version(subcls, version):
492 continue
493 rv.append((instance, subcls))
494
495 return rv
496
497################################################################
498#
499# Extension related data and functions
500#
501################################################################
502
503# Per OF Version, per experimenter, map exp msg type (subtype) to object IDs
504# @fixme Generate defines for OF_<exp>_SUBTYPE_<msg> for the values below?
505extension_message_subtype = {
506 # version 1.0
507 of_g.VERSION_1_0:dict( # Version 1.0 extensions
508 bsn = { # BSN extensions; indexed by class name, value is subtype
Rich Lanea06d0c32013-03-25 08:52:03 -0700509 },
510 nicira = { # Nicira extensions, value is subtype
Rich Lanea06d0c32013-03-25 08:52:03 -0700511 },
512 ),
513 of_g.VERSION_1_1:dict( # Version 1.0 extensions
514 bsn = { # BSN extensions; indexed by class name, value is subtype
Rich Lanea06d0c32013-03-25 08:52:03 -0700515 },
516 ),
517 of_g.VERSION_1_2:dict( # Version 1.0 extensions
518 bsn = { # BSN extensions; indexed by class name, value is subtype
Rich Lanea06d0c32013-03-25 08:52:03 -0700519 },
520 ),
521 of_g.VERSION_1_3:dict( # Version 1.0 extensions
522 bsn = { # BSN extensions; indexed by class name, value is subtype
Rich Lanea06d0c32013-03-25 08:52:03 -0700523 },
524 ),
525}
526
527# Set to empty dict if no extension actions defined
528# Per OF Version, per experimenter, map actions to subtype
529extension_action_subtype = {
530 # version 1.0
531 of_g.VERSION_1_0:dict( # Version 1.0 extensions
532 bsn = { # of_action_bsn_
Rich Lanea06d0c32013-03-25 08:52:03 -0700533 },
534 nicira = { # of_action_nicira_
Rich Lanea06d0c32013-03-25 08:52:03 -0700535 }
536 ),
537 of_g.VERSION_1_1:dict( # Version 1.0 extensions
538 bsn = { # of_action_bsn_
Rich Lanea06d0c32013-03-25 08:52:03 -0700539 },
540 nicira = { # of_action_nicira_
Rich Lanea06d0c32013-03-25 08:52:03 -0700541 }
542 ),
543 of_g.VERSION_1_2:dict( # Version 1.0 extensions
544 bsn = { # of_action_bsn_
Rich Lanea06d0c32013-03-25 08:52:03 -0700545 },
546 nicira = { # of_action_nicira_
Rich Lanea06d0c32013-03-25 08:52:03 -0700547 }
548 ),
549 of_g.VERSION_1_3:dict( # Version 1.0 extensions
550 bsn = { # of_action_bsn_
Rich Lanea06d0c32013-03-25 08:52:03 -0700551 },
552 nicira = { # of_action_nicira_
Rich Lanea06d0c32013-03-25 08:52:03 -0700553 }
554 ),
555}
556
557# Set to empty dict if no extension actions defined
558# Per OF Version, per experimenter, map actions to subtype
559extension_action_id_subtype = {
560 # version 1.0
561 of_g.VERSION_1_0:dict(),
562 of_g.VERSION_1_1:dict(),
563 of_g.VERSION_1_2:dict(),
564 of_g.VERSION_1_3:dict( # Version 1.3 extensions
565 bsn = { # of_action_bsn_
Rich Lanea06d0c32013-03-25 08:52:03 -0700566 },
567 nicira = { # of_action_nicira_
Rich Lanea06d0c32013-03-25 08:52:03 -0700568 }
569 ),
570}
571
572# Set to empty dict if no extension instructions defined
Rich Laneef7b9942013-11-18 16:29:28 -0800573extension_instruction_subtype = {
574 # version 1.0
575 of_g.VERSION_1_0:dict(),
576 of_g.VERSION_1_1:dict(),
577 of_g.VERSION_1_2:dict(),
578 of_g.VERSION_1_3:dict(
579 bsn = { # of_instruction_bsn_
580 },
581 nicira = { # of_instruction_nicira_
582 }
583 ),
584}
Rich Lanea06d0c32013-03-25 08:52:03 -0700585
586# Set to empty dict if no extension instructions defined
587extension_queue_prop_subtype = {}
588
589# Set to empty dict if no extension instructions defined
590extension_table_feature_prop_subtype = {}
591
592extension_objects = [
593 extension_message_subtype,
594 extension_action_subtype,
595 extension_action_id_subtype,
596 extension_instruction_subtype,
597 extension_queue_prop_subtype,
598 extension_table_feature_prop_subtype
599]
600
601################################################################
602# These are extension type generic (for messages, actions...)
603################################################################
604
605def extension_to_experimenter_name(cls):
606 """
607 Return the name of the experimenter if class is an
608 extension, else None
609
610 This is brute force; we search all extension data for a match
611 """
Andreas Wundsam53256162013-05-02 14:05:53 -0700612
Rich Lanea06d0c32013-03-25 08:52:03 -0700613 for ext_obj in extension_objects:
614 for version, exp_list in ext_obj.items():
615 for exp_name, classes in exp_list.items():
616 if cls in classes:
617 return exp_name
618 return None
619
620def extension_to_experimenter_id(cls):
621 """
622 Return the ID of the experimenter if class is an
623 extension, else None
624 """
625 exp_name = extension_to_experimenter_name(cls)
626 if exp_name:
627 return of_g.experimenter_name_to_id[exp_name]
628 return None
629
630def extension_to_experimenter_macro_name(cls):
631 """
632 Return the "macro name" of the ID of the experimenter if class is an
633 extension, else None
634 """
635 exp_name = extension_to_experimenter_name(cls)
636 if exp_name:
637 return "OF_EXPERIMENTER_ID_" + exp_name.upper()
638 return None
639
640def extension_to_subtype(cls, version):
641 """
642 Generic across all extension objects, return subtype identifier
643 """
644 for ext_obj in extension_objects:
645 for version, exp_list in ext_obj.items():
646 for exp_name, classes in exp_list.items():
647 if cls in classes:
648 return classes[cls]
649
650def class_is_extension(cls, version):
651 """
652 Return True if class, version is recognized as an extension
653 of any type (message, action....)
654
655 Accepts of_g.OF_VERSION_ANY
656 """
657
658 for ext_obj in extension_objects:
659 if cls_is_ext_obj(cls, version, ext_obj):
660 return True
661
662 return False
663
664# Internal
665def cls_is_ext_obj(cls, version, ext_obj):
666 """
667 @brief Return True if cls in an extension of type ext_obj
668 @param cls The class to check
669 @param version The version to check
670 @param ext_obj The extension object dictionary (messages, actions...)
671
672 Accepts of_g.VERSION_ANY
673 """
674
675 # Call with each version if "any" is passed
676 if version == of_g.VERSION_ANY:
677 for v in of_g.of_version_range:
678 if cls_is_ext_obj(cls, v, ext_obj):
679 return True
680 else: # Version specified
681 if version in ext_obj:
682 for exp, subtype_vals in ext_obj[version].items():
683 if cls in subtype_vals:
684 return True
685
686 return False
Andreas Wundsam53256162013-05-02 14:05:53 -0700687
Rich Lanea06d0c32013-03-25 08:52:03 -0700688################################################################
689# These are extension message specific
690################################################################
691
692def message_is_extension(cls, version):
693 """
694 Return True if cls, version is recognized as an extension
695 This is brute force, searching records for a match
696 """
697 return cls_is_ext_obj(cls, version, extension_message_subtype)
698
699def extension_message_to_subtype(cls, version):
700 """
701 Return the subtype of the experimenter message if the class is an
702 extension, else None
703 """
704 if version in extension_message_subtype:
705 for exp, classes in extension_message_subtype[version].items():
706 for ext_class, subtype in classes.items():
707 if cls == ext_class:
708 return subtype
709 return None
710
711################################################################
712# These are extension action specific
713################################################################
714
715def action_is_extension(cls, version):
716 """
717 Return True if cls, version is recognized as an action extension
718 This is brute force, searching records for a match
719 """
720 return cls_is_ext_obj(cls, version, extension_action_subtype)
721
722def extension_action_to_subtype(cls, version):
723 """
724 Return the ID of the action subtype (for its experimenteer)
725 if class is an action extension, else None
726 """
727 if version in extension_action_subtype:
728 for exp, classes in extension_action_subtype[version].items():
729 if cls in classes:
730 return classes[cls]
731
732 return None
733
734################################################################
735# These are extension action specific
736################################################################
737
738def action_id_is_extension(cls, version):
739 """
740 Return True if cls, version is recognized as an action ID extension
741 This is brute force, searching records for a match
742 """
743 if version not in [of_g.VERSION_1_3]: # Action IDs only 1.3
744 return False
745 return cls_is_ext_obj(cls, version, extension_action_id_subtype)
746
747def extension_action_id_to_subtype(cls, version):
748 """
749 Return the ID of the action ID subtype (for its experimenteer)
750 if class is an action ID extension, else None
751 """
752 if version in extension_action_id_subtype:
753 for exp, classes in extension_action_id_subtype[version].items():
754 if cls in classes:
755 return classes[cls]
756
757 return None
758
759################################################################
760# These are extension instruction specific
761################################################################
762
763def instruction_is_extension(cls, version):
764 """
765 Return True if cls, version is recognized as an instruction extension
766 This is brute force, searching records for a match
767 """
768 return cls_is_ext_obj(cls, version, extension_instruction_subtype)
769
770################################################################
771# These are extension queue_prop specific
772################################################################
773
774def queue_prop_is_extension(cls, version):
775 """
776 Return True if cls, version is recognized as an instruction extension
777 This is brute force, searching records for a match
778 """
779 return cls_is_ext_obj(cls, version, extension_queue_prop_subtype)
780
781################################################################
782# These are extension table_feature_prop specific
783################################################################
784
785def table_feature_prop_is_extension(cls, version):
786 """
787 Return True if cls, version is recognized as an instruction extension
788 This is brute force, searching records for a match
789 """
790 return cls_is_ext_obj(cls, version,
791 extension_table_feature_prop_subtype)