Merge remote-tracking branch 'upstream/master'

Conflicts:
	c_gen/c_test_gen.py
	java_gen/java_type.py
	java_gen/pre-written/pom.xml
	java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
	java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
	loxi_ir/ir_offset.py
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/BundleIdGenerator.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/BundleIdGenerator.java
new file mode 100644
index 0000000..2cb3583
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/BundleIdGenerator.java
@@ -0,0 +1,7 @@
+package org.projectfloodlight.openflow.protocol;
+
+import org.projectfloodlight.openflow.types.BundleId;
+
+public interface BundleIdGenerator {
+    BundleId nextBundleId();
+}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/BundleIdGenerators.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/BundleIdGenerators.java
new file mode 100644
index 0000000..997e0cd
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/BundleIdGenerators.java
@@ -0,0 +1,28 @@
+package org.projectfloodlight.openflow.protocol;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.projectfloodlight.openflow.types.BundleId;
+
+public class BundleIdGenerators {
+    private static final BundleIdGenerator GLOBAL_BUNDLE_ID_GENERATOR = create();
+
+    public static BundleIdGenerator create() {
+        return new StandardBundleIdGenerator();
+    }
+
+    public static BundleIdGenerator global() {
+        return GLOBAL_BUNDLE_ID_GENERATOR;
+    }
+}
+
+class StandardBundleIdGenerator implements BundleIdGenerator {
+
+    private final AtomicInteger idGen = new AtomicInteger();
+
+    @Override
+    public BundleId nextBundleId() {
+        return BundleId.of(idGen.incrementAndGet());
+    }
+
+}
\ No newline at end of file
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFVersion.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFVersion.java
index 6f54e5f..0c54fdc 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFVersion.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFVersion.java
@@ -1,7 +1,7 @@
 package org.projectfloodlight.openflow.protocol;
 
 public enum OFVersion {
-    OF_10(1), OF_11(2), OF_12(3), OF_13(4);
+    OF_10(1), OF_11(2), OF_12(3), OF_13(4), OF_14(5);
 
     public final int wireVersion;
 
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 9fb3fd4..e2f172b 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
@@ -14,6 +14,7 @@
 import org.projectfloodlight.openflow.types.LagId;
 import org.projectfloodlight.openflow.types.MacAddress;
 import org.projectfloodlight.openflow.types.OFBitMask128;
+import org.projectfloodlight.openflow.types.OFBitMask512;
 import org.projectfloodlight.openflow.types.OFBooleanValue;
 import org.projectfloodlight.openflow.types.OFMetadata;
 import org.projectfloodlight.openflow.types.OFPort;
@@ -179,12 +180,33 @@
             new MatchField<U8>("mpls_tc", MatchFields.MPLS_TC,
                     new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.MPLS_UNICAST, EthType.MPLS_MULTICAST));
 
-    public final static MatchField<U64> TUNNEL_ID = 
+    public final static MatchField<OFBooleanValue> MPLS_BOS =
+            new MatchField<OFBooleanValue>("mpls_bos", MatchFields.MPLS_BOS,
+                    new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.MPLS_UNICAST, EthType.MPLS_MULTICAST));
+
+    public final static MatchField<U64> TUNNEL_ID =
             new MatchField<U64>("tunnel_id", MatchFields.TUNNEL_ID);
 
+    public final static MatchField<U16> IPV6_EXTHDR =
+            new MatchField<U16>("ipv6_exthdr", MatchFields.IPV6_EXTHDR);
+
+    public final static MatchField<OFBooleanValue> PBB_UCA =
+            new MatchField<OFBooleanValue>("pbb_uca", MatchFields.PBB_UCA);
+
+    public final static MatchField<IPv4Address> TUNNEL_IPV4_SRC =
+            new MatchField<IPv4Address>("tunnel_ipv4_src", MatchFields.TUNNEL_IPV4_SRC,
+                    new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.IPv4));
+
+    public final static MatchField<IPv4Address> TUNNEL_IPV4_DST =
+            new MatchField<IPv4Address>("tunnel_ipv4_dst", MatchFields.TUNNEL_IPV4_DST,
+                    new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.IPv4));
+
     public final static MatchField<OFBitMask128> BSN_IN_PORTS_128 =
             new MatchField<OFBitMask128>("bsn_in_ports_128", MatchFields.BSN_IN_PORTS_128);
 
