Merge into master from pull request #252:
Fix bsn_vport subtype and add l2gre vport (https://github.com/floodlight/loxigen/pull/252)
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index 8537f66..57d141d 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -1306,6 +1306,8 @@
     for m_type in member_types:
         if loxi_utils.type_is_scalar(m_type) or m_type in ["of_match_t", "of_octets_t"]:
             out.write("    %s %s;\n" % (m_type, var_name_map(m_type)))
+        elif m_type == "of_bsn_vport_header_t":
+            out.write("    of_bsn_vport_q_in_q_t *%s;\n" % var_name_map(m_type))
         else:
             out.write("    %s *%s;\n" % (m_type, var_name_map(m_type)))
     out.write("""
@@ -1316,6 +1318,8 @@
         m_name = member["name"]
         if loxi_utils.skip_member_name(m_name):
             continue
+        if m_type == "of_bsn_vport_header_t":
+            continue
         if loxi_utils.type_is_scalar(m_type) or m_type in ["of_match_t", "of_octets_t"]:
             out.write("""\
     %(cls)s_%(m_name)s_get(obj, &%(var_name)s);
@@ -1364,12 +1368,13 @@
         FREE(octets.data);
     }
 """ % dict(var_name=var_name_map(m_type), cls=cls, m_name=m_name))
-        elif m_type == "of_bsn_vport_t": # FIXME: tests only q_in_q
+        elif m_type == "of_bsn_vport_header_t": # test q_in_q
+            sub_cls = "of_bsn_vport_q_in_q"
             out.write("""\
     %(var_name)s = %(sub_cls)s_new(%(v_name)s);
     TEST_ASSERT(%(var_name)s != NULL);
-    value = %(sub_cls)s_q_in_q_%(v_name)s_populate(
-        &%(var_name)s->q_in_q, value);
+    value = %(sub_cls)s_%(v_name)s_populate(
+        %(var_name)s, value);
     TEST_ASSERT(value != 0);
     %(cls)s_%(m_name)s_set(
         obj, %(var_name)s);
@@ -1443,16 +1448,16 @@
     value = of_octets_check(&%(var_name)s, value);
 """ % dict(cls=cls, var_name=var_name_map(m_type), m_name=m_name,
            v_name=loxi_utils.version_to_name(version)))
-        elif m_type == "of_bsn_vport_t": # FIXME: tests only q_in_q
-            sub_cls = m_type[:-2] # Trim _t
+        elif m_type == "of_bsn_vport_header_t": # tests only q_in_q
+            sub_cls = "of_bsn_vport_q_in_q"
             out.write("""
     { /* Use get/delete to access on check */
-        %(m_type)s *%(m_name)s_ptr;
+        %(sub_cls)s_t *%(m_name)s_ptr;
 
         %(m_name)s_ptr = %(cls)s_%(m_name)s_get(obj);
         TEST_ASSERT(%(m_name)s_ptr != NULL);
-        value = %(sub_cls)s_q_in_q_%(v_name)s_check(
-            &%(m_name)s_ptr->q_in_q, value);
+        value = %(sub_cls)s_%(v_name)s_check(
+            %(m_name)s_ptr, value);
         TEST_ASSERT(value != 0);
         %(sub_cls)s_delete(%(m_name)s_ptr);
     }
@@ -1728,6 +1733,11 @@
         if loxi_utils.type_is_scalar(m_type) or m_type in ["of_match_t", "of_octets_t"]:
             # Declare instance of these
             out.write("    %s %s;\n" % (m_type, var_name_map(m_type)))
+        elif m_type == "of_bsn_vport_header_t": # test q_in_q
+            out.write("""
+    of_bsn_vport_q_in_q_t src_%(v_name)s;
+    of_bsn_vport_q_in_q_t *dst_%(v_name)s;
+""" % dict(v_name=var_name_map(m_type)))
         else:
             out.write("""
     %(m_type)s src_%(v_name)s;
@@ -1755,6 +1765,20 @@
     %(cls)s_%(m_name)s_get(src, &%(v_name)s);
     %(cls)s_%(m_name)s_set(dst, &%(v_name)s);
 """ % dict(cls=cls, m_name=m_name, v_name=var_name_map(m_type)))
+        elif m_type == "of_bsn_vport_header_t": # test q_in_q
+            sub_cls = "of_bsn_vport_q_in_q"
+            out.write("""
+    %(cls)s_%(m_name)s_bind(
+        src, &src_%(v_name)s);
+    dst_%(v_name)s = %(sub_cls)s_%(ver_name)s_dup(&src_%(v_name)s);
+    if (dst_%(v_name)s == NULL) {
+        %(cls)s_delete(dst);
+        return NULL;
+    }
+    %(cls)s_%(m_name)s_set(dst, dst_%(v_name)s);
+    %(sub_cls)s_delete(dst_%(v_name)s);
+""" % dict(sub_cls=sub_cls, cls=cls, m_name=m_name,
+           v_name=var_name_map(m_type), ver_name=ver_name))
         else:
             sub_cls = m_type[:-2] # Trim _t
             out.write("""
@@ -1923,7 +1947,19 @@
                 continue
             if cls in type_maps.inheritance_map:
                 continue
-            out.write("""
+            if cls == "of_bsn_virtual_port_create_request": # test q_in_q
+                out.write("""
+    obj = (of_object_t *)%(cls)s_new(%(version)s);
+    {
+        of_object_t *vport = of_bsn_vport_q_in_q_new(%(version)s);
+        %(cls)s_vport_set(obj, vport);
+        of_object_delete(vport);
+    }
+    of_object_dump((loci_writer_f)fprintf, out, obj);
+    of_object_delete(obj);
+""" % dict(cls=cls, version=of_g.of_version_wire2name[version]))
+            else:
+                out.write("""
     obj = (of_object_t *)%(cls)s_new(%(version)s);
     of_object_dump((loci_writer_f)fprintf, out, obj);
     of_object_delete(obj);
diff --git a/c_gen/codegen.py b/c_gen/codegen.py
index 89a0a81..9af9223 100644
--- a/c_gen/codegen.py
+++ b/c_gen/codegen.py
@@ -206,6 +206,10 @@
                 wire_length_set = 'of_tlv16_wire_length_set'
                 wire_length_get = 'of_tlv16_wire_length_get'
                 wire_type_get = 'of_action_wire_object_id_get'
+            elif uclass.is_instanceof('of_bsn_vport'):
+                wire_length_set = 'of_tlv16_wire_length_set'
+                wire_length_get = 'of_tlv16_wire_length_get'
+                wire_type_get = 'of_bsn_vport_wire_object_id_get'
             elif uclass.is_action_id:
                 wire_length_set = 'of_tlv16_wire_length_set'
                 wire_length_get = 'of_tlv16_wire_length_get'
@@ -280,6 +284,12 @@
                 wire_type_get='of_action_id_wire_object_id_get',
                 wire_type_set='NULL'),
             ClassMetadata(
+                name="of_bsn_vport_header",
+                wire_length_set='of_tlv16_wire_length_set',
+                wire_length_get='of_tlv16_wire_length_get',
+                wire_type_get='of_bsn_vport_wire_object_id_get',
+                wire_type_set='NULL'),
+            ClassMetadata(
                 name="of_instruction_header",
                 wire_length_set='of_tlv16_wire_length_set',
                 wire_length_get='of_tlv16_wire_length_get',