loci: clean up generating remaining type_maps
diff --git a/c_gen/build_of_g.py b/c_gen/build_of_g.py
index 784dcea..d919e42 100755
--- a/c_gen/build_of_g.py
+++ b/c_gen/build_of_g.py
@@ -361,48 +361,6 @@
"""
Use the type members in the IR to fill out the legacy type_maps.
"""
-
- def split_inherited_cls(cls):
- if cls == 'of_meter_band_stats': # HACK not a subtype of of_meter_band
- return None, None
- for parent in sorted(type_maps.inheritance_data.keys(), reverse=True):
- if cls.startswith(parent):
- return (parent, cls[len(parent)+1:])
- return None, None
-
- def find_experimenter(parent, cls):
- for experimenter in sorted(of_g.experimenter_name_to_id.keys(), reverse=True):
- prefix = parent + '_' + experimenter
- if cls.startswith(prefix) and cls != prefix:
- return experimenter
- return None
-
- def find_type_value(ofclass, m_name):
- for m in ofclass.members:
- if isinstance(m, OFTypeMember) and m.name == m_name:
- return m.value
- raise KeyError("ver=%d, cls=%s, m_name=%s" % (wire_version, cls, m_name))
-
- # Most inheritance classes: actions, instructions, etc
- for version, protocol in loxi_globals.ir.items():
- wire_version = version.wire_version
- for ofclass in protocol.classes:
- cls = ofclass.name
- parent, subcls = split_inherited_cls(cls)
- if not (parent and subcls):
- continue
- if parent == 'of_oxm':
- type_len = find_type_value(ofclass, 'type_len')
- oxm_class = (type_len >> 16) & 0xffff
- if oxm_class != 0x8000:
- # Do not include experimenter OXMs in the main table
- val = type_maps.invalid_type
- else:
- val = (type_len >> 8) & 0xff
- else:
- val = find_type_value(ofclass, 'type')
- type_maps.inheritance_data[parent][wire_version][subcls] = val
-
type_maps.generate_maps()
def analyze_input():
diff --git a/c_gen/type_maps.py b/c_gen/type_maps.py
index 03e1c2a..221adbe 100644
--- a/c_gen/type_maps.py
+++ b/c_gen/type_maps.py
@@ -53,98 +53,19 @@
#
################################################################
-instruction_types = {
- of_g.VERSION_1_0:dict(),
- of_g.VERSION_1_1:dict(),
- of_g.VERSION_1_2:dict(),
- of_g.VERSION_1_3:dict()
- }
-
-instruction_id_types = {
- of_g.VERSION_1_0:dict(),
- of_g.VERSION_1_1:dict(),
- of_g.VERSION_1_2:dict(),
- of_g.VERSION_1_3:dict()
- }
-
-action_types = {
- of_g.VERSION_1_0:dict(),
- of_g.VERSION_1_1:dict(),
- of_g.VERSION_1_2:dict(),
- of_g.VERSION_1_3:dict(),
- }
-
-action_id_types = {
- of_g.VERSION_1_0:dict(),
- of_g.VERSION_1_1:dict(),
- of_g.VERSION_1_2:dict(),
- of_g.VERSION_1_3:dict(),
- }
-
-queue_prop_types = {
- of_g.VERSION_1_0:dict(),
- of_g.VERSION_1_1:dict(),
- of_g.VERSION_1_2:dict(),
- of_g.VERSION_1_3:dict()
- }
-
-bsn_vport_types = {
- of_g.VERSION_1_0:dict(),
- of_g.VERSION_1_1:dict(),
- of_g.VERSION_1_2:dict(),
- of_g.VERSION_1_3:dict(),
- }
-
-oxm_types = {
- of_g.VERSION_1_0:dict(),
- of_g.VERSION_1_1:dict(),
- of_g.VERSION_1_2:dict(),
- of_g.VERSION_1_3:dict(),
- }
-
-hello_elem_types = {
- of_g.VERSION_1_0:dict(),
- of_g.VERSION_1_1:dict(),
- of_g.VERSION_1_2:dict(),
- of_g.VERSION_1_3:dict(),
- }
-
-table_feature_prop_types = {
- of_g.VERSION_1_0:dict(),
- of_g.VERSION_1_1:dict(),
- of_g.VERSION_1_2:dict(),
- of_g.VERSION_1_3:dict(),
- }
-
-meter_band_types = {
- of_g.VERSION_1_0:dict(),
- of_g.VERSION_1_1:dict(),
- of_g.VERSION_1_2:dict(),
- of_g.VERSION_1_3:dict(),
- }
-
-bsn_tlv_types = {
- of_g.VERSION_1_0:dict(),
- of_g.VERSION_1_1:dict(),
- of_g.VERSION_1_2:dict(),
- of_g.VERSION_1_3:dict(),
- }
-
-# All inheritance data for non-messages
-inheritance_data = dict(
- of_instruction = instruction_types,
- of_instruction_id = instruction_id_types,
- of_action = action_types,
- of_action_id = action_id_types,
- of_oxm = oxm_types,
- of_queue_prop = queue_prop_types,
- of_hello_elem = hello_elem_types,
- of_table_feature_prop = table_feature_prop_types,
- of_meter_band = meter_band_types,
- # BSN specific inheritance extensions
- of_bsn_vport = bsn_vport_types,
- of_bsn_tlv = bsn_tlv_types,
- )
+inheritance_roots = [
+ 'of_instruction',
+ 'of_instruction_id',
+ 'of_action',
+ 'of_action_id',
+ 'of_oxm',
+ 'of_queue_prop',
+ 'of_hello_elem',
+ 'of_table_feature_prop',
+ 'of_meter_band',
+ 'of_bsn_vport',
+ 'of_bsn_tlv',
+]
def class_is_virtual(cls):
"""
@@ -156,32 +77,41 @@
return True
return loxi_globals.unified.class_by_name(cls).virtual
-################################################################
-#
-# type_val is the primary data structure that maps an
-# (class_name, version) pair to the wire data type value
-#
-################################################################
+# map from root class name to (map from wire version to set of subclass names)
+inheritance_data = {}
-type_val = dict()
+# map from parent class name to set of subclass names
inheritance_map = dict()
def generate_maps():
- for parent, versioned in inheritance_data.items():
- inheritance_map[parent] = set()
- for ver, subclasses in versioned.items():
- for subcls in subclasses:
- inheritance_map[parent].add(subcls)
+ def inheritance_root(ofclass):
+ if not ofclass.superclass:
+ if ofclass.name in inheritance_roots:
+ return ofclass
+ else:
+ return None
+ else:
+ return inheritance_root(ofclass.superclass)
- for parent, versioned in inheritance_data.items():
- for version, subclasses in versioned.items():
- for subcls, value in subclasses.items():
- name = parent + "_" + subcls
- type_val[(name, version)] = value
+ for version, protocol in loxi_globals.ir.items():
+ wire_version = version.wire_version
+ for ofclass in protocol.classes:
+ root = inheritance_root(ofclass)
+ if not root or root == ofclass:
+ continue
- # Special case OF-1.2 match type
- type_val[("of_match_v3", of_g.VERSION_1_2)] = 1
- type_val[("of_match_v3", of_g.VERSION_1_3)] = 1
+ assert ofclass.name.startswith(root.name + '_')
+ subcls = ofclass.name[len(root.name)+1:]
+
+ if root.name not in inheritance_data:
+ inheritance_data[root.name] = {}
+ if wire_version not in inheritance_data[root.name]:
+ inheritance_data[root.name][wire_version] = set()
+ inheritance_data[root.name][wire_version].add(subcls)
+
+ if root.name not in inheritance_map:
+ inheritance_map[root.name] = set()
+ inheritance_map[root.name].add(subcls)
def sub_class_map(base_type, version):
"""