+    public final static MatchField<OFBitMask512> BSN_IN_PORTS_512 =
+            new MatchField<OFBitMask512>("bsn_in_ports_512", MatchFields.BSN_IN_PORTS_512);
+
     public final static MatchField<LagId> BSN_LAG_ID =
             new MatchField<LagId>("bsn_lag_id", MatchFields.BSN_LAG_ID);
 
@@ -236,7 +258,6 @@
     public final static MatchField<ClassId> BSN_VLAN_XLATE_PORT_GROUP_ID =
             new MatchField<ClassId>("bsn_vlan_xlate_port_group_id", MatchFields.BSN_VLAN_XLATE_PORT_GROUP_ID);
 
-
     public final static MatchField<U8> OCH_SIGTYPE =
             new MatchField<U8>("och_sigtype",
                                     MatchFields.OCH_SIGTYPE);
@@ -245,7 +266,6 @@
             new MatchField<U8>("och_sigtype_basic",
                                     MatchFields.OCH_SIGTYPE_BASIC);
 
-
     public final static MatchField<CircuitSignalID> OCH_SIGID =
             new MatchField<CircuitSignalID>("och_sigid",
                                     MatchFields.OCH_SIGID);
@@ -254,6 +274,9 @@
             new MatchField<CircuitSignalID>("och_sigid_basic",
                                     MatchFields.OCH_SIGID);
     
+    public final static MatchField<OFBooleanValue> BSN_L2_CACHE_HIT =
+            new MatchField<OFBooleanValue>("bsn_l2_cache_hit", MatchFields.BSN_L2_CACHE_HIT);
+
     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 3bf717b..12e2b20 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
@@ -38,8 +38,14 @@
     IPV6_ND_TLL,
     MPLS_LABEL,
     MPLS_TC,
+    MPLS_BOS,
     TUNNEL_ID,
+    IPV6_EXTHDR,
+    PBB_UCA,
+    TUNNEL_IPV4_SRC,
+    TUNNEL_IPV4_DST,
     BSN_IN_PORTS_128,
+    BSN_IN_PORTS_512,
     BSN_LAG_ID,
     BSN_VRF,
     BSN_GLOBAL_VRF_ALLOWED,
@@ -57,8 +63,9 @@
     BSN_UDF7,
     BSN_TCP_FLAGS,
     BSN_VLAN_XLATE_PORT_GROUP_ID,
+    BSN_L2_CACHE_HIT,
     OCH_SIGTYPE,
     OCH_SIGTYPE_BASIC,
     OCH_SIGID,
