Merge branch 'master' of github.com:floodlight/loxigen
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index 19ca090..bd1967b 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -113,7 +113,22 @@
                 "OFOxmIpv6Dst":             OxmMapEntry("IPv6", "IPV6_DST", False),
                 "OFOxmIpv6DstMasked":       OxmMapEntry("IPv6", "IPV6_DST", True),
                 "OFOxmIpv6Flabel":          OxmMapEntry("IPv6FlowLabel", "IPV6_FLABEL", False),
-                "OFOxmIpv6FlabelMasked":    OxmMapEntry("IPv6FlowLabel", "IPV6_FLABEL", True) }
+                "OFOxmIpv6FlabelMasked":    OxmMapEntry("IPv6FlowLabel", "IPV6_FLABEL", True),
+                "OFOxmIcmpv6Type":          OxmMapEntry("U8", "ICMPV6_TYPE", False),
+                "OFOxmIcmpv6TypeMasked":    OxmMapEntry("U8", "ICMPV6_TYPE", True),
+                "OFOxmIcmpv6Code":          OxmMapEntry("U8", "ICMPV6_CODE", False),
+                "OFOxmIcmpv6CodeMasked":    OxmMapEntry("U8", "ICMPV6_CODE", True),
+                "OFOxmIpv6NdTarget":        OxmMapEntry("IPv6", "IPV6_ND_TARGET", False),
+                "OFOxmIpv6NdTargetMasked":  OxmMapEntry("IPv6", "IPV6_ND_TARGET", True),
+                "OFOxmIpv6NdSll":           OxmMapEntry("MacAddress", "IPV6_ND_SLL", False),
+                "OFOxmIpv6NdSllMasked":     OxmMapEntry("MacAddress", "IPV6_ND_SLL", True),
+                "OFOxmIpv6NdTll":           OxmMapEntry("MacAddress", "IPV6_ND_TLL", False),
+                "OFOxmIpv6NdTllMasked":     OxmMapEntry("MacAddress", "IPV6_ND_TLL", True),
+                "OFOxmMplsLabel":           OxmMapEntry("U32", "MPLS_LABEL", False),
+                "OFOxmMplsLabelMasked":     OxmMapEntry("U32", "MPLS_LABEL", True),
+                "OFOxmMplsTc":              OxmMapEntry("U8", "MPLS_TC", False),
+                "OFOxmMplsTcMasked":        OxmMapEntry("U8", "MPLS_TC", True)
+                }
 
     @property
     @memoize
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 333d25d..3e217e6 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
@@ -15,6 +15,8 @@
 import org.projectfloodlight.openflow.types.OFPort;
 import org.projectfloodlight.openflow.types.OFValueType;
 import org.projectfloodlight.openflow.types.TransportPort;
+import org.projectfloodlight.openflow.types.U32;
+import org.projectfloodlight.openflow.types.U8;
 import org.projectfloodlight.openflow.types.VlanPcp;
 import org.projectfloodlight.openflow.types.VlanVid;
 
@@ -140,6 +142,34 @@
             new MatchField<IPv6FlowLabel>("ipv6_flabel", MatchFields.IPV6_FLABEL,
                     new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.ETH_TYPE_IPv6));
 
+    public final static MatchField<U8> ICMPV6_TYPE =
+            new MatchField<U8>("icmpv6_type", MatchFields.ICMPV6_TYPE,
+                    new Prerequisite<IpProtocol>(MatchField.IP_PROTO, IpProtocol.IP_PROTO_IPv6_ICMP));
+
+    public final static MatchField<U8> ICMPV6_CODE =
+            new MatchField<U8>("icmpv6_code", MatchFields.ICMPV6_CODE,
+                    new Prerequisite<IpProtocol>(MatchField.IP_PROTO, IpProtocol.IP_PROTO_IPv6_ICMP));
+
+    public final static MatchField<IPv6> IPV6_ND_TARGET =
+            new MatchField<IPv6>("ipv6_nd_target", MatchFields.IPV6_ND_TARGET,
+                    new Prerequisite<U8>(MatchField.ICMPV6_TYPE, U8.of((short)135), U8.of((short)136)));
+
+    public final static MatchField<MacAddress> IPV6_ND_SLL =
+            new MatchField<MacAddress>("ipv6_nd_sll", MatchFields.IPV6_ND_SLL,
+                    new Prerequisite<U8>(MatchField.ICMPV6_TYPE, U8.of((short)135)));
+
+    public final static MatchField<MacAddress> IPV6_ND_TLL =
+            new MatchField<MacAddress>("ipv6_nd_tll", MatchFields.IPV6_ND_TLL,
+                    new Prerequisite<U8>(MatchField.ICMPV6_TYPE, U8.of((short)136)));
+
+    public final static MatchField<U32> MPLS_LABEL =
+            new MatchField<U32>("mpls_label", MatchFields.MPLS_LABEL,
+                    new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.ETH_TYPE_MPLS_UNICAST, EthType.ETH_TYPE_MPLS_MULTICAST));
+
+    public final static MatchField<U8> MPLS_TC =
+            new MatchField<U8>("mpls_tc", MatchFields.MPLS_TC,
+                    new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.ETH_TYPE_MPLS_UNICAST, EthType.ETH_TYPE_MPLS_MULTICAST));
+
     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 2fc10ae..7deb9af 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
