Merge remote-tracking branch 'origin/master' into codegen-list
diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
index 6ff2010..191fcd3 100644
--- a/c_gen/c_code_gen.py
+++ b/c_gen/c_code_gen.py
@@ -1287,19 +1287,14 @@
     elif m_type == "of_match_t":
         out.write("""
     LOCI_ASSERT(cur_len + abs_offset <= WBUF_CURRENT_BYTES(wbuf));
-    match_octets.bytes = cur_len;
-    match_octets.data = OF_OBJECT_BUFFER_INDEX(obj, offset);
-    OF_TRY(of_match_deserialize(ver, %(m_name)s, &match_octets));
+    OF_TRY(of_match_deserialize(ver, %(m_name)s, obj, offset, cur_len));
 """ % dict(m_name=m_name))
     elif m_type == "of_oxm_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_attach(obj, %(m_name)s, offset, 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":
@@ -1307,10 +1302,7 @@
     /* 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_attach(obj, %(m_name)s, offset, cur_len);
     of_object_wire_init(%(m_name)s, OF_BSN_VPORT, 0);
 """ % dict(m_type=m_type[:-2], m_name=m_name))
     else:
@@ -1318,10 +1310,7 @@
     /* 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_attach(obj, %(m_name)s, offset, cur_len);
 """ % dict(m_type=m_type[:-2], m_name=m_name))
 
 
@@ -1347,13 +1336,16 @@
 
     elif m_type == "of_match_t":
         out.write("""
-    /* Match object */
-    OF_TRY(of_match_serialize(ver, %(m_name)s, &match_octets));
-    new_len = match_octets.bytes;
-    of_wire_buffer_replace_data(wbuf, abs_offset, cur_len,
-        match_octets.data, new_len);
-    /* Free match serialized octets */
-    FREE(match_octets.data);
+    {
+        /* Match object */
+        of_octets_t match_octets;
+        OF_TRY(of_match_serialize(ver, %(m_name)s, &match_octets));
+        new_len = match_octets.bytes;
+        of_wire_buffer_replace_data(wbuf, abs_offset, cur_len,
+            match_octets.data, new_len);
+        /* Free match serialized octets */
+        FREE(match_octets.data);
+    }
 """ % dict(m_name=m_name))
 
     else:  # Other object type
@@ -1473,12 +1465,6 @@
     int new_len, delta; /* For set, need new length and delta */
 """)
 
-    # For match, need octet string for set/get
-    if m_type == "of_match_t":
-        out.write("""\
-    of_octets_t match_octets; /* Serialized string for match */
-""")
-
     out.write("""
     LOCI_ASSERT(%(assert_str)s);
     ver = obj->version;
@@ -1785,9 +1771,6 @@
  * Initializes the new object with it's default fixed length associating
  * a new underlying wire buffer.
  *
- * Use new_from_message to bind an existing message to a message object,
- * or a _get function for non-message objects.
- *
  * \\ingroup %(cls)s
  */
 
@@ -1829,55 +1812,6 @@
 """ % dict(cls=cls))
 
 
-def gen_from_message_fn_body(cls, out):
-    """
-    Generate function body for from_message function
-    @param cls The class name for the function
-    @param out The file to which to write
-    """
-    out.write("""
-/**
- * Create a new %(cls)s object and bind it to an existing message
- *
- * @param msg The message to bind the new object to
- * @return Pointer to the newly create object or NULL on error
- *
- * \ingroup %(cls)s
- */
-
-%(cls)s_t *
-%(cls)s_new_from_message(of_message_t msg)
-{
-    %(cls)s_t *obj = NULL;
-    of_version_t version;
-    int length;
-
-    if (msg == NULL) return NULL;
-
-    version = of_message_version_get(msg);
-    if (!OF_VERSION_OKAY(version)) return NULL;
-
-    length = of_message_length_get(msg);
-
-    if ((obj = (%(cls)s_t *)of_object_new(-1)) == NULL) {
-        return NULL;
-    }
-
-    %(cls)s_init(obj, version, 0, 0);
-
-    if ((of_object_buffer_bind((of_object_t *)obj, OF_MESSAGE_TO_BUFFER(msg),
-                               length, OF_MESSAGE_FREE_FUNCTION)) < 0) {
-       FREE(obj);
-       return NULL;
-    }
-    obj->length = length;
-    obj->version = version;
-
-    return obj;
-}
-""" % dict(cls=cls))
-
-
 ################################################################
 # Now the top level generator functions
 ################################################################