-    OCH_SIGID_BASIC,;
+    OCH_SIGID_BASIC,
 }
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/ver14/ChannelUtilsVer14.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/ver14/ChannelUtilsVer14.java
new file mode 100644
index 0000000..c893cab
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/ver14/ChannelUtilsVer14.java
@@ -0,0 +1,26 @@
+package org.projectfloodlight.openflow.protocol.ver14;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.projectfloodlight.openflow.exceptions.OFParseError;
+import org.projectfloodlight.openflow.protocol.OFMatchBmap;
+import org.projectfloodlight.openflow.protocol.match.Match;
+
+/**
+ * Collection of helper functions for reading and writing into ChannelBuffers
+ *
+ * @author capveg
+ */
+
+public class ChannelUtilsVer14 {
+    public static Match readOFMatch(final ChannelBuffer bb) throws OFParseError {
+        return OFMatchV3Ver14.READER.readFrom(bb);
+    }
+
+    public static OFMatchBmap readOFMatchBmap(ChannelBuffer bb) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    public static void writeOFMatchBmap(ChannelBuffer bb, OFMatchBmap match) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/BundleId.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/BundleId.java
new file mode 100644
index 0000000..cccf67e
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/BundleId.java
@@ -0,0 +1,92 @@
+package org.projectfloodlight.openflow.types;
+
+import javax.annotation.concurrent.Immutable;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+
+import com.google.common.hash.PrimitiveSink;
+import com.google.common.primitives.UnsignedInts;
+
+@Immutable
+public class BundleId implements OFValueType<BundleId> {
+    static final int LENGTH = 4;
+
+    private final static int NONE_VAL = 0;
+    public final static BundleId NONE = new BundleId(NONE_VAL);
+
+    private final static int NO_MASK_VAL = 0xFFFFFFFF;
+    public final static BundleId NO_MASK = new BundleId(NO_MASK_VAL);
+    public final static BundleId FULL_MASK = NONE;
+
+    private final int rawValue;
+
+    private BundleId(final int rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    public static BundleId of(final int raw) {
+        if(raw == NONE_VAL)
+            return NONE;
+        else if(raw == NO_MASK_VAL)
+            return NO_MASK;
+        return new BundleId(raw);
+    }
+
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public int getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public String toString() {
+        return UnsignedInts.toString(rawValue);
+    }
+
+    @Override
+    public BundleId applyMask(BundleId mask) {
+        return BundleId.of(rawValue & mask.rawValue);    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + rawValue;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        BundleId other = (BundleId) obj;
+        if (rawValue != other.rawValue)
+            return false;
+        return true;
+    }
+
+    public void write4Bytes(ChannelBuffer c) {
+        c.writeInt(rawValue);
+    }
+
+    public static BundleId read4Bytes(ChannelBuffer c) {
+        return BundleId.of(c.readInt());
+    }
+
+    @Override
+    public int compareTo(BundleId o) {
+        return UnsignedInts.compare(rawValue, rawValue);
+    }
+
+    @Override
+    public void putTo(PrimitiveSink sink) {
+        sink.putInt(rawValue);
+    }
+}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/ClassId.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/ClassId.java
index 7d7c38e..98c1253 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/ClassId.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/ClassId.java
@@ -43,7 +43,7 @@
 
     @Override
     public String toString() {
-        return Integer.toString(rawValue);
+        return UnsignedInts.toString(rawValue);
     }
 
     @Override
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 3a1b15e..eb37a20 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
@@ -12,14 +12,16 @@
 import com.google.common.hash.PrimitiveSink;
 import com.google.common.primitives.UnsignedInts;
 
-
+import org.projectfloodlight.openflow.protocol.Writeable;
+import org.projectfloodlight.openflow.protocol.OFMessageReader;
+import org.projectfloodlight.openflow.exceptions.OFParseError;
 
 /**
  * Wrapper around an IPv4Address address
  *
  * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
  */
-public class IPv4Address extends IPAddress<IPv4Address> {
+public class IPv4Address extends IPAddress<IPv4Address> implements Writeable {
     static final int LENGTH = 4;
     private final int rawValue;
 
@@ -38,6 +40,15 @@
         this.rawValue = rawValue;
     }
 
+    public final static Reader READER = new Reader();
+
+    private static class Reader implements OFMessageReader<IPv4Address> {
+        @Override
+        public IPv4Address readFrom(ChannelBuffer bb) throws OFParseError {
+            return new IPv4Address(bb.readInt());
+        }
+    }
+
     @Override
     public IPVersion getIpVersion() {
         return IPVersion.IPv4;
@@ -345,4 +356,8 @@
         sink.putInt(rawValue);
     }
 
+    @Override
+    public void writeTo(ChannelBuffer bb) {
+        bb.writeInt(rawValue);
+    }
 }
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 471d0fb..9d6fa4d 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
@@ -8,19 +8,22 @@
 import javax.annotation.Nonnull;
 
 import org.jboss.netty.buffer.ChannelBuffer;
-import org.projectfloodlight.openflow.exceptions.OFParseError;
 
 import com.google.common.base.Preconditions;
 import com.google.common.hash.PrimitiveSink;
 import com.google.common.primitives.Longs;
 
+import org.projectfloodlight.openflow.protocol.Writeable;
+import org.projectfloodlight.openflow.protocol.OFMessageReader;
+import org.projectfloodlight.openflow.exceptions.OFParseError;
+
 /**
  * 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>
  */
-public class IPv6Address extends IPAddress<IPv6Address> {
+public class IPv6Address extends IPAddress<IPv6Address> implements Writeable {
     static final int LENGTH = 16;
     private final long raw1;
     private final long raw2;
@@ -43,6 +46,15 @@
         this.raw2 = raw2;
     }
 
+    public final static Reader READER = new Reader();
+
+    private static class Reader implements OFMessageReader<IPv6Address> {
+        @Override
+        public IPv6Address readFrom(ChannelBuffer bb) throws OFParseError {
+            return new IPv6Address(bb.readLong(), bb.readLong());
+        }
+    }
+
     @Override
     public IPVersion getIpVersion() {
         return IPVersion.IPv6;
@@ -213,8 +225,17 @@
     public static IPv6Address of(@Nonnull final String string) throws IllegalArgumentException {
         Preconditions.checkNotNull(string, "string must not be null");
 
+        // remove the zone id
+        int zoneDelimIndex = string.indexOf("%");
+        String substring;
+        if (zoneDelimIndex != -1) {
+            substring = string.substring(0, zoneDelimIndex);
+        } else {
+            substring = string;
+        }
+
         IPv6Builder builder = new IPv6Builder();
-        String[] parts = colonPattern.split(string, -1);
+        String[] parts = colonPattern.split(substring, -1);
 
         int leftWord = 0;
         int leftIndex = 0;
@@ -538,4 +559,10 @@
         sink.putLong(raw1);
         sink.putLong(raw2);
     }
+
+    @Override
+    public void writeTo(ChannelBuffer bb) {
+        bb.writeLong(raw1);
+        bb.writeLong(raw2);
+    }
 }
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
new file mode 100644
index 0000000..3fe9b88
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBitMask512.java
@@ -0,0 +1,205 @@
+package org.projectfloodlight.openflow.types;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+
+import com.google.common.hash.PrimitiveSink;
+
+public class OFBitMask512 implements OFValueType<OFBitMask512> {
+
+    static final int LENGTH = 64;
+
+    private final long raw1;
+    private final long raw2;
+    private final long raw3;
+    private final long raw4;
+    private final long raw5;
+    private final long raw6;
+    private final long raw7;
+    private final long raw8;
+
+    public static final OFBitMask512 ALL = new OFBitMask512(-1, -1, -1, -1,
+                                                            -1, -1, -1, -1);
+    public static final OFBitMask512 NONE = new OFBitMask512(0, 0, 0, 0,
+                                                             0, 0, 0, 0);
+
+    public static final OFBitMask512 NO_MASK = ALL;
+    public static final OFBitMask512 FULL_MASK = NONE;
+
+    private OFBitMask512(long raw1, long raw2, long raw3, long raw4,
+                         long raw5, long raw6, long raw7, long raw8) {
+        this.raw1 = raw1;
+        this.raw2 = raw2;
+        this.raw3 = raw3;
+        this.raw4 = raw4;
+        this.raw5 = raw5;
+        this.raw6 = raw6;
+        this.raw7 = raw7;
+        this.raw8 = raw8;
+    }
+
+    public static OFBitMask512 of(long raw1, long raw2, long raw3, long raw4,
+                                  long raw5, long raw6, long raw7, long raw8) {
+        if (raw1 == -1 && raw2 == -1 && raw3 == -1 && raw4 == -1
+                && raw5 == -1 && raw6 == -1 && raw7 == -1 && raw8 == -1)
+            return ALL;
+        if (raw1 == 0 && raw2 == 0 && raw3 == 0 && raw4 == 0
+                && raw5 == 0 && raw6 == 0 && raw7 == 0 && raw8 == 0)
+            return NONE;
+        return new OFBitMask512(raw1, raw2, raw3, raw4, raw5, raw6, raw7, raw8);
+    }
+
+    @Override
+    public int getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public OFBitMask512 applyMask(OFBitMask512 mask) {
+        return of(this.raw1 & mask.raw1, this.raw2 & mask.raw2,
+                  this.raw3 & mask.raw3, this.raw4 & mask.raw4,
+                  this.raw5 & mask.raw5, this.raw6 & mask.raw6,
+                  this.raw7 & mask.raw7, this.raw8 & mask.raw8);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + (int) (raw1 ^ (raw1 >>> 32));
+        result = prime * result + (int) (raw2 ^ (raw2 >>> 32));
+        result = prime * result + (int) (raw3 ^ (raw3 >>> 32));
+        result = prime * result + (int) (raw4 ^ (raw4 >>> 32));
+        result = prime * result + (int) (raw5 ^ (raw5 >>> 32));
+        result = prime * result + (int) (raw6 ^ (raw6 >>> 32));
+        result = prime * result + (int) (raw7 ^ (raw7 >>> 32));
+        result = prime * result + (int) (raw8 ^ (raw8 >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (getClass() != obj.getClass()) return false;
+        OFBitMask512 other = (OFBitMask512) obj;
+        if (raw1 != other.raw1) return false;
+        if (raw2 != other.raw2) return false;
+        if (raw3 != other.raw3) return false;
+        if (raw4 != other.raw4) return false;
+        if (raw5 != other.raw5) return false;
+        if (raw6 != other.raw6) return false;
+        if (raw7 != other.raw7) return false;
+        if (raw8 != other.raw8) return false;
+        return true;
+    }
+
+    protected static boolean isBitOn(long raw1, long raw2, long raw3, long raw4,
+                                     long raw5, long raw6, long raw7, long raw8, int bit) {
+        if (bit < 0 || bit >= 512)
+            throw new IndexOutOfBoundsException();
+        long word;
+        if (bit < 64) {
+            word = raw8;
+        } else if (bit < 128) {
+            word = raw7;
+            bit -= 64;
+        } else if (bit < 128) {
+            word = raw6;
+            bit -= 128;
+        } else if (bit < 128) {
+            word = raw5;
+            bit -= 192;
+        } else if (bit < 128) {
+            word = raw4;
+            bit -= 256;
+        } else if (bit < 128) {
+            word = raw3;
+            bit -= 320;
+        } else if (bit < 128) {
+            word = raw2;
+            bit -= 384;
+        } else {
+            word = raw1;
+            bit -= 448;
+        }
+        return (word & ((long)1 << bit)) != 0;
+    }
+
+    public void write64Bytes(ChannelBuffer cb) {
+        cb.writeLong(raw1);
+        cb.writeLong(raw2);
+        cb.writeLong(raw3);
+        cb.writeLong(raw4);
+        cb.writeLong(raw5);
+        cb.writeLong(raw6);
+        cb.writeLong(raw7);
+        cb.writeLong(raw8);
+    }
+
+    public static OFBitMask512 read64Bytes(ChannelBuffer cb) {
+        long raw1 = cb.readLong();
+        long raw2 = cb.readLong();
+        long raw3 = cb.readLong();
+        long raw4 = cb.readLong();
+        long raw5 = cb.readLong();
+        long raw6 = cb.readLong();
+        long raw7 = cb.readLong();
+        long raw8 = cb.readLong();
+        return of(raw1, raw2, raw3, raw4, raw5, raw6, raw7, raw8);
+    }
+
+    public boolean isOn(int bit) {
+        return isBitOn(raw1, raw2, raw3, raw4, raw5, raw6, raw7, raw8, bit);
+    }
+
+    @Override
+    public String toString() {
+        return (String.format("%64s", Long.toBinaryString(raw8))
+                + String.format("%64s", Long.toBinaryString(raw7))
+                + String.format("%64s", Long.toBinaryString(raw6))
+                + String.format("%64s", Long.toBinaryString(raw5))
+                + String.format("%64s", Long.toBinaryString(raw4))
+                + String.format("%64s", Long.toBinaryString(raw3))
+                + String.format("%64s", Long.toBinaryString(raw2))
+                + String.format("%64s", Long.toBinaryString(raw1))).replaceAll(" ", "0");
+    }
+
+    @Override
+    public int compareTo(OFBitMask512 o) {
+        long c = this.raw1 - o.raw1;
+        if (c != 0)
+            return Long.signum(c);
+        c = this.raw2 - o.raw2;
+        if (c != 0)
+            return Long.signum(c);
+        c = this.raw3 - o.raw3;
+        if (c != 0)
+            return Long.signum(c);
+        c = this.raw4 - o.raw4;
+        if (c != 0)
+            return Long.signum(c);
+        c = this.raw5 - o.raw5;
+        if (c != 0)
+            return Long.signum(c);
+        c = this.raw6 - o.raw6;
+        if (c != 0)
+            return Long.signum(c);
+        c = this.raw7 - o.raw7;
+        if (c != 0)
+            return Long.signum(c);
+        return Long.signum(this.raw8 - o.raw8);
+    }
+
+    @Override
+    public void putTo(PrimitiveSink sink) {
+        sink.putLong(raw1);
+        sink.putLong(raw2);
+        sink.putLong(raw3);
+        sink.putLong(raw4);
+        sink.putLong(raw5);
+        sink.putLong(raw6);
+        sink.putLong(raw7);
+        sink.putLong(raw8);
+    }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/MultiplePktInReasonUtil.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/MultiplePktInReasonUtil.java
index a919f62..3ee588f 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/MultiplePktInReasonUtil.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/MultiplePktInReasonUtil.java
@@ -22,10 +22,10 @@
      * reasons in Match.MetaData field.
      * */
     public static Set<OFBsnPktinFlag> getOFBsnPktinFlags(OFPacketIn pktIn) {
-        if(pktIn.getVersion() != OFVersion.OF_13) {
+        if(pktIn.getVersion().compareTo(OFVersion.OF_13) < 0) {
             throw new IllegalArgumentException("multiple pkt in reasons are "
                                                + "only supported by BVS using "
-                                               + "openflow 1.3");
+                                               + "openflow version >= 1.3");
         }
 
         Match match = pktIn.getMatch();
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 a397c2a..fd26856 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
@@ -399,4 +399,10 @@
             assertNotNull(e.getMessage());
         }
     }
+
+    @Test
+    public void testZoneId() throws OFParseError {
+        assertEquals("::", IPv6Address.of("::%eth0").toString(true, false));
+        assertEquals("1:0:0:4::8", IPv6Address.of("1:0:0:4:0:0:0:8%2").toString(true, false));
+    }
 }
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
new file mode 100644
index 0000000..965e314
--- /dev/null
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFPortDescTest.java
@@ -0,0 +1,53 @@
+package org.projectfloodlight.protocol;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+import org.junit.Test;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFPortConfig;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFPortState;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+
+import static org.hamcrest.Matchers.is;
+
+import static org.junit.Assert.assertThat;
+
+/**
+ * Tests auxiliary OFPortDesc methods for all versions of OpenFlow
+ *
+ * @author Jason Parraga <jason.parraga@bigswitch.com>
+ */
+public class OFPortDescTest {
+
+    @Test
+    public void testIsEnabled() {
+       testIsEnabledForFactory(OFFactories.getFactory(OFVersion.OF_10));
+       testIsEnabledForFactory(OFFactories.getFactory(OFVersion.OF_11));
+       testIsEnabledForFactory(OFFactories.getFactory(OFVersion.OF_12));
+       testIsEnabledForFactory(OFFactories.getFactory(OFVersion.OF_13));
+       testIsEnabledForFactory(OFFactories.getFactory(OFVersion.OF_14));
+    }
+
+    public void testIsEnabledForFactory(OFFactory factory) {
+        // Default
+        OFPortDesc desc = factory.buildPortDesc()
+                .build();
+        assertThat(desc.isEnabled(), is(true));
+
+        // Partially disabled
+        desc = factory.buildPortDesc()
+                .setConfig(new HashSet<OFPortConfig>(Arrays.asList(OFPortConfig.PORT_DOWN)))
+                .build();
+        assertThat(desc.isEnabled(), is(false));
+
+        // Fully disabled
+        desc = factory.buildPortDesc()
+                .setConfig(new HashSet<OFPortConfig>(Arrays.asList(OFPortConfig.PORT_DOWN)))
+                .setState(new HashSet<OFPortState>(Arrays.asList(OFPortState.LINK_DOWN)))
+                .build();
+        assertThat(desc.isEnabled(), is(false));
+    }
+}