@@ -31,4 +31,11 @@
     IPV6_SRC,
     IPV6_DST,
     IPV6_FLABEL,
+    ICMPV6_TYPE,
+    ICMPV6_CODE,
+    IPV6_ND_TARGET,
+    IPV6_ND_SLL,
+    IPV6_ND_TLL,
+    MPLS_LABEL,
+    MPLS_TC
 }
diff --git a/java_gen/templates/of_class.java b/java_gen/templates/of_class.java
index 2dc88fb..93ab558 100644
--- a/java_gen/templates/of_class.java
+++ b/java_gen/templates/of_class.java
@@ -145,7 +145,12 @@
     static class Reader implements OFMessageReader<${msg.interface.name}> {
         @Override
         public ${msg.interface.name} readFrom(ChannelBuffer bb) throws OFParseError {
+//:: for prop in msg.members:
+//:: if not prop.is_virtual and (prop.is_length_value or prop.is_field_length_value):
             int start = bb.readerIndex();
+//::     break
+//:: #endif
+//:: #endfor
 //:: fields_with_length_member = {}
 //:: for prop in msg.members:
 //:: if prop.is_virtual:
@@ -203,7 +208,9 @@
     static class Writer implements OFMessageWriter<${impl_class}> {
         @Override
         public void write(ChannelBuffer bb, ${impl_class} message) {
+//:: if not msg.is_fixed_length:
             int startIndex = bb.writerIndex();
+//:: #endif
 //:: fields_with_length_member = {}
 //:: for prop in msg.members:
 //:: if prop.c_name in fields_with_length_member:
@@ -278,7 +285,9 @@
             return false;
         if (getClass() != obj.getClass())
             return false;
+        //:: if len(msg.data_members) > 0:
         ${msg.name} other = (${msg.name}) obj;
+        //:: #endif
 
         //:: for prop in msg.data_members:
         //:: if prop.java_type.is_primitive:
@@ -300,7 +309,9 @@
 
     @Override
     public int hashCode() {
+        //:: if len(msg.data_members) > 0:
         final int prime = 31;
+        //:: #endif
         int result = 1;
 
         //:: for prop in msg.data_members:
diff --git a/java_gen/templates/of_factory_class.java b/java_gen/templates/of_factory_class.java
index adf5df1..86b092a 100644
--- a/java_gen/templates/of_factory_class.java
+++ b/java_gen/templates/of_factory_class.java
@@ -27,12 +27,15 @@
 //::
 //:: import itertools
 //:: import of_g
+//:: import re
 //:: include('_copyright.java')
 
 //:: include('_autogen.java')
 
 package ${factory.package};
 
+import org.projectfloodlight.openflow.protocol.OFOxmList;
+
 //:: include("_imports.java")
 
 public class ${factory.name} implements ${factory.interface.name} {
@@ -45,10 +48,13 @@
     }
     //:: #endfor
 
+//:: general_get_match_func_written = False
 //:: for i in factory.interface.members:
     //:: if i.is_virtual:
     //::    continue
     //:: #endif
+    //:: is_match_object = re.match('OFMatch.*', i.name) # i.has_version(factory.version) and model.generate_class(i.versioned_class(factory.version)) and i.versioned_class(factory.version).interface.parent_interface == 'Match'
+    //:: unsupported_match_object = is_match_object and not i.has_version(factory.version)
 
     //:: if len(i.writeable_members) > 0:
     public ${i.name}.Builder ${factory.interface.method_name(i, builder=True)}() {
@@ -59,6 +65,12 @@
         //:: #endif
     }
     //:: #endif
+    //:: if not general_get_match_func_written and is_match_object and not unsupported_match_object:
+    public Match.Builder buildMatch() {
+        return new ${i.versioned_class(factory.version).name}.Builder();
+    }
+    //::     general_get_match_func_written = True
+    //:: #endif
     //:: if len(i.writeable_members) <= 2:
     public ${i.name} ${factory.interface.method_name(i, builder=False)}(${", ".join("%s %s" % (p.java_type.public_type, p.name) for p in i.writeable_members)}) {
         //::   if i.has_version(factory.version) and model.generate_class(i.versioned_class(factory.version)):
diff --git a/java_gen/templates/of_factory_interface.java b/java_gen/templates/of_factory_interface.java
index 329539f..634362d 100644
--- a/java_gen/templates/of_factory_interface.java
+++ b/java_gen/templates/of_factory_interface.java
@@ -27,6 +27,7 @@
 //::
 //:: import itertools
 //:: import of_g
+//:: import re
 //:: include('_copyright.java')
 
 //:: include('_autogen.java')
@@ -52,6 +53,9 @@
     ${i.name} ${factory.method_name(i, builder=False )}(${", ".join("%s %s" % (p.java_type.public_type, p.name) for p in i.writeable_members)});
     //:: #endif
 //:: #endfor
+//:: if factory.name == 'OFFactory':
+    Match.Builder buildMatch();
+//:: #endif
 
     OFMessageReader<${factory.base_class}> getReader();
 
diff --git a/java_gen/templates/of_virtual_class.java b/java_gen/templates/of_virtual_class.java
index 86587f0..55ccc5e 100644
--- a/java_gen/templates/of_virtual_class.java
+++ b/java_gen/templates/of_virtual_class.java
@@ -51,7 +51,7 @@
 
     static class Reader implements OFMessageReader<${msg.interface.inherited_declaration()}> {
         @Override
-        public ${msg.interface.name} readFrom(ChannelBuffer bb) throws OFParseError {
+        public ${msg.interface.inherited_declaration()} readFrom(ChannelBuffer bb) throws OFParseError {
 //:: if msg.is_fixed_length:
             if(bb.readableBytes() < LENGTH)
 //:: else:
diff --git a/test_data/of13/flow_add.data b/test_data/of13/flow_add.data
index 666da50..ba6e84f 100644
--- a/test_data/of13/flow_add.data
+++ b/test_data/of13/flow_add.data
@@ -85,7 +85,7 @@
     .setOutGroup(8)
     .setFlags(0)
     .setMatch(
-        factory.buildMatchV3()
+        factory.buildMatch()
             .setMasked(MatchField.IN_PORT, OFPort.of(4), OFPort.of(5))
             .setExact(MatchField.ETH_TYPE, EthType.ETH_TYPE_IPv6)
             .setExact(MatchField.IP_PROTO, IpProtocol.IP_PROTO_TCP)
diff --git a/test_data/of13/flow_delete.data b/test_data/of13/flow_delete.data
index 22f07c2..6ae6ad4 100644
--- a/test_data/of13/flow_delete.data
+++ b/test_data/of13/flow_delete.data
@@ -85,7 +85,7 @@
     .setOutGroup(8)
     .setFlags(0)
     .setMatch(
-        factory.buildMatchV3()
+        factory.buildMatch()
             .setMasked(MatchField.IN_PORT, OFPort.of(4), OFPort.of(5))
             .setExact(MatchField.ETH_TYPE, EthType.ETH_TYPE_IPv6)
             .setExact(MatchField.IP_PROTO, IpProtocol.IP_PROTO_TCP)
diff --git a/test_data/of13/flow_delete_strict.data b/test_data/of13/flow_delete_strict.data
index ab21088..b5a96ce 100644
--- a/test_data/of13/flow_delete_strict.data
+++ b/test_data/of13/flow_delete_strict.data
@@ -85,7 +85,7 @@
     .setOutGroup(8)
     .setFlags(0)
     .setMatch(
-        factory.buildMatchV3()
+        factory.buildMatch()
             .setMasked(MatchField.IN_PORT, OFPort.of(4), OFPort.of(5))
             .setExact(MatchField.ETH_TYPE, EthType.ETH_TYPE_IPv6)
             .setExact(MatchField.IP_PROTO, IpProtocol.IP_PROTO_TCP)
diff --git a/test_data/of13/flow_modify.data b/test_data/of13/flow_modify.data
index 8218b96..06ac626 100644
--- a/test_data/of13/flow_modify.data
+++ b/test_data/of13/flow_modify.data
@@ -85,7 +85,7 @@
     .setOutGroup(8)
     .setFlags(0)
     .setMatch(
-        factory.buildMatchV3()
+        factory.buildMatch()
             .setMasked(MatchField.IN_PORT, OFPort.of(4), OFPort.of(5))
             .setExact(MatchField.ETH_TYPE, EthType.ETH_TYPE_IPv6)
             .setExact(MatchField.IP_PROTO, IpProtocol.IP_PROTO_TCP)
diff --git a/test_data/of13/flow_modify_strict.data b/test_data/of13/flow_modify_strict.data
index 3f0a074..ebdf2f0 100644
--- a/test_data/of13/flow_modify_strict.data
+++ b/test_data/of13/flow_modify_strict.data
@@ -85,7 +85,7 @@
     .setOutGroup(8)
     .setFlags(0)
     .setMatch(
-        factory.buildMatchV3()
+        factory.buildMatch()
             .setMasked(MatchField.IN_PORT, OFPort.of(4), OFPort.of(5))
             .setExact(MatchField.ETH_TYPE, EthType.ETH_TYPE_IPv6)
             .setExact(MatchField.IP_PROTO, IpProtocol.IP_PROTO_TCP)