@@ -1894,13 +1828,10 @@
  * New operator declarations
  *
  * _new: Create a new object for writing; includes init
- * _new_from_message: Create a new instance of the object and bind the
- *    message data to the object
  * _init: Initialize and optionally allocate buffer space for an
  *    automatic instance
  *
- * _new and _from_message require a delete operation to be called
- * on the object.
+ * _new and requires a delete operation to be called on the object.
  *
  ****************************************************************/
 """)
@@ -1910,10 +1841,6 @@
 extern %(cls)s_t *
     %(cls)s_new(of_version_t version);
 """ % dict(cls=cls))
-        if loxi_utils.class_is_message(cls):
-            out.write("""extern %(cls)s_t *
-    %(cls)s_new_from_message(of_message_t msg);
-""" % dict(cls=cls))
         out.write("""extern void %(cls)s_init(
     %(cls)s_t *obj, of_version_t version, int bytes, int clean_wire);
 """ % dict(cls=cls))
@@ -1966,8 +1893,6 @@
 
     gen_new_fn_body(cls, out)
     gen_init_fn_body(cls, out)
-    if loxi_utils.class_is_message(cls):
-        gen_from_message_fn_body(cls, out)
 
 """
 Document generation functions
diff --git a/c_gen/c_match.py b/c_gen/c_match.py
index bc05747..3afc99c 100644
--- a/c_gen/c_match.py
+++ b/c_gen/c_match.py
@@ -77,7 +77,7 @@
 extern int of_match_serialize(of_version_t version, of_match_t *match,
                               of_octets_t *octets);
 extern int of_match_deserialize(of_version_t version, of_match_t *match,
-                                of_octets_t *octets);
+                                of_object_t *parent, int offset, int length);
 extern int of_match_v1_to_match(of_match_v1_t *src, of_match_t *dst);
 extern int of_match_v2_to_match(of_match_v2_t *src, of_match_t *dst);
 extern int of_match_v3_to_match(of_match_v3_t *src, of_match_t *dst);
@@ -738,33 +738,18 @@
 
 int
 of_match_deserialize(of_version_t version, of_match_t *match,
-                     of_octets_t *octets)
+                     of_object_t *parent, int offset, int length)
 {
-    if (octets->bytes == 0) { /* No match specified means all wildcards */
-        MEMSET(match, 0, sizeof(*match));
-        match->version = version;
-
-        return OF_ERROR_NONE;
-    }
+    of_object_t obj;
 
     switch (version) {
 """)
     for version in of_g.of_version_range:
         out.write("""
     case %(ver_name)s:
-        { /* FIXME: check init bytes */
-            uint8_t *tmp;
-            of_match_v%(version)d_t wire_match;
-            of_match_v%(version)d_init(&wire_match,
-                   %(ver_name)s, -1, 1);
-            of_object_buffer_bind((of_object_t *)&wire_match,
-                octets->data, octets->bytes, NULL);
-            OF_TRY(of_match_v%(version)d_to_match(&wire_match, match));
-
-            /* Free the wire buffer control block without freeing
-             * octets->bytes. */
-            of_wire_buffer_steal(wire_match.wbuf, &tmp);
-        }
+        of_match_v%(version)d_init(&obj, %(ver_name)s, length, 1);
+        of_object_attach(parent, &obj, offset, length);
+        OF_TRY(of_match_v%(version)d_to_match(&obj, match));
         break;
 """ % dict(version=version, ver_name=of_g.of_version_wire2name[version]))
 
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index aff1ca6..71615e6 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -1027,6 +1027,9 @@
     of_match_t match2;
     int value = 1;
     of_octets_t octets;
+    of_object_storage_t storage;
+    memset(&storage, 0, sizeof(storage));
+    storage.obj.wbuf = &storage.wbuf;
 """)
     for version in of_g.of_version_range:
         out.write("""
