blob: ee452fca89b30fc2fb82087f9c137f2ee94393b1 [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
Jonathan Stoutc26cbdb2014-03-04 12:46:17 -0500587extension_instruction_id_subtype = {
588 # version 1.0
589 of_g.VERSION_1_0:dict(),
590 of_g.VERSION_1_1:dict(),
591 of_g.VERSION_1_2:dict(),
592 of_g.VERSION_1_3:dict(
593 bsn = { # of_instruction_bsn_
594 },
595 nicira = { # of_instruction_nicira_
596 }
597 ),
598}
599
600# Set to empty dict if no extension instructions defined
Rich Lanea06d0c32013-03-25 08:52:03 -0700601extension_queue_prop_subtype = {}
602
603# Set to empty dict if no extension instructions defined
604extension_table_feature_prop_subtype = {}
605
606extension_objects = [
607 extension_message_subtype,
608 extension_action_subtype,
609 extension_action_id_subtype,
610 extension_instruction_subtype,
Jonathan Stoutc26cbdb2014-03-04 12:46:17 -0500611 extension_instruction_id_subtype,
Rich Lanea06d0c32013-03-25 08:52:03 -0700612 extension_queue_prop_subtype,
613 extension_table_feature_prop_subtype
614]
615
616################################################################
617# These are extension type generic (for messages, actions...)
618################################################################
619
620def extension_to_experimenter_name(cls):
621 """
622 Return the name of the experimenter if class is an
623 extension, else None
624
625 This is brute force; we search all extension data for a match
626 """
Andreas Wundsam53256162013-05-02 14:05:53 -0700627
Rich Lanea06d0c32013-03-25 08:52:03 -0700628 for ext_obj in extension_objects:
629 for version, exp_list in ext_obj.items():
630 for exp_name, classes in exp_list.items():
631 if cls in classes:
632 return exp_name
633 return None
634
635def extension_to_experimenter_id(cls):
636 """
637 Return the ID of the experimenter if class is an
638 extension, else None
639 """
640 exp_name = extension_to_experimenter_name(cls)
641 if exp_name:
642 return of_g.experimenter_name_to_id[exp_name]
643 return None
644
645def extension_to_experimenter_macro_name(cls):
646 """
647 Return the "macro name" of the ID of the experimenter if class is an
648 extension, else None
649 """
650 exp_name = extension_to_experimenter_name(cls)
651 if exp_name:
652 return "OF_EXPERIMENTER_ID_" + exp_name.upper()
653 return None
654
655def extension_to_subtype(cls, version):
656 """
657 Generic across all extension objects, return subtype identifier
658 """
659 for ext_obj in extension_objects:
660 for version, exp_list in ext_obj.items():
661 for exp_name, classes in exp_list.items():
662 if cls in classes:
663 return classes[cls]
664
665def class_is_extension(cls, version):
666 """
667 Return True if class, version is recognized as an extension
668 of any type (message, action....)
669
670 Accepts of_g.OF_VERSION_ANY
671 """
672
673 for ext_obj in extension_objects:
674 if cls_is_ext_obj(cls, version, ext_obj):
675 return True
676
677 return False
678
679# Internal
680def cls_is_ext_obj(cls, version, ext_obj):
681 """
682 @brief Return True if cls in an extension of type ext_obj
683 @param cls The class to check
684 @param version The version to check
685 @param ext_obj The extension object dictionary (messages, actions...)
686
687 Accepts of_g.VERSION_ANY
688 """
689
690 # Call with each version if "any" is passed
691 if version == of_g.VERSION_ANY:
692 for v in of_g.of_version_range:
693 if cls_is_ext_obj(cls, v, ext_obj):
694 return True
695 else: # Version specified
696 if version in ext_obj:
697 for exp, subtype_vals in ext_obj[version].items():
698 if cls in subtype_vals:
699 return True
700
701 return False
Andreas Wundsam53256162013-05-02 14:05:53 -0700702
Rich Lanea06d0c32013-03-25 08:52:03 -0700703################################################################
704# These are extension message specific
705################################################################
706
707def message_is_extension(cls, version):
708 """
709 Return True if cls, version is recognized as an extension
710 This is brute force, searching records for a match
711 """
712 return cls_is_ext_obj(cls, version, extension_message_subtype)
713
714def extension_message_to_subtype(cls, version):
715 """
716 Return the subtype of the experimenter message if the class is an
717 extension, else None
718 """
719 if version in extension_message_subtype:
720 for exp, classes in extension_message_subtype[version].items():
721 for ext_class, subtype in classes.items():
722 if cls == ext_class:
723 return subtype
724 return None
725
726################################################################
727# These are extension action specific
728################################################################
729
730def action_is_extension(cls, version):
731 """
732 Return True if cls, version is recognized as an action extension
733 This is brute force, searching records for a match
734 """
735 return cls_is_ext_obj(cls, version, extension_action_subtype)
736
737def extension_action_to_subtype(cls, version):
738 """
739 Return the ID of the action subtype (for its experimenteer)
740 if class is an action extension, else None
741 """
742 if version in extension_action_subtype:
743 for exp, classes in extension_action_subtype[version].items():
744 if cls in classes:
745 return classes[cls]
746
747 return None
748
749################################################################
750# These are extension action specific
751################################################################
752
753def action_id_is_extension(cls, version):
754 """
755 Return True if cls, version is recognized as an action ID extension
756 This is brute force, searching records for a match
757 """
758 if version not in [of_g.VERSION_1_3]: # Action IDs only 1.3
759 return False
760 return cls_is_ext_obj(cls, version, extension_action_id_subtype)
761
762def extension_action_id_to_subtype(cls, version):
763 """
764 Return the ID of the action ID subtype (for its experimenteer)
765 if class is an action ID extension, else None
766 """
767 if version in extension_action_id_subtype:
768 for exp, classes in extension_action_id_subtype[version].items():
769 if cls in classes:
770 return classes[cls]
771
772 return None
773
774################################################################
775# These are extension instruction specific
776################################################################
777
778def instruction_is_extension(cls, version):
779 """
780 Return True if cls, version is recognized as an instruction extension
781 This is brute force, searching records for a match
782 """
783 return cls_is_ext_obj(cls, version, extension_instruction_subtype)
784
785################################################################
Jonathan Stoutc26cbdb2014-03-04 12:46:17 -0500786# These are extension instruction specific
787################################################################
788
789def instruction_id_is_extension(cls, version):
790 """
791 Return True if cls, version is recognized as an instruction ID extension
792 This is brute force, searching records for a match
793 """
794 return cls_is_ext_obj(cls, version, extension_instruction_id_subtype)
795
796################################################################
Rich Lanea06d0c32013-03-25 08:52:03 -0700797# These are extension queue_prop specific
798################################################################
799
800def queue_prop_is_extension(cls, version):
801 """
802 Return True if cls, version is recognized as an instruction extension
803 This is brute force, searching records for a match
804 """
805 return cls_is_ext_obj(cls, version, extension_queue_prop_subtype)
806
807################################################################
808# These are extension table_feature_prop specific
809################################################################
810
811def table_feature_prop_is_extension(cls, version):
812 """
813 Return True if cls, version is recognized as an instruction extension
814 This is brute force, searching records for a match
815 """
816 return cls_is_ext_obj(cls, version,
817 extension_table_feature_prop_subtype)