Merge remote-tracking branch 'upstream/master'
diff --git a/Makefile b/Makefile
index 5f3d8e5..518ac6e 100644
--- a/Makefile
+++ b/Makefile
@@ -41,6 +41,7 @@
                            \) -a -name '*.py')
 LOXI_TEMPLATE_FILES=$(shell find */templates -type f -a \
                                  \! \( -name '*.cache' -o -name '.*' \))
+JAVA_PRE_WRITTEN_FILES=$(shell find java_gen/pre-written -type f)
 INPUT_FILES = $(wildcard openflow_input/*)
 TEST_DATA = $(shell find test_data -name '*.data')
 OPENFLOWJ_OUTPUT_DIR = ${LOXI_OUTPUT_DIR}/openflowj
@@ -75,7 +76,7 @@
 		rsync --checksum --delete -rv ${LOXI_OUTPUT_DIR}/openflowj/gen-src/ ${OPENFLOWJ_ECLIPSE_WORKSPACE}/gen-src; \
 	fi
 
-.loxi_ts.java: ${LOXI_PY_FILES} ${LOXI_TEMPLATE_FILES} ${INPUT_FILES} ${TEST_DATA}
+.loxi_ts.java: ${LOXI_PY_FILES} ${LOXI_TEMPLATE_FILES} ${INPUT_FILES} ${TEST_DATA} ${JAVA_PRE_WRITTEN_FILES}
 	./loxigen.py --install-dir=${LOXI_OUTPUT_DIR} --lang=java
 	touch $@
 
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index 05ff8e2..0784fd4 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -124,8 +124,7 @@
 string_types = [ "of_port_name_t", "of_table_name_t",
                 "of_desc_str_t", "of_serial_num_t", "of_mac_addr_t",
                 "of_ipv6_t", "of_bitmap_128_t", "of_checksum_128_t",
-                "of_str64_t","of_app_code_t"]
-                "of_str64_t", "of_bitmap_512_t"]
+                "of_str64_t", "of_app_code_t", "of_bitmap_512_t"]
 
 scalar_types = integer_types[:]
 scalar_types.extend(string_types)
diff --git a/c_gen/templates/of_object.c b/c_gen/templates/of_object.c
index 574db27..3836728 100644
--- a/c_gen/templates/of_object.c
+++ b/c_gen/templates/of_object.c
@@ -601,87 +601,14 @@
 }
 
 /*
- * Set member:
- *    get_wbuf_extent
- *    find offset of start of member
- *    if offset is at wbuf_extent (append new data)
- *        copy data at extent
- *        update parent length
- *    else
- *        find length of current entry
- *        move from end of current to extent to create (or remove) space
- *        copy data to offset
- *        update my length -- NEED LOCAL INFO TO DO THIS for some cases
- */
-
-/* Also need: get offset of member for all combinations */
-/* Also need: get length of member for all combinations */
-#if 0
-/**
- * Append the wire buffer data from src to the end of dst's wire buffer
- */
-int
-of_object_append_buffer(of_object_t *dst, of_object_t *src)
-{
-    of_wire_buffer_t *s_wbuf, *d_wbuf;
-    int orig_len, dst_offset, src_offset;
-
-    d_wbuf = OF_OBJECT_TO_WBUF(dst);
-    s_wbuf = OF_OBJECT_TO_WBUF(src);
-    dst_offset = dst->obj_offset + dst_length;
-    src_offset = src->obj_offset;
-    OF_WIRE_BUFFER_INIT_CHECK(d_wbuf, dst_offset + src->length);
-    MEMCPY(OF_WBUF_BUFFER_POINTER(d_wbuf, dst_offset),
-           OF_WBUF_BUFFER_POINTER(s_wbuf, 0), src->length);
-
-    orig_len = dst->length;
-    dst->length += src->length;
-
-    return OF_ERROR_NONE;
-}
-
-/**
- * Set the length of the actions object in a packet_in object
- */
-
-int
-of_packet_out_actions_length_set(of_packet_t *obj, int len)
-{
-    if (obj == NULL || obj->object_id != OF_PACKET_IN ||
-        obj->wbuf == NULL) {
-        return OF_ERROR_PARAM;
-    }
-
-    obj->actions_len_set(obj, len);
-}
-
-int
-_packet_out_data_offset_get(of_packet_t *obj)
-{
-    if (obj == NULL || obj->object_id != OF_PACKET_IN ||
-        obj->wbuf == NULL) {
-        return -1;
-    }
-
-    return OF_PACKET_OUT_FIXED_LENGTH + _packet_out_actions_length_get(obj);
-}
-
-
-/**
- * Simple length derivation function
+ * Truncate an object to its initial length.
  *
- * Most variable length fields are alone at the end of a structure.
- * Their length is a simple calculation, just the total length of
- * the parent minus the length of the non-variable part of the 
- * parent's class type.
- *
- * @param parent The parent object
- * @param length (out) Where to store the length of the final 
- * variable length member
+ * This allows the caller to reuse a single allocated object even if
+ * it has been appended to.
  */
-int
-of_object_simple_length_derive(of_object_t *obj, int *length)
+void
+of_object_truncate(of_object_t *obj)
 {
-    
+    of_object_init_map[obj->object_id](obj, obj->version, -1, 0);
+    obj->wbuf->current_bytes = obj->length;
 }
-#endif
diff --git a/c_gen/templates/of_object.h b/c_gen/templates/of_object.h
index 0ca415b..804e7ec 100644
--- a/c_gen/templates/of_object.h
+++ b/c_gen/templates/of_object.h
@@ -100,6 +100,8 @@
 
 void of_object_parent_length_update(of_object_t *obj, int delta);
 
+void of_object_truncate(of_object_t *obj);
+
 struct of_object_s {
     /** A pointer to the underlying buffer's management structure. */
     of_wire_buffer_t *wbuf;
diff --git a/java_gen/java_type.py b/java_gen/java_type.py
index 900aa6d..00debb5 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -675,6 +675,9 @@
         'of_oxm_bsn_egr_port_group_id' : { 'value' : class_id },
         'of_oxm_bsn_egr_port_group_id_masked' : { 'value' : class_id, 'value_mask' : class_id },
 
+        'of_oxm_bsn_ingress_port_group_id' : { 'value' : class_id },
+        'of_oxm_bsn_ingress_port_group_id_masked' : { 'value' : class_id, 'value_mask' : class_id },
+
         'of_oxm_bsn_udf0' : { 'value' : udf },
         'of_oxm_bsn_udf0_masked' : { 'value' : udf, 'value_mask' : udf },
 
@@ -708,6 +711,15 @@
         'of_oxm_bsn_l2_cache_hit' : { 'value' : boolean_value },
         'of_oxm_bsn_l2_cache_hit_masked' : { 'value' : boolean_value, 'value_mask' : boolean_value },
 
+        'of_oxm_bsn_vxlan_network_id' : { 'value' : u32obj },
+        'of_oxm_bsn_vxlan_network_id_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
+
+        'of_oxm_bsn_inner_eth_dst' : { 'value' : mac_addr },
+        'of_oxm_bsn_inner_eth_dst_masked' : { 'value' : mac_addr, 'value_mask' : mac_addr },
+
+        'of_oxm_bsn_inner_eth_src' : { 'value' : mac_addr },
+        'of_oxm_bsn_inner_eth_src_masked' : { 'value' : mac_addr, 'value_mask' : mac_addr },
+
         'of_table_stats_entry': { 'wildcards': table_stats_wildcards },
         'of_match_v1': { 'vlan_vid' : vlan_vid_match, 'vlan_pcp': vlan_pcp,
                 'eth_type': eth_type, 'ip_dscp': ip_dscp, 'ip_proto': ip_proto,
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/annotations/Immutable.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/annotations/Immutable.java
index 5de2171..6b0ba00 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/annotations/Immutable.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/annotations/Immutable.java
@@ -6,7 +6,7 @@
  * construction. Such a class can be freely shared between threads and does not
  * require defensive copying (don't call clone).
  *
- * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ * @author Andreas Wundsam {@literal <}andreas.wundsam@bigswitch.com{@literal >}
  */
 public @interface Immutable {
 
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/Match.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/Match.java
index 0efdcbb..67513b9 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/Match.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/Match.java
@@ -114,7 +114,7 @@
 
     /**
      * True if and only if this field is currently partially specified in the match, i.e, the
-     * match will only select packets that match (p.value & getMask(field)) == getValue(field),
+     * match will only select packets that match (p.value &amp; getMask(field)) == getValue(field),
      * and getMask(field) != 0.
      *
      * @param field Match field.
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
index e2f172b..3ea9215 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
@@ -228,6 +228,9 @@
     public final static MatchField<ClassId> BSN_EGR_PORT_GROUP_ID =
             new MatchField<ClassId>("bsn_egr_port_group_id", MatchFields.BSN_EGR_PORT_GROUP_ID);
 
+    public final static MatchField<ClassId> BSN_INGRESS_PORT_GROUP_ID =
+            new MatchField<ClassId>("bsn_ingress_port_group_id", MatchFields.BSN_INGRESS_PORT_GROUP_ID);
+
     public final static MatchField<UDF> BSN_UDF0 =
             new MatchField<UDF>("bsn_udf", MatchFields.BSN_UDF0);
 
@@ -277,6 +280,15 @@
     public final static MatchField<OFBooleanValue> BSN_L2_CACHE_HIT =
             new MatchField<OFBooleanValue>("bsn_l2_cache_hit", MatchFields.BSN_L2_CACHE_HIT);
 
+    public final static MatchField<U32> BSN_VXLAN_NETWORK_ID =
+            new MatchField<U32>("bsn_vxlan_network_id", MatchFields.BSN_VXLAN_NETWORK_ID);
+
+    public final static MatchField<MacAddress> BSN_INNER_ETH_DST =
+            new MatchField<MacAddress>("bsn_inner_eth_dst", MatchFields.BSN_INNER_ETH_DST);
+
+    public final static MatchField<MacAddress> BSN_INNER_ETH_SRC =
+            new MatchField<MacAddress>("bsn_inner_eth_src", MatchFields.BSN_INNER_ETH_SRC);
+
     public String getName() {
         return name;
     }
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
index 12e2b20..cd5ba32 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
@@ -64,6 +64,10 @@
     BSN_TCP_FLAGS,
     BSN_VLAN_XLATE_PORT_GROUP_ID,
     BSN_L2_CACHE_HIT,
+    BSN_INGRESS_PORT_GROUP_ID,
+    BSN_VXLAN_NETWORK_ID,
+    BSN_INNER_ETH_DST,
+    BSN_INNER_ETH_SRC,
     OCH_SIGTYPE,
     OCH_SIGTYPE_BASIC,
     OCH_SIGID,
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/DatapathId.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/DatapathId.java
index 79fa14f..fe52fc3 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/DatapathId.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/DatapathId.java
@@ -11,7 +11,7 @@
  * Abstraction of a datapath ID that can be set and/or accessed as either a
  * long value or a colon-separated string. Immutable
  *
- * @author Rob Vaterlaus <rob.vaterlaus@bigswitch.com>
+ * @author Rob Vaterlaus {@literal <}rob.vaterlaus@bigswitch.com{@literal >}
  */
 @Immutable
 public class DatapathId implements PrimitiveSinkable, Comparable<DatapathId> {
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/EthType.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/EthType.java
index c5f4f86..1d9c8d6 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/EthType.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/EthType.java
@@ -218,7 +218,7 @@
 
     @Override
     public String toString() {
-        return Integer.toHexString(rawValue);
+        return "0x" + Integer.toHexString(rawValue);
     }
 
     public void write2Bytes(ChannelBuffer c) {
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/HashValue.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/HashValue.java
index 3030e3e..ee736d7 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/HashValue.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/HashValue.java
@@ -5,7 +5,7 @@
 /** a hash value that supports bit-wise combinations, mainly to calculate hash values for
  *  reconciliation operations.
  *
- * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ * @author Andreas Wundsam {@literal <}andreas.wundsam@bigswitch.com{@literal >}
  *
  * @param <H> - this type, for return type safety.
  */
@@ -53,7 +53,7 @@
      *  operations on a hashv value without the associated cost of object
      *  reallocation.
      *
-     * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+     * @author Andreas Wundsam {@literal <}andreas.wundsam@bigswitch.com{@literal >}
      *
      * @param <H> - the hashvalue
      */
@@ -99,4 +99,4 @@
         /** @return the hash value */
         public H build();
     }
-}
\ No newline at end of file
+}
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 cee9ad1..ad21e06 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
@@ -40,23 +40,30 @@
      */
     public abstract boolean isBroadcast();
 
+
     /**
-     * Perform a low level AND operation on the bits of two IPAddress<?> objects
-     * @param   other IPAddress<?>
-     * @return  new IPAddress<?> object after the AND oper
+     * Checks if the IPAddress is the multicast address
+     * @return boolean true or false
+     */
+    public abstract boolean isMulticast();
+
+    /**
+     * Perform a low level AND operation on the bits of two IPAddress objects
+     * @param   other IPAddress
+     * @return  new IPAddress object after the AND oper
      */
     public abstract F and(F other);
 
     /**
-     * Perform a low level OR operation on the bits of two IPAddress<?> objects
-     * @param   other IPAddress<?>
-     * @return  new IPAddress<?> object after the AND oper
+     * Perform a low level OR operation on the bits of two IPAddress objects
+     * @param   other IPAddress
+     * @return  new IPAddress object after the AND oper
      */
     public abstract F or(F other);
 
     /**
      * Returns a new IPAddress object with the bits inverted
-     * @return  IPAddress<?>
+     * @return  IPAddress
      */
     public abstract F not();
 
@@ -79,13 +86,14 @@
      * @param cidrMaskLength  the prefix length of the CIDR subnet mask
      *                        (i.e. the number of leading one-bits),
      *                        where <code>
-     *                        0 <= cidrMaskLength <= (F.getLength() * 8)
+     *                        0 {@literal <=} cidrMaskLength {@literal <=} (F.getLength() * 8)
      *                        </code>
      * @return                an {@code IPAddressWithMask<F>} object that
      *                        represents this IP address masked by the CIDR
      *                        subnet mask of the given prefix length
      * @throws IllegalArgumentException  if the given prefix length was invalid
-     * @see #ofCidrMaskLength(int)
+     * @see org.projectfloodlight.openflow.types.IPv4Address#ofCidrMaskLength(int)
+     * @see org.projectfloodlight.openflow.types.IPv6Address#ofCidrMaskLength(int)
      */
     @Nonnull
     public abstract IPAddressWithMask<F> withMaskOfLength(
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java
index eb37a20..53e8071 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java
@@ -19,7 +19,7 @@
 /**
  * Wrapper around an IPv4Address address
  *
- * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ * @author Andreas Wundsam {@literal <}andreas.wundsam@bigswitch.com{@literal >}
  */
 public class IPv4Address extends IPAddress<IPv4Address> implements Writeable {
     static final int LENGTH = 4;
@@ -90,6 +90,14 @@
         return this.equals(NO_MASK);
     }
 
+    /**
+     * IPv4 multicast addresses are defined by the leading address bits of 1110 
+     */
+    @Override
+    public boolean isMulticast() {
+        return ((rawValue >>> 24) & 0xF0) == 0xE0;
+    }
+    
     @Override
     public IPv4Address and(IPv4Address other) {
         Preconditions.checkNotNull(other, "other must not be null");
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4AddressWithMask.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4AddressWithMask.java
index b6dc1b9..3bd7a5c 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4AddressWithMask.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4AddressWithMask.java
@@ -31,7 +31,7 @@
      *                  the given raw IP address masked by the given raw IP
      *                  address mask
      * @deprecated      replaced by {@link IPv4Address#of(int)} and
-     *                  {@link IPv4Address#withMask(IPv4Address), e.g. <code>
+     *                  {@link IPv4Address#withMask(IPv4Address)}, e.g. <code>
      *                  IPv4Address.of(int).withMask(IPv4Address.of(int))
      *                  </code>
      */
@@ -68,7 +68,7 @@
      * the given string in CIDR notation or other acceptable notations.
      * <p>
      * The following notations are accepted.
-     * <table><tr>
+     * <table summary=""><tr>
      * <th>Notation</th><th>Example</th><th>Notes</th>
      * </tr><tr>
      * <td>IPv4 address only</td><td>{@code 1.2.3.4}</td><td>The subnet mask of
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java
index 9d6fa4d..fee04ac 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java
@@ -11,7 +11,7 @@
 
 import com.google.common.base.Preconditions;
 import com.google.common.hash.PrimitiveSink;
-import com.google.common.primitives.Longs;
+import com.google.common.primitives.UnsignedLongs;
 
 import org.projectfloodlight.openflow.protocol.Writeable;
 import org.projectfloodlight.openflow.protocol.OFMessageReader;
@@ -21,7 +21,7 @@
  * IPv6 address object. Instance controlled, immutable. Internal representation:
  * two 64 bit longs (not that you'd have to know).
  *
- * @author Andreas Wundsam <andreas.wundsam@teleteach.de>
+ * @author Andreas Wundsam {@literal <}andreas.wundsam@teleteach.de{@literal >}
  */
 public class IPv6Address extends IPAddress<IPv6Address> implements Writeable {
     static final int LENGTH = 16;
@@ -115,6 +115,14 @@
         return this.equals(NO_MASK);
     }
 
+    /**
+     * IPv6 multicast addresses are defined by the prefix ff00::/8 
+     */
+    @Override
+    public boolean isMulticast() {
+        return (raw1 >>> 56) == 0xFFL;
+    }
+    
     @Override
     public IPv6Address and(IPv6Address other) {
         Preconditions.checkNotNull(other, "other must not be null");
@@ -166,13 +174,13 @@
                 (address[0] & 0xFFL) << 56 | (address[1] & 0xFFL) << 48
                         | (address[2] & 0xFFL) << 40 | (address[3] & 0xFFL) << 32
                         | (address[4] & 0xFFL) << 24 | (address[5] & 0xFFL) << 16
-                        | (address[6] & 0xFFL) << 8 | (address[7]);
+                        | (address[6] & 0xFFL) << 8 | (address[7] & 0xFFL);
 
         long raw2 =
                 (address[8] & 0xFFL) << 56 | (address[9] & 0xFFL) << 48
                         | (address[10] & 0xFFL) << 40 | (address[11] & 0xFFL) << 32
                         | (address[12] & 0xFFL) << 24 | (address[13] & 0xFFL) << 16
-                        | (address[14] & 0xFFL) << 8 | (address[15]);
+                        | (address[14] & 0xFFL) << 8 | (address[15] & 0xFFL);
 
         return IPv6Address.of(raw1, raw2);
     }
@@ -547,11 +555,11 @@
 
     @Override
     public int compareTo(IPv6Address o) {
-        int res = Longs.compare(raw1, o.raw1);
+        int res = UnsignedLongs.compare(raw1, o.raw1);
         if(res != 0)
             return res;
         else
-            return Longs.compare(raw2, o.raw2);
+            return UnsignedLongs.compare(raw2, o.raw2);
     }
 
     @Override
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6FlowLabel.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6FlowLabel.java
index de49b51..cfefd39 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6FlowLabel.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6FlowLabel.java
@@ -53,7 +53,7 @@
 
     @Override
     public String toString() {
-        return Integer.toHexString(label);
+        return "0x" + Integer.toHexString(label);
     }
 
     public void write4Bytes(ChannelBuffer c) {
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IpDscp.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IpDscp.java
index 27596b7..f19e051 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IpDscp.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IpDscp.java
@@ -227,7 +227,7 @@
 
     @Override
     public String toString() {
-        return Integer.toHexString(dscp);
+        return "0x" + Integer.toHexString(dscp);
     }
 
     public void writeByte(ChannelBuffer c) {
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IpProtocol.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IpProtocol.java
index 69f497e..8443a31 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IpProtocol.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IpProtocol.java
@@ -612,7 +612,7 @@
 
     @Override
     public String toString() {
-        return Integer.toHexString(proto);
+        return "0x" + Integer.toHexString(proto);
     }
 
     public void writeByte(ChannelBuffer c) {
@@ -662,4 +662,4 @@
         sink.putShort(proto);
     }
 
-}
\ No newline at end of file
+}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/MacAddress.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/MacAddress.java
index d7f044e..89debf0 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/MacAddress.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/MacAddress.java
@@ -14,7 +14,7 @@
 /**
  * Wrapper around a 6 byte mac address.
  *
- * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ * @author Andreas Wundsam {@literal <}andreas.wundsam@bigswitch.com{@literal >}
  */
 
 public class MacAddress implements OFValueType<MacAddress> {
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBitMask512.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBitMask512.java
index 3fe9b88..e3686a4 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBitMask512.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBitMask512.java
@@ -103,19 +103,19 @@
         } else if (bit < 128) {
             word = raw7;
             bit -= 64;
-        } else if (bit < 128) {
+        } else if (bit < 192) {
             word = raw6;
             bit -= 128;
-        } else if (bit < 128) {
+        } else if (bit < 256) {
             word = raw5;
             bit -= 192;
-        } else if (bit < 128) {
+        } else if (bit < 320) {
             word = raw4;
             bit -= 256;
-        } else if (bit < 128) {
+        } else if (bit < 384) {
             word = raw3;
             bit -= 320;
-        } else if (bit < 128) {
+        } else if (bit < 448) {
             word = raw2;
             bit -= 384;
         } else {
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBufferId.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBufferId.java
index 7f76b4d..78261dc 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBufferId.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBufferId.java
@@ -8,7 +8,7 @@
 /**
  * Abstraction of a buffer id in OpenFlow. Immutable.
  *
- * @author Rob Vaterlaus <rob.vaterlaus@bigswitch.com>
+ * @author Rob Vaterlaus {@literal <}rob.vaterlaus@bigswitch.com{@literal >}
  */
 @Immutable
 public class OFBufferId implements Comparable<OFBufferId>, PrimitiveSinkable {
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFErrorCauseData.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFErrorCauseData.java
index 824b809..1e71b3c 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFErrorCauseData.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFErrorCauseData.java
@@ -24,7 +24,7 @@
  *  This attempts to parse the offending message on demand, and if successful
  *  will present the parsed message.
  *
- * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ * @author Andreas Wundsam {@literal <}andreas.wundsam@bigswitch.com{@literal >}
  */
 public class OFErrorCauseData implements Writeable, PrimitiveSinkable {
     private static final Logger logger =
@@ -124,4 +124,4 @@
        return true;
    }
 
-}
\ No newline at end of file
+}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFGroup.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFGroup.java
index b05d5fa..9c571ea 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFGroup.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFGroup.java
@@ -11,7 +11,7 @@
  * Abstraction of an logical / OpenFlow group (ofp_group) in OpenFlow.
  * Immutable.
  *
- * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ * @author Andreas Wundsam {@literal <}andreas.wundsam@bigswitch.com{@literal >}
  */
 @Immutable
 public class OFGroup implements OFValueType<OFGroup> {
@@ -38,7 +38,7 @@
     public final static OFGroup ANY = new NamedGroup(ANY_VAL, "any");
 
     /** group 0 in case we need it */
-    public static final OFGroup ZERO = OFGroup.of(ZERO_VAL);
+    public static final OFGroup ZERO = new OFGroup(ZERO_VAL);
 
     public static final OFGroup NO_MASK = ANY;
     public static final OFGroup FULL_MASK = ZERO;
@@ -62,7 +62,7 @@
     public static OFGroup of(final int groupNumber) {
         switch(groupNumber) {
             case ZERO_VAL:
-                return MAX;
+                return ZERO;
             case MAX_VAL:
                 return MAX;
             case ALL_VAL:
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPort.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPort.java
index d96942f..f2b1e9a 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPort.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPort.java
@@ -15,7 +15,7 @@
  * called. If this port is not representable in OpenFlow 1.0, an
  * IllegalStateException is raised.
  *
- * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ * @author Andreas Wundsam {@literal <}andreas.wundsam@bigswitch.com{@literal >}
  */
 @Immutable
 public class OFPort implements OFValueType<OFPort> {
@@ -445,7 +445,7 @@
 
     /**
      * return the port number as int16. Special ports as defined by the OpenFlow
-     * spec will be converted to their OpenFlow 1.0 equivalent. port numbers >=
+     * spec will be converted to their OpenFlow 1.0 equivalent. port numbers {@literal >=}
      * FF00 will cause a IllegalArgumentException to be thrown
      *
      * @throws IllegalArgumentException
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPortBitMap.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPortBitMap.java
index 63b97f3..1d658c5 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPortBitMap.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPortBitMap.java
@@ -37,7 +37,7 @@
  *  matchBuilder.setMasked(MatchField.BSN_IN_PORTS_128, portBitmap);
  *  </pre>
  *
- * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ * @author Andreas Wundsam {@literal <}andreas.wundsam@bigswitch.com{@literal >}
  */
 @Immutable
 public class OFPortBitMap extends Masked<OFBitMask128> {
@@ -47,7 +47,7 @@
     }
 
     /** @return whether or not the given port is logically included in the
-     *  match, i.e., whether a packet from in-port <emph>port</emph> be matched by
+     *  match, i.e., whether a packet from in-port <em>port</em> be matched by
      *  this OXM.
      */
     public boolean isOn(OFPort port) {
@@ -71,7 +71,7 @@
     }
 
     /** @return iterating over all ports that are logically included in the
-     *  match, i.e., whether a packet from in-port <emph>port</emph> be matched by
+     *  match, i.e., whether a packet from in-port <em>port</em> be matched by
      *  this OXM.
      */
     public Iterable<OFPort> getOnPorts() {
@@ -105,7 +105,7 @@
         }
 
         /** @return whether or not the given port is logically included in the
-         *  match, i.e., whether a packet from in-port <emph>port</emph> be matched by
+         *  match, i.e., whether a packet from in-port <em>port</em> be matched by
          *  this OXM.
          */
         public boolean isOn(OFPort port) {
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatch.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatch.java
index 0a35926..91c9fc8 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatch.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatch.java
@@ -21,7 +21,7 @@
  *  </b>
  *
  *
- * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ * @author Andreas Wundsam {@literal <}andreas.wundsam@bigswitch.com{@literal >}
  *
  */
 public class OFVlanVidMatch implements OFValueType<OFVlanVidMatch> {
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/VlanVid.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/VlanVid.java
index ee605de..1c3eba4 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/VlanVid.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/VlanVid.java
@@ -10,7 +10,7 @@
 
 /** Represents an 802.1Q Vlan VID (12 bits).
  *
- * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ * @author Andreas Wundsam {@literal <}andreas.wundsam@bigswitch.com{@literal >}
  *
  */
 public class VlanVid implements OFValueType<VlanVid> {
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/PrimitiveSinkUtils.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/PrimitiveSinkUtils.java
index 28eb3a4..aafe262 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/PrimitiveSinkUtils.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/PrimitiveSinkUtils.java
@@ -11,7 +11,7 @@
 
 /** Utility methods for dumping collections into primitive sinks.
  *
- * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ * @author Andreas Wundsam {@literal <}andreas.wundsam@bigswitch.com{@literal >}
  */
 public class PrimitiveSinkUtils {
     private PrimitiveSinkUtils() {}
@@ -21,7 +21,7 @@
      *
      *
      * @param sink the sink to put the object
-     * @param nullableObj the potentially null string to put in the sink
+     * @param nullableChars the potentially null string to put in the sink
      */
     public static void putNullableStringTo(PrimitiveSink sink,
             @Nullable CharSequence nullableChars) {
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 2ba4528..6e9d047 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
@@ -130,4 +130,17 @@
         }
     }
 
+    @Test
+    public void testMulticastIp() {
+        IPAddress<?> ip0 = IPAddress.of("240.2.3.4");
+        IPAddress<?> ip1 = IPAddress.of("224.0.1.1");
+        IPAddress<?> ip2 = IPAddress.of("239.0.0.0");
+        IPAddress<?> ip3 = IPAddress.of("feff::1");
+        IPAddress<?> ip4 = IPAddress.of("ff00::1");
+        assertTrue(!ip0.isMulticast());
+        assertTrue(ip1.isMulticast());
+        assertTrue(ip2.isMulticast());
+        assertTrue(!ip3.isMulticast());
+        assertTrue(ip4.isMulticast());
+    }
 }
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java
index 0716b50..5d95a5a 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java
@@ -13,6 +13,7 @@
 import java.net.InetAddress;
 
 import org.hamcrest.CoreMatchers;
+import org.hamcrest.Matchers;
 import org.jboss.netty.buffer.ChannelBuffers;
 import org.junit.Test;
 import org.projectfloodlight.openflow.exceptions.OFParseError;
@@ -389,6 +390,21 @@
     }
 
     @Test
+    public void testCompareTo() {
+        assertThat(
+                IPv4Address.of("1.0.0.1").compareTo(IPv4Address.of("1.0.0.2")),
+                Matchers.lessThan(0));
+        assertThat(
+                IPv4Address.of("1.0.0.3").compareTo(IPv4Address.of("3.0.0.1")),
+                Matchers.lessThan(0));
+
+        // Make sure that unsigned comparison is used
+        assertThat(
+                IPv4Address.of("201.0.0.1").compareTo(IPv4Address.NONE),
+                Matchers.greaterThan(0));
+    }
+
+    @Test
     public void testOfExceptions() {
         // We check if the message of a caught NPE is set to a useful message
         // as a hacky way of verifying that we got an NPE thrown by use rather
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv6AddressTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv6AddressTest.java
index fd26856..a94f443 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv6AddressTest.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv6AddressTest.java
@@ -7,6 +7,7 @@
 import java.net.UnknownHostException;
 
 import org.hamcrest.CoreMatchers;
+import org.hamcrest.Matchers;
 import org.jboss.netty.buffer.ChannelBuffers;
 import org.junit.Test;
 import org.projectfloodlight.openflow.exceptions.OFParseError;
@@ -19,7 +20,8 @@
             "::",
             "::1",
             "ffe0::",
-            "1:2:3:4:5:6:7:8"
+            "1:2:3:4:5:6:7:8",
+            "8091:a2b3:c4d5:e6f7:8495:a6b7:c1d2:e3d4",
     };
 
 
@@ -331,6 +333,26 @@
     }
 
     @Test
+    public void testCompareTo() {
+        assertThat(
+                IPv6Address.of("fc00::1").compareTo(IPv6Address.of("fc00::2")),
+                Matchers.lessThan(0));
+        assertThat(
+                IPv6Address.of("::1").compareTo(IPv6Address.of("fc00::")),
+                Matchers.lessThan(0));
+
+        // Make sure that unsigned comparison is used on the first 64 bits
+        assertThat(
+                IPv6Address.of("fc00::1").compareTo(IPv6Address.of("1234::3")),
+                Matchers.greaterThan(0));
+
+        // Make sure that unsigned comparison is used on the next 64 bits
+        assertThat(
+                IPv6Address.of("::8000:0:0:1").compareTo(IPv6Address.of("::1")),
+                Matchers.greaterThan(0));
+    }
+
+    @Test
     public void testOfExceptions() throws Exception {
         try {
             IPv6AddressWithMask.of(null);
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFPortDescTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFPortDescTest.java
index 965e314..530f66b 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFPortDescTest.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFPortDescTest.java
@@ -18,7 +18,7 @@
 /**
  * Tests auxiliary OFPortDesc methods for all versions of OpenFlow
  *
- * @author Jason Parraga <jason.parraga@bigswitch.com>
+ * @author Jason Parraga {@literal <}jason.parraga@bigswitch.com{@literal >}
  */
 public class OFPortDescTest {
 
diff --git a/openflow_input/bsn-1.4 b/openflow_input/bsn-1.4
new file mode 100644
index 0000000..c64a70a
--- /dev/null
+++ b/openflow_input/bsn-1.4
@@ -0,0 +1,35 @@
+// Copyright 2015, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+// the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may distribute libraries
+// generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+// that copyright and licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i) included in
+// the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+// documentation for the LoxiGen Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+// a copy of the EPL at:
+//
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// EPL for the specific language governing permissions and limitations
+// under the EPL.
+
+#version 5
+
+struct of_port_desc_prop_bsn : of_port_desc_prop_experimenter {
+    uint16_t type == 0xffff;
+    uint16_t length;
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t exp_type == ?;
+};
diff --git a/openflow_input/bsn_disable_l3 b/openflow_input/bsn_disable_l3
new file mode 100644
index 0000000..29d8ad1
--- /dev/null
+++ b/openflow_input/bsn_disable_l3
@@ -0,0 +1,41 @@
+// Copyright 2015, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+// the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may distribute libraries
+// generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+// that copyright and licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i) included in
+// the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+// documentation for the LoxiGen Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+// a copy of the EPL at:
+//
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// EPL for the specific language governing permissions and limitations
+// under the EPL.
+//
+// Also derived from the OpenFlow header files which have these copyrights:
+// Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+// Copyright (c) 2011, 2012 Open Networking Foundation
+
+#version 4
+#version 5
+
+struct of_instruction_bsn_disable_l3 : of_instruction_bsn {
+    uint16_t type == 65535;
+    uint16_t len;
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 13;
+    pad(4);
+};
diff --git a/openflow_input/bsn_ingress_port_group_id b/openflow_input/bsn_ingress_port_group_id
new file mode 100644
index 0000000..5e1ad97
--- /dev/null
+++ b/openflow_input/bsn_ingress_port_group_id
@@ -0,0 +1,49 @@
+// Copyright 2015, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License,
+// version 1.0 (EPL), with the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may
+// distribute libraries generated by LoxiGen (LoxiGen Libraries)
+// under the terms of your choice, provided that copyright and
+// licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i)
+// included in the LoxiGen Libraries, if distributed in source code
+// form and (ii) included in any documentation for the LoxiGen
+// Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc.
+// This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or
+// LOXI Exception. You may obtain a copy of the EPL at:
+//
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an "AS
+// IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+// express or implied. See the EPL for the specific language
+// governing permissions and limitations under the EPL.
+
+#version 3
+#version 4
+#version 5
+
+/*
+ * Ingress port group ID for SwitchLight
+ */
+
+struct of_oxm_bsn_ingress_port_group_id : of_oxm {
+    uint32_t type_len == 0x00032804;
+    uint32_t value;
+};
+
+struct of_oxm_bsn_ingress_port_group_id_masked : of_oxm {
+    uint32_t type_len == 0x00032908;
+    uint32_t value;
+    uint32_t value_mask;
+};
+
diff --git a/openflow_input/bsn_inner_eth_dst b/openflow_input/bsn_inner_eth_dst
new file mode 100644
index 0000000..d3e9fa9
--- /dev/null
+++ b/openflow_input/bsn_inner_eth_dst
@@ -0,0 +1,47 @@
+// Copyright 2015, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License,
+// version 1.0 (EPL), with the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may
+// distribute libraries generated by LoxiGen (LoxiGen Libraries)
+// under the terms of your choice, provided that copyright and
+// licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i)
+// included in the LoxiGen Libraries, if distributed in source code
+// form and (ii) included in any documentation for the LoxiGen
+// Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc.
+// This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or
+// LOXI Exception. You may obtain a copy of the EPL at:
+//
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an "AS
+// IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+// express or implied. See the EPL for the specific language
+// governing permissions and limitations under the EPL.
+
+#version 4
+#version 5
+
+/*
+ * Inner ethernet destination MAC
+ */
+
+struct of_oxm_bsn_inner_eth_dst : of_oxm {
+    uint32_t type_len == 0x00032c06;
+    of_mac_addr_t value;
+};
+
+struct of_oxm_bsn_inner_eth_dst_masked : of_oxm {
+    uint32_t type_len == 0x00032d0c;
+    of_mac_addr_t value;
+    of_mac_addr_t value_mask;
+};
diff --git a/openflow_input/bsn_inner_eth_src b/openflow_input/bsn_inner_eth_src
new file mode 100644
index 0000000..36e0e35
--- /dev/null
+++ b/openflow_input/bsn_inner_eth_src
@@ -0,0 +1,47 @@
+// Copyright 2015, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License,
+// version 1.0 (EPL), with the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may
+// distribute libraries generated by LoxiGen (LoxiGen Libraries)
+// under the terms of your choice, provided that copyright and
+// licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i)
+// included in the LoxiGen Libraries, if distributed in source code
+// form and (ii) included in any documentation for the LoxiGen
+// Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc.
+// This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or
+// LOXI Exception. You may obtain a copy of the EPL at:
+//
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an "AS
+// IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+// express or implied. See the EPL for the specific language
+// governing permissions and limitations under the EPL.
+
+#version 4
+#version 5
+
+/*
+ * Inner ethernet source MAC
+ */
+
+struct of_oxm_bsn_inner_eth_src : of_oxm {
+    uint32_t type_len == 0x00032e06;
+    of_mac_addr_t value;
+};
+
+struct of_oxm_bsn_inner_eth_src_masked : of_oxm {
+    uint32_t type_len == 0x00032f0c;
+    of_mac_addr_t value;
+    of_mac_addr_t value_mask;
+};
diff --git a/openflow_input/bsn_internal_priority b/openflow_input/bsn_internal_priority
new file mode 100644
index 0000000..55d903d
--- /dev/null
+++ b/openflow_input/bsn_internal_priority
@@ -0,0 +1,41 @@
+// Copyright 2015, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+// the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may distribute libraries
+// generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+// that copyright and licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i) included in
+// the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+// documentation for the LoxiGen Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+// a copy of the EPL at:
+//
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// EPL for the specific language governing permissions and limitations
+// under the EPL.
+//
+// Also derived from the OpenFlow header files which have these copyrights:
+// Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+// Copyright (c) 2011, 2012 Open Networking Foundation
+
+#version 4
+#version 5
+
+struct of_instruction_bsn_internal_priority : of_instruction_bsn {
+    uint16_t type == 65535;
+    uint16_t len;
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 12;
+    uint32_t value;
+};
diff --git a/openflow_input/bsn_pktin_flag b/openflow_input/bsn_pktin_flag
index b046024..b21616a 100644
--- a/openflow_input/bsn_pktin_flag
+++ b/openflow_input/bsn_pktin_flag
@@ -46,4 +46,5 @@
     OFP_BSN_PKTIN_FLAG_INGRESS_ACL = 0x400,
     OFP_BSN_PKTIN_FLAG_SFLOW = 0x800,
     OFP_BSN_PKTIN_FLAG_ARP_CACHE = 0x1000,
+    OFP_BSN_PKTIN_FLAG_ARP_TARGET = 0x2000,
 };
diff --git a/openflow_input/bsn_port_counter b/openflow_input/bsn_port_counter
index 6cf5e10..51a36f8 100644
--- a/openflow_input/bsn_port_counter
+++ b/openflow_input/bsn_port_counter
@@ -59,6 +59,7 @@
   OFP_BSN_PORT_COUNTER_RX_LENGTH_ERRORS = 24,
   OFP_BSN_PORT_COUNTER_RX_OVERFLOW_ERRORS = 25,
   OFP_BSN_PORT_COUNTER_TX_CARRIER_ERRORS = 26,
+  OFP_BSN_PORT_COUNTER_RX_PACKETS_BAD_VLAN = 27,
 };
 
 struct of_bsn_port_counter_stats_request : of_bsn_stats_request {
diff --git a/openflow_input/bsn_tlv b/openflow_input/bsn_tlv
index 7e9b376..150c879 100644
--- a/openflow_input/bsn_tlv
+++ b/openflow_input/bsn_tlv
@@ -474,3 +474,29 @@
     uint16_t length;
     uint64_t value;
 };
+
+struct of_bsn_tlv_vlan_pcp : of_bsn_tlv {
+    uint16_t type == 72;
+    uint16_t length;
+    uint8_t value;
+};
+
+struct of_bsn_tlv_strip_vlan_on_egress : of_bsn_tlv {
+    uint16_t type == 73;
+    uint16_t length;
+};
+
+struct of_bsn_tlv_set_loopback_mode: of_bsn_tlv {
+    uint16_t type == 74;
+    uint16_t length;
+};
+
+struct of_bsn_tlv_strip_mpls_l2_on_ingress : of_bsn_tlv {
+    uint16_t type == 75;
+    uint16_t length;
+};
+
+struct of_bsn_tlv_strip_mpls_l3_on_ingress : of_bsn_tlv {
+    uint16_t type == 76;
+    uint16_t length;
+};
diff --git a/openflow_input/bsn_uplink b/openflow_input/bsn_uplink
new file mode 100644
index 0000000..dec2ed4
--- /dev/null
+++ b/openflow_input/bsn_uplink
@@ -0,0 +1,35 @@
+// Copyright 2015, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+// the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may distribute libraries
+// generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+// that copyright and licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i) included in
+// the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+// documentation for the LoxiGen Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+// a copy of the EPL at:
+//
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// EPL for the specific language governing permissions and limitations
+// under the EPL.
+
+#version 5
+
+struct of_port_desc_prop_bsn_uplink : of_port_desc_prop_bsn {
+    uint16_t type == 0xffff;
+    uint16_t length;
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t exp_type == 0;
+};
diff --git a/openflow_input/bsn_vxlan b/openflow_input/bsn_vxlan
new file mode 100644
index 0000000..4171a51
--- /dev/null
+++ b/openflow_input/bsn_vxlan
@@ -0,0 +1,47 @@
+// Copyright 2015, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License,
+// version 1.0 (EPL), with the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may
+// distribute libraries generated by LoxiGen (LoxiGen Libraries)
+// under the terms of your choice, provided that copyright and
+// licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i)
+// included in the LoxiGen Libraries, if distributed in source code
+// form and (ii) included in any documentation for the LoxiGen
+// Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc.
+// This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or
+// LOXI Exception. You may obtain a copy of the EPL at:
+//
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an "AS
+// IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+// express or implied. See the EPL for the specific language
+// governing permissions and limitations under the EPL.
+
+#version 4
+#version 5
+
+/*
+ * VXLAN Virtual Network Identifier
+ */
+
+struct of_oxm_bsn_vxlan_network_id : of_oxm {
+    uint32_t type_len == 0x00032a04;
+    uint32_t value;
+};
+
+struct of_oxm_bsn_vxlan_network_id_masked : of_oxm {
+    uint32_t type_len == 0x00032b08;
+    uint32_t value;
+    uint32_t value_mask;
+};
diff --git a/py_gen/codegen.py b/py_gen/codegen.py
index 9c741d2..aa7141a 100644
--- a/py_gen/codegen.py
+++ b/py_gen/codegen.py
@@ -88,6 +88,7 @@
     render('__init__.py', template_name='toplevel_init.py')
     render('pp.py')
     render('generic_util.py')
+    render('connection.py')
 
     for version in loxi_globals.OFVersions.all_supported:
         subdir = 'of' + version.version.replace('.', '')
diff --git a/py_gen/templates/connection.py b/py_gen/templates/connection.py
new file mode 100644
index 0000000..f0648be
--- /dev/null
+++ b/py_gen/templates/connection.py
@@ -0,0 +1,264 @@
+:: # Copyright 2015, Big Switch Networks, Inc.
+:: #
+:: # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+:: # the following special exception:
+:: #
+:: # LOXI Exception
+:: #
+:: # As a special exception to the terms of the EPL, you may distribute libraries
+:: # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+:: # that copyright and licensing notices generated by LoxiGen are not altered or removed
+:: # from the LoxiGen Libraries and the notice provided below is (i) included in
+:: # the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+:: # documentation for the LoxiGen Libraries, if distributed in binary form.
+:: #
+:: # Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+:: #
+:: # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+:: # a copy of the EPL at:
+:: #
+:: # http://www.eclipse.org/legal/epl-v10.html
+:: #
+:: # Unless required by applicable law or agreed to in writing, software
+:: # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+:: # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+:: # EPL for the specific language governing permissions and limitations
+:: # under the EPL.
+::
+# Copyright 2015, Big Switch Networks, Inc.
+
+"""
+OpenFlow connection class
+
+This class creates a thread which continually parses OpenFlow messages off the
+supplied socket and places them in a queue. The class has methods for reading messages
+from the RX queue, sending messages, and higher level operations like request-response
+and multipart transactions.
+"""
+
+import loxi
+import loxi.of14
+import logging
+import time
+import socket
+import errno
+import os
+import select
+from threading import Condition, Lock, Thread
+
+DEFAULT_TIMEOUT = 1
+
+class TransactionError(Exception):
+    def __str__(self):
+        return self.args[0]
+
+    @property
+    def msg(self):
+        return self.args[1]
+
+class Connection(Thread):
+    def __init__(self, sock):
+        Thread.__init__(self)
+        self.sock = sock
+        self.logger = logging.getLogger("connection")
+        self.rx = []
+        self.rx_cv = Condition()
+        self.tx_lock = Lock()
+        self.next_xid = 1
+        self.wakeup_rd, self.wakeup_wr = os.pipe()
+        self.finished = False
+        self.read_buffer = None
+
+    def run(self):
+        while not self.finished:
+            rd, wr, err = select.select([self.sock, self.wakeup_rd], [], [])
+            if self.sock in rd:
+                self.process_read()
+            if self.wakeup_rd in rd:
+                os.read(self.wakeup_rd, 1)
+        self.logger.debug("Exited event loop")
+
+    def process_read(self):
+        recvd = self.sock.recv(4096)
+
+        self.logger.debug("Received %d bytes", len(recvd))
+
+        buf = self.read_buffer
+        if buf:
+            buf += recvd
+        else:
+            buf = recvd
+
+        offset = 0
+        while offset < len(buf):
+            if offset + 8 > len(buf):
+                # Not enough data for the OpenFlow header
+                break
+
+            # Parse the header to get type
+            hdr_version, hdr_type, hdr_msglen, hdr_xid = loxi.of14.message.parse_header(buf[offset:])
+
+            # Use loxi to resolve ofp of matching version
+            ofp = loxi.protocol(hdr_version)
+
+            # Extract the raw message bytes
+            if (offset + hdr_msglen) > len(buf):
+                # Not enough data for the body
+                break
+            rawmsg = buf[offset : offset + hdr_msglen]
+            offset += hdr_msglen
+
+            msg = ofp.message.parse_message(rawmsg)
+            if not msg:
+                self.logger.warn("Could not parse message")
+                continue
+
+            self.logger.debug("Received message %s.%s xid %d length %d",
+                              type(msg).__module__, type(msg).__name__, hdr_xid, hdr_msglen)
+
+            with self.rx_cv:
+                self.rx.append(msg)
+                self.rx_cv.notify_all()
+
+        if offset == len(buf):
+            self.read_buffer = None
+        else:
+            self.read_buffer = buf[offset:]
+            self.logger.debug("%d bytes remaining", len(self.read_buffer))
+
+    def recv(self, predicate, timeout=DEFAULT_TIMEOUT):
+        """
+        Remove and return the first message in the RX queue for
+        which 'predicate' returns true
+        """
+        assert self.is_alive()
+
+        deadline = time.time() + timeout
+        while True:
+            with self.rx_cv:
+                for i, msg in enumerate(self.rx):
+                    if predicate(msg):
+                        return self.rx.pop(i)
+
+                now = time.time()
+                if now > deadline:
+                    return None
+                else:
+                    self.rx_cv.wait(deadline - now)
+
+    def recv_any(self, timeout=DEFAULT_TIMEOUT):
+        """
+        Return the first message in the RX queue
+        """
+        return self.recv(lambda msg: True, timeout)
+
+    def recv_xid(self, xid, timeout=DEFAULT_TIMEOUT):
+        """
+        Return the first message in the RX queue with XID 'xid'
+        """
+        return self.recv(lambda msg: msg.xid == xid, timeout)
+
+    def recv_class(self, klass, timeout=DEFAULT_TIMEOUT):
+        """
+        Return the first message in the RX queue which is an instance of 'klass'
+        """
+        return self.recv(lambda msg: isinstance(msg, klass), timeout)
+
+    def send_raw(self, buf):
+        """
+        Send raw bytes on the socket
+        """
+        assert self.is_alive()
+        self.logger.debug("Sending raw message length %d", len(buf))
+        with self.tx_lock:
+            if self.sock.sendall(buf) is not None:
+                raise RuntimeError("failed to send message to switch")
+
+    def send(self, msg):
+        """
+        Send a message
+        """
+        assert self.is_alive()
+
+        if msg.xid is None:
+            msg.xid = self._gen_xid()
+        buf = msg.pack()
+        self.logger.debug("Sending message %s.%s xid %d length %d",
+                          type(msg).__module__, type(msg).__name__, msg.xid, len(buf))
+        with self.tx_lock:
+            if self.sock.sendall(buf) is not None:
+                raise RuntimeError("failed to send message to switch")
+
+    def transact(self, msg, timeout=DEFAULT_TIMEOUT):
+        """
+        Send a message and return the reply
+        """
+        self.send(msg)
+        reply = self.recv_xid(msg.xid, timeout)
+        if reply is None:
+            raise TransactionError("no reply for %s" % type(msg).__name__, None)
+        elif isinstance(reply, loxi.protocol(reply.version).message.error_msg):
+            raise TransactionError("received %s in response to %s" % (type(reply).__name__, type(msg).__name__), reply)
+        return reply
+
+    def transact_multipart_generator(self, msg, timeout=DEFAULT_TIMEOUT):
+        """
+        Send a multipart request and yield each entry from the replies
+        """
+        self.send(msg)
+        finished = False
+        while not finished:
+            reply = self.recv_xid(msg.xid, timeout)
+            if reply is None:
+                raise TransactionError("no reply for %s" % type(msg).__name__, None)
+            elif not isinstance(reply, loxi.protocol(reply.version).message.stats_reply):
+                raise TransactionError("received %s in response to %s" % (type(reply).__name__, type(msg).__name__), reply)
+            for entry in reply.entries:
+                yield entry
+            finished = reply.flags & loxi.protocol(reply.version).OFPSF_REPLY_MORE == 0
+
+    def transact_multipart(self, msg, timeout=DEFAULT_TIMEOUT):
+        """
+        Send a multipart request and return all entries from the replies
+        """
+        entries = []
+        for entry in self.transact_multipart_generator(msg, timeout):
+            entries.append(entry)
+        return entries
+
+    def stop(self):
+        """
+        Signal the thread to exit and wait for it
+        """
+        assert not self.finished
+        self.logger.debug("Stopping connection")
+        self.finished = True
+        os.write(self.wakeup_wr, "x")
+        self.join()
+        self.sock.close()
+        os.close(self.wakeup_rd)
+        os.close(self.wakeup_wr)
+        self.logger.debug("Stopped connection")
+
+    def _gen_xid(self):
+        xid = self.next_xid
+        self.next_xid += 1
+        return xid
+
+def connect(ip, port=6653, daemon=True, ofp=loxi.of14):
+    """
+    Actively connect to a switch
+    """
+    soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    soc.connect((ip, port))
+    soc.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True)
+    cxn = Connection(soc)
+    cxn.daemon = daemon
+    cxn.logger.debug("Connected to %s:%d", ip, port)
+    cxn.start()
+
+    cxn.send(ofp.message.hello())
+    if not cxn.recv(lambda msg: msg.type == ofp.OFPT_HELLO):
+        raise Exception("Did not receive HELLO")
+
+    return cxn
diff --git a/wireshark_gen/field_info.py b/wireshark_gen/field_info.py
index 6c35d99..bc11170 100644
--- a/wireshark_gen/field_info.py
+++ b/wireshark_gen/field_info.py
@@ -194,4 +194,5 @@
     ("of_role_request_failed_error_msg", "data"): "read_openflow",
     ("of_meter_mod_failed_error_msg", "data"): "read_openflow",
     ("of_table_features_failed_error_msg", "data"): "read_openflow",
+    ("of_bundle_add_msg", "data"): "read_openflow",
 }
diff --git a/wireshark_gen/templates/_oftype_readers.lua b/wireshark_gen/templates/_oftype_readers.lua
index ad0f0c2..9695c59 100644
--- a/wireshark_gen/templates/_oftype_readers.lua
+++ b/wireshark_gen/templates/_oftype_readers.lua
@@ -76,6 +76,8 @@
         dissect_of_match_v3_v3(reader, subtree:add("of_match"))
     elseif version == 4 then
         dissect_of_match_v3_v4(reader, subtree:add("of_match"))
+    elseif version == 5 then
+        dissect_of_match_v3_v5(reader, subtree:add("of_match"))
     else
         error("Unsupported match version")
     end
@@ -133,6 +135,10 @@
     read_scalar(reader, subtree, field_name, 32)
 end
 
+function read_of_str64_t(reader, version, subtree, field_name)
+    read_scalar(reader, subtree, field_name, 64)
+end
+
 function read_of_port_desc_t(reader, version, subtree, field_name)
     if reader.is_empty() then
         return
diff --git a/wireshark_gen/templates/openflow.lua b/wireshark_gen/templates/openflow.lua
index f96fccf..f6aaea3 100644
--- a/wireshark_gen/templates/openflow.lua
+++ b/wireshark_gen/templates/openflow.lua
@@ -74,10 +74,13 @@
 :: #endif
 :: #endfor
 
+error_field = ProtoField.string("of.error", "Error")
+
 p_of.fields = {
 :: for field in fields:
     fields[${repr(field.fullname)}],
 :: #endfor
+    error_field,
 }
 
 -- Subclass maps for virtual classes
@@ -142,6 +145,13 @@
         return "Unknown protocol", "Dissection error"
     end
 
+    if type_val == 1 then -- OpenFlow error message
+        local err = subtree:add(error_field, "")
+        err:set_hidden()
+        err:set_generated()
+        subtree:add_expert_info(PI_DEBUG, PI_WARN, "OpenFlow error message")
+    end
+
     local info = "unknown"
     info = of_message_dissectors[version_val](reader, subtree)