@@ -1034,7 +1037,10 @@
     TEST_ASSERT((value = of_match_populate(&match1, %(v_name)s, value)) > 0);
     TEST_ASSERT(of_match_serialize(%(v_name)s, &match1, &octets) ==
         OF_ERROR_NONE);
-    TEST_ASSERT(of_match_deserialize(%(v_name)s, &match2, &octets) ==
+    storage.obj.wbuf->buf = octets.data;
+    storage.obj.wbuf->alloc_bytes = octets.bytes;
+    storage.obj.wbuf->current_bytes = octets.bytes;
+    TEST_ASSERT(of_match_deserialize(%(v_name)s, &match2, &storage.obj, 0, octets.bytes) ==
         OF_ERROR_NONE);
     TEST_ASSERT(memcmp(&match1, &match2, sizeof(match1)) == 0);
     FREE(octets.data);
@@ -1084,6 +1090,7 @@
     uint8_t *msg_buf;
     int value;
     of_object_id_t object_id;
+    int len;
 
     obj = %(cls)s_new(%(v_name)s);
     TEST_ASSERT(obj != NULL);
@@ -1099,11 +1106,13 @@
     value = %(cls)s_%(v_name)s_populate_scalars(obj, 1);
     TEST_ASSERT(value != 0);
 
+    len = obj->length;
+
     /* Grab the underlying buffer from the message */
     of_object_wire_buffer_steal((of_object_t *)obj, &msg_buf);
     TEST_ASSERT(msg_buf != NULL);
     %(cls)s_delete(obj);
-    obj = %(cls)s_new_from_message(OF_BUFFER_TO_MESSAGE(msg_buf));
+    obj = of_object_new_from_message(OF_BUFFER_TO_MESSAGE(msg_buf), len);
 
     TEST_ASSERT(obj != NULL);
 
diff --git a/c_gen/templates/loci_show.h b/c_gen/templates/loci_show.h
index 4179b13..aff632f 100644
--- a/c_gen/templates/loci_show.h
+++ b/c_gen/templates/loci_show.h
@@ -220,6 +220,7 @@
 #define LOCI_SHOW_u32_role(writer, cookie, val) LOCI_SHOW_x32(writer, cookie, val)
 #define LOCI_SHOW_u16_total_len(writer, cookie, val) LOCI_SHOW_u16(writer, cookie, val)
 #define LOCI_SHOW_port_no_port_no(writer, cookie, val) LOCI_SHOW_port_no(writer, cookie, val)
+#define LOCI_SHOW_port_no_loopback_port_no(writer, cookie, val) LOCI_SHOW_port_no(writer, cookie, val)
 #define LOCI_SHOW_mac_hw_addr(writer, cookie, val) LOCI_SHOW_mac(writer, cookie, val)
 #define LOCI_SHOW_u32_config(writer, cookie, val) LOCI_SHOW_x32(writer, cookie, val)
 #define LOCI_SHOW_u32_advertise(writer, cookie, val) LOCI_SHOW_x32(writer, cookie, val)
diff --git a/c_gen/templates/locitest/test_ext.c b/c_gen/templates/locitest/test_ext.c
index 7bd0998..8d28e87 100644
--- a/c_gen/templates/locitest/test_ext.c
+++ b/c_gen/templates/locitest/test_ext.c
@@ -46,5 +46,7 @@
     TEST_ASSERT(obj != NULL);
     TEST_ASSERT(obj->object_id == OF_ACTION_BSN_MIRROR);
 
+    of_object_delete(obj);
+
     return TEST_PASS;
 }
diff --git a/c_gen/templates/of_object.c b/c_gen/templates/of_object.c
index 39a6790..b0d3e14 100644
--- a/c_gen/templates/of_object.c
+++ b/c_gen/templates/of_object.c
@@ -254,7 +254,6 @@
  * @param offset The offset at which to attach the child RELATIVE 
  * TO THE PARENT in the buffer
  * @param bytes The amount of the buffer dedicated to the child; see below
- * @param inc_ref_count Should the ref count of the parent be incremented
  * 
  * This is used for 'get' accessors for composite types as well as
  * iterator functions for lists, both read (first/next) and write
