Fix bsn_vport subtype, add l2gre vport and test file.
diff --git a/c_gen/build_of_g.py b/c_gen/build_of_g.py
index 41d8ab2..4d37b36 100755
--- a/c_gen/build_of_g.py
+++ b/c_gen/build_of_g.py
@@ -158,6 +158,11 @@
             # but is variable length
             bytes = -1
             len_update = 4
+        elif base_type == "of_bsn_vport_header_t":
+            # This is a special case: it has non-zero min length
+            # but is variable length
+            bytes = -1
+            len_update = 4
         elif base_type in of_g.of_base_types:
             bytes = of_g.of_base_types[base_type]["bytes"]
         else:
@@ -332,6 +337,9 @@
                     # HACK the C backend does not yet support of_oxm_t
                     if m.oftype == 'of_oxm_t':
                         m_type = 'of_oxm_header_t'
+                    # HACK the C backend does not yet support of_bsn_vport_t
+                    elif m.oftype == 'of_bsn_vport_t':
+                        m_type = 'of_bsn_vport_header_t'
                     else:
                         enum = find(lambda e: e.name == m.oftype, protocol.enums)
                         if enum and "wire_type" in enum.params:
diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
index 4f5ee7f..3fa4f3a 100644
--- a/c_gen/c_code_gen.py
+++ b/c_gen/c_code_gen.py
@@ -1585,6 +1585,17 @@
     %(m_name)s->length = cur_len;
     of_object_wire_init(%(m_name)s, OF_OXM, 0);
 """ % dict(m_type=m_type[:-2], m_name=m_name))
+    elif m_type == "of_bsn_vport_header_t":
+        out.write("""
+    /* Initialize child */
+    %(m_type)s_init(%(m_name)s, obj->version, 0, 1);
+    /* Attach to parent */
+    %(m_name)s->parent = (of_object_t *)obj;
+    %(m_name)s->wbuf = obj->wbuf;
+    %(m_name)s->obj_offset = abs_offset;
+    %(m_name)s->length = cur_len;
+    of_object_wire_init(%(m_name)s, OF_BSN_VPORT, 0);
+""" % dict(m_type=m_type[:-2], m_name=m_name))
     else:
         out.write("""
     /* Initialize child */
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index 3eaaf82..be1b0da 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -100,6 +100,7 @@
         of_meter_features_t="features",
         of_match_t="match",
         of_oxm_header_t="oxm",
+        of_bsn_vport_header_t="bsn_vport",
         # BSN extensions
         of_bsn_vport_q_in_q_t="vport",
         of_bitmap_128_t="bitmap_128",
@@ -1363,6 +1364,19 @@
         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
+            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);
+    TEST_ASSERT(value != 0);
+    %(cls)s_%(m_name)s_set(
+        obj, %(var_name)s);
+    %(sub_cls)s_delete(%(var_name)s);
+""" % dict(cls=cls, sub_cls=sub_cls, m_name=m_name, m_type=m_type,
+           var_name=var_name_map(m_type),
+           v_name=loxi_utils.version_to_name(version)))
         else:
             sub_cls = m_type[:-2] # Trim _t
             out.write("""
@@ -1429,6 +1443,22 @@
     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
+            out.write("""
+    { /* Use get/delete to access on check */
+        %(m_type)s *%(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);
+        TEST_ASSERT(value != 0);
+        %(sub_cls)s_delete(%(m_name)s_ptr);
+    }
+""" % dict(cls=cls, sub_cls=sub_cls, m_name=m_name, m_type=m_type,
+           var_name=var_name_map(m_type),
+           v_name=loxi_utils.version_to_name(version)))
         else:
             sub_cls = m_type[:-2] # Trim _t
             out.write("""
diff --git a/c_gen/loxi_utils_legacy.py b/c_gen/loxi_utils_legacy.py
index 38feb44..220d043 100644
--- a/c_gen/loxi_utils_legacy.py
+++ b/c_gen/loxi_utils_legacy.py
@@ -120,6 +120,8 @@
         return True
     if cls.find("of_bsn_tlv") == 0:
         return True
+    if cls.find("of_bsn_vport") == 0:
+        return True
     return False
 
 def class_is_u16_len(cls):
diff --git a/c_gen/templates/loci_show.h b/c_gen/templates/loci_show.h
index b210570..b21665d 100644
--- a/c_gen/templates/loci_show.h
+++ b/c_gen/templates/loci_show.h
@@ -398,5 +398,13 @@
 #define LOCI_SHOW_u64_counter_id(writer, cookie, val) LOCI_SHOW_u64(writer, cookie, val)
 #define LOCI_SHOW_desc_str_description(writer, cookie, val) LOCI_SHOW_desc_str(writer, cookie, val)
 #define LOCI_SHOW_str64_name(writer, cookie, val) LOCI_SHOW_str64(writer, cookie, val)
+#define LOCI_SHOW_mac_local_mac(writer, cookie, val) LOCI_SHOW_mac(writer, cookie, val)
+#define LOCI_SHOW_mac_nh_mac(writer, cookie, val) LOCI_SHOW_mac(writer, cookie, val)
+#define LOCI_SHOW_ipv4_src_ip(writer, cookie, val) LOCI_SHOW_ipv4(writer, cookie, val)
+#define LOCI_SHOW_ipv4_dst_ip(writer, cookie, val) LOCI_SHOW_ipv4(writer, cookie, val)
+#define LOCI_SHOW_u8_dscp_mode(writer, cookie, val) LOCI_SHOW_u8(writer, cookie, val)
+#define LOCI_SHOW_u8_dscp(writer, cookie, val) LOCI_SHOW_u8(writer, cookie, val)
+#define LOCI_SHOW_u8_ttl(writer, cookie, val) LOCI_SHOW_u8(writer, cookie, val)
+#define LOCI_SHOW_u32_vpn(writer, cookie, val) LOCI_SHOW_u32(writer, cookie, val)
 
 #endif /* _LOCI_SHOW_H_ */
diff --git a/c_gen/type_maps.py b/c_gen/type_maps.py
index af43a15..2f23d61 100644
--- a/c_gen/type_maps.py
+++ b/c_gen/type_maps.py
@@ -92,18 +92,22 @@
     # version 1.0
     of_g.VERSION_1_0:dict(
         q_in_q      = 0,
+        l2gre       = 1,
         ),
     # version 1.1
     of_g.VERSION_1_1:dict(
         q_in_q      = 0,
+        l2gre       = 1,
         ),
     # version 1.2
     of_g.VERSION_1_2:dict(
         q_in_q      = 0,
+        l2gre       = 1,
         ),
     # version 1.3
     of_g.VERSION_1_3:dict(
         q_in_q      = 0,
+        l2gre       = 1,
         )
     }