loxi_ir: add support for byte alignment of messages, superclass
diff --git a/loxi_front_end/frontend.py b/loxi_front_end/frontend.py
index 5d35260..24819a1 100644
--- a/loxi_front_end/frontend.py
+++ b/loxi_front_end/frontend.py
@@ -62,8 +62,15 @@
 
     for decl_ast in ast:
         if decl_ast[0] == 'struct':
-            members = [create_member(m_ast) for m_ast in decl_ast[2]]
-            ofclass = OFClass(name=decl_ast[1], members=members)
+            # 0: "enum"
+            # 1: name
+            # 2: potentially list of [param_name, param_value]
+            # 3: [ super_class] or []
+            # 4: list of [constant_name, constant_value]+
+            super_class = decl_ast[3][0] if decl_ast[3] else ""
+            members = [create_member(m_ast) for m_ast in decl_ast[4]]
+            ofclass = OFClass(name=decl_ast[1], members=members, super_class=super_class,
+                    params = { param: value for param, value in decl_ast[2] })
             ofinput.classes.append(ofclass)
         if decl_ast[0] == 'enum':
             # 0: "enum"
diff --git a/loxi_front_end/parser.py b/loxi_front_end/parser.py
index 03d5af1..1b6b75f 100644
--- a/loxi_front_end/parser.py
+++ b/loxi_front_end/parser.py
@@ -53,8 +53,14 @@
 pad_member = P.Group(kw('pad') - s('(') - integer - s(')'))
 type_member = P.Group(tag('type') + any_type + identifier + s('==') + integer)
 data_member = P.Group(tag('data') + any_type - identifier)
+
+struct_param_name = kw("align")
+struct_param = P.Group(struct_param_name - s('=') - any_type)
+struct_param_list = P.Forward()
+struct_param_list << struct_param + P.Optional(s(',') - P.Optional(struct_param_list))
+
 struct_member = pad_member | type_member | data_member;
-struct = kw('struct') - identifier - s('{') + \
+struct = kw('struct') - identifier - P.Group(P.Optional(s('(') - struct_param_list - s(')'))) - P.Group(P.Optional(s('<') - word)) - s('{') + \
          P.Group(P.ZeroOrMore(struct_member - s(';'))) + \
          s('}') - s(';')
 
diff --git a/loxi_ir.py b/loxi_ir.py
index 8f1e822..aeefa74 100644
--- a/loxi_ir.py
+++ b/loxi_ir.py
@@ -25,6 +25,7 @@
 # EPL for the specific language governing permissions and limitations
 # under the EPL.
 
+from generic_utils import find
 from collections import namedtuple
 
 # This module is intended to be imported like this: from loxi_ir import *
@@ -72,8 +73,12 @@
 
 @param name
 @param members List of *Member objects
+@param super_class name of the super class
+@param params optional dictionary of parameters
 """
-OFClass = namedtuple('OFClass', ['name', 'members'])
+class OFClass(namedtuple('OFClass', ['name', 'members', 'super_class', 'params'])):
+    def member_by_name(self, name):
+        return find(self.members, lambda m: hasattr(m, "name") and m.name == name)
 
 """
 Normal field
diff --git a/openflow_input/standard-1.2 b/openflow_input/standard-1.2
index f4d31d6..4ff23b7 100644
--- a/openflow_input/standard-1.2
+++ b/openflow_input/standard-1.2
@@ -598,7 +598,7 @@
     pad(4);
 };
 
-struct of_match_v3 {
+struct of_match_v3(align=8) {
     uint16_t type == 1;
     uint16_t length;
     list(of_oxm_t) oxm_list;
diff --git a/openflow_input/standard-1.3 b/openflow_input/standard-1.3
index b0aa242..ab94fd5 100644
--- a/openflow_input/standard-1.3
+++ b/openflow_input/standard-1.3
@@ -724,7 +724,7 @@
 };
 
 // FIXME Does this need to be v4?
-struct of_match_v3 {
+struct of_match_v3(align=8) {
     uint16_t type == 1;
     uint16_t length;
     list(of_oxm_t) oxm_list;