@@ -276,14 +275,7 @@
 object_child_attach(of_object_t *parent, of_object_t *child, 
                        int offset, int bytes)
 {
-    of_wire_buffer_t *wbuf; /* Pointer to common wire buffer manager */
-
-    child->parent = parent;
-    wbuf = parent->wbuf;
-
-    /* Set up the child's wire buf to point to same as parent */
-    child->wbuf = wbuf;
-    child->obj_offset = parent->obj_offset + offset;
+    of_object_attach(parent, child, offset, bytes);
 
     /*
      * bytes determines if this is a read or write setup.
@@ -296,8 +288,7 @@
         /* Set up space for the child in the parent's buffer */
         tot_bytes = parent->obj_offset + offset + bytes;
 
-        of_wire_buffer_grow(wbuf, tot_bytes);
-        child->length = bytes;
+        of_wire_buffer_grow(parent->wbuf, tot_bytes);
     }
     /* if bytes == 0 don't do anything */
 }
diff --git a/c_gen/templates/of_object.h b/c_gen/templates/of_object.h
index d299537..0ca415b 100644
--- a/c_gen/templates/of_object.h
+++ b/c_gen/templates/of_object.h
@@ -132,4 +132,22 @@
     of_wire_buffer_t wbuf;
 };
 
+/**
+ * Connect a child to a parent at the wire buffer level
+ *
+ * @param parent The top level object to bind to
+ * @param child The sub-object connecting to the parent
+ * @param offset The offset at which to attach the child RELATIVE
+ * TO THE PARENT in the buffer
+ * @param bytes The amount of the buffer dedicated to the child
+ */
+static inline void
+of_object_attach(of_object_t *parent, of_object_t *child, int offset, int length)
+{
+    child->parent = parent;
+    child->wbuf = parent->wbuf;
+    child->obj_offset = parent->obj_offset + offset;
+    child->length = length;
+}
+
 #endif /* _OF_OBJECT_H_ */
diff --git a/c_gen/templates/of_wire_buf.h b/c_gen/templates/of_wire_buf.h
index dfec5c3..0922a69 100644
--- a/c_gen/templates/of_wire_buf.h
+++ b/c_gen/templates/of_wire_buf.h
@@ -119,12 +119,6 @@
 #define OF_OBJECT_TO_WBUF(obj) ((obj)->wbuf)
 
 
-
-/**
- * Minimum allocation size for wire buffer object
- */
-#define OF_WIRE_BUFFER_MIN_ALLOC_BYTES 128
-
 /**
  * Allocate a wire buffer object and the underlying data buffer.
  * The wire buffer is initally empty (current_bytes == 0).
@@ -142,10 +136,6 @@
     }
     MEMSET(wbuf, 0, sizeof(of_wire_buffer_t));
 
-    if (a_bytes < OF_WIRE_BUFFER_MIN_ALLOC_BYTES) {
-        a_bytes = OF_WIRE_BUFFER_MIN_ALLOC_BYTES;
-    }
-
     if ((wbuf->buf = (uint8_t *)MALLOC(a_bytes)) == NULL) {
         FREE(wbuf);
         return NULL;
diff --git a/java_gen/java_type.py b/java_gen/java_type.py
index 14878c3..8c06379 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -681,6 +681,7 @@
         'of_bucket' : { 'watch_group': of_group },
 
         'of_bsn_tlv_vlan_vid' : { 'value' : vlan_vid },
+        'of_bsn_table_set_buckets_size' : { 'table_id' : table_id },
         'of_bsn_gentable_entry_add' : { 'table_id' : gen_table_id },
 
         'of_features_reply' : { 'auxiliary_id' : of_aux_id},
diff --git a/java_gen/pre-written/pom.xml b/java_gen/pre-written/pom.xml
index fd595ce..338172f 100644
--- a/java_gen/pre-written/pom.xml
+++ b/java_gen/pre-written/pom.xml
@@ -10,7 +10,7 @@
 
     <groupId>org.projectfloodlight</groupId>
     <artifactId>openflowj</artifactId>
-    <version>0.3.6-SNAPSHOT</version>
+    <version>0.3.7-SNAPSHOT</version>
     <packaging>jar</packaging>
 
     <name>OpenFlowJ-Loxi</name>
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddress.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddress.java
index 1c5be86..5e4e818 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddress.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddress.java
@@ -1,7 +1,13 @@
 package org.projectfloodlight.openflow.types;
 
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+
 import javax.annotation.Nonnull;
 
+import com.google.common.base.Preconditions;
+
 public abstract class IPAddress<F extends IPAddress<F>> implements OFValueType<F> {
 
     public abstract IPVersion getIpVersion();
@@ -66,9 +72,7 @@
      */
     @Nonnull
     public static IPAddress<?> of(@Nonnull String ip) {
-        if (ip == null) {
-            throw new NullPointerException("String ip must not be null");
-        }
+        Preconditions.checkNotNull(ip, "ip must not be null");
         if (ip.indexOf('.') != -1)
             return IPv4Address.of(ip);
         else if (ip.indexOf(':') != -1)
@@ -77,4 +81,21 @@
             throw new IllegalArgumentException("IP Address not well formed: " + ip);
     }
 
+    /**
+     * Factory function for InetAddress values.
+     * @param address the InetAddress you wish to parse into an IPAddress object.
+     * @return the IPAddress object.
+     * @throws NullPointerException if address is null
+     */
+    @Nonnull
+    public static IPAddress<?> fromInetAddress(@Nonnull InetAddress address) {
+        Preconditions.checkNotNull(address, "address must not be null");
+        byte [] bytes = address.getAddress();
+        if(address instanceof Inet4Address)
+            return IPv4Address.of(bytes);
+        else if (address instanceof Inet6Address)
+            return IPv6Address.of(bytes);
+        else
+            return IPAddress.of(address.getHostAddress());
+    }
 }
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPAddressTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPAddressTest.java
index 25fc943..865df75 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPAddressTest.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPAddressTest.java
@@ -1,6 +1,9 @@
 package org.projectfloodlight.openflow.types;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.net.UnknownHostException;
 
 import org.junit.Test;
 
@@ -51,4 +54,14 @@
         }
     }
 
+    @Test
+    public void testFromInetAddressException() throws UnknownHostException {
+        try {
+            IPAddress.fromInetAddress(null);
+            fail("Should have thrown NullPointerException");
+        } catch (NullPointerException e) {
+            assertNotNull(e.getMessage());
+        }
+    }
+
 }
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java
index fb5cd23..18f524e 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java
@@ -10,6 +10,8 @@
 import static org.junit.Assert.fail;
 
 import org.hamcrest.Matchers;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
 import org.junit.Test;
 
 import com.google.common.hash.HashCode;
@@ -27,6 +29,22 @@
     }
 
     @Test
+    public void testReadBytes() {
+        ChannelBuffer empty = ChannelBuffers.wrappedBuffer(new byte[16]);
+        U128 uEmpty = U128.read16Bytes(empty);
+        assertThat(uEmpty.getMsb(), equalTo(0L));
+        assertThat(uEmpty.getLsb(), equalTo(0L));
+
+        ChannelBuffer value = ChannelBuffers.wrappedBuffer(
+                new byte[] { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte) 0x88,
+                        (byte) 0x99, (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd,
+                        (byte) 0xee, (byte) 0xff, 0x11 });
+        U128 uValue = U128.read16Bytes(value);
+        assertThat(uValue.getMsb(), equalTo(0x1122334455667788L));
+        assertThat(uValue.getLsb(), equalTo(0x99aabbccddeeff11L));
+    }
+
+    @Test
     public void testPutTo() {
         U128 h         = U128.of(0x1234_5678_90ab_cdefL,0xdeafbeefdeadbeefL);
         U128 hSame     = U128.of(0x1234_5678_90ab_cdefL,0xdeafbeefdeadbeefL);
diff --git a/openflow_input/bsn_vport b/openflow_input/bsn_vport
index 82d9d33..4f06462 100644
--- a/openflow_input/bsn_vport
+++ b/openflow_input/bsn_vport
@@ -48,6 +48,8 @@
     /* DSCP flags are mutually exclusive */
     OF_BSN_VPORT_L2GRE_DSCP_ASSIGN = 0x2,
     OF_BSN_VPORT_L2GRE_DSCP_COPY = 0x4,
+
+    OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID = 0x8,
 };
 
 // BSN Virtual port object header
@@ -79,16 +81,17 @@
     uint16_t type == 1;
     uint16_t length;
     enum ofp_bsn_vport_l2gre_flags flags;
-    of_port_no_t port_no;       /* OF port number of parent */
-    of_mac_addr_t local_mac;    /* Local MAC */
-    of_mac_addr_t nh_mac;       /* Next Hop MAC */
-    of_ipv4_t src_ip;           /* Source IP */
-    of_ipv4_t dst_ip;           /* Destination IP */
+    of_port_no_t port_no;           /* OF port number of parent */
+    of_port_no_t loopback_port_no;  /* OF port number of loopback */
+    of_mac_addr_t local_mac;        /* Local MAC */
+    of_mac_addr_t nh_mac;           /* Next Hop MAC */
+    of_ipv4_t src_ip;               /* Source IP */
+    of_ipv4_t dst_ip;               /* Destination IP */
     uint8_t dscp;
     uint8_t ttl;
     pad(2);
-    uint32_t vpn;               /* VPN ID (for GRE Key) */
-    of_port_name_t if_name;     /* Virtual Interface Name */
+    uint32_t vpn;                   /* VPN ID (for GRE Key) */
+    of_port_name_t if_name;         /* Virtual Interface Name */
 };
 
 
diff --git a/openflow_input/standard-1.3 b/openflow_input/standard-1.3
index 19940ac..64a465d 100644
--- a/openflow_input/standard-1.3
+++ b/openflow_input/standard-1.3
@@ -1378,7 +1378,7 @@
     uint16_t priority;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
-    uint16_t flags;
+    enum ofp_flow_mod_flags flags;
     pad(4);
     uint64_t cookie;
     uint64_t packet_count;
diff --git a/test_data/of13/bsn_virtual_port_create_request__l2gre.data b/test_data/of13/bsn_virtual_port_create_request__l2gre.data
index b5fd5fa..9d90293 100644
--- a/test_data/of13/bsn_virtual_port_create_request__l2gre.data
+++ b/test_data/of13/bsn_virtual_port_create_request__l2gre.data
@@ -1,13 +1,14 @@
 -- binary
 04 04               # version, type
-00 48               # len
+00 4c               # len
 01 02 03 04         # xid
 00 5c 16 c7         # experimenter
 00 00 00 0f         # subtype
 00 01               # vport type
-00 38               # vport len
+00 3c               # vport len
 00 00 00 03         # vport flags
-00 00 00 01         # vport port no
+00 00 00 01         # parent port no
+00 00 00 02         # loopback port no
 0a 0b 0c 0d 0e 0f   # local mac
 01 02 03 04 05 06   # next hop mac
 c0 00 00 02         # src ip
@@ -20,6 +21,7 @@
 xid=0x01020304, vport=ofp.bsn_vport_l2gre(
 flags=ofp.OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID | ofp.OF_BSN_VPORT_L2GRE_DSCP_ASSIGN,
 port_no=1,
+loopback_port_no=2,
 local_mac=[0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f],
 nh_mac=[0x01, 0x02, 0x03, 0x04, 0x05, 0x06],
 src_ip=0xc0000002,
@@ -42,6 +44,7 @@
             OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID |
             OF_BSN_VPORT_L2GRE_DSCP_ASSIGN);
         of_bsn_vport_l2gre_port_no_set(vport, 1);
+        of_bsn_vport_l2gre_loopback_port_no_set(vport, 2);
         of_bsn_vport_l2gre_local_mac_set(vport, local_mac);
         of_bsn_vport_l2gre_nh_mac_set(vport, nh_mac);
         of_bsn_vport_l2gre_src_ip_set(vport, 0xc0000002);
@@ -65,6 +68,7 @@
                 )
             )
             .setPortNo(OFPort.of(1))
+            .setLoopbackPortNo(OFPort.of(2))
             .setLocalMac(MacAddress.of("0a:0b:0c:0d:0e:0f"))
             .setNhMac(MacAddress.of("01:02:03:04:05:06"))
             .setSrcIp(IPv4Address.of("192.0.0.2"))