Adding support for writing metadata instruction.
Needed by Centec driver.

Change-Id: I705015c4d7ac881c273a01b36b05d39d9cd9ba87
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
index 61bda98..61f669c 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
@@ -16,6 +16,7 @@
 package org.onosproject.provider.of.flow.impl;
 
 import com.google.common.collect.Lists;
+
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.Ip4Prefix;
 import org.onlab.packet.Ip6Address;
@@ -56,6 +57,7 @@
 import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions;
 import org.projectfloodlight.openflow.protocol.instruction.OFInstructionGotoTable;
 import org.projectfloodlight.openflow.protocol.instruction.OFInstructionWriteActions;
+import org.projectfloodlight.openflow.protocol.instruction.OFInstructionWriteMetadata;
 import org.projectfloodlight.openflow.protocol.match.Match;
 import org.projectfloodlight.openflow.protocol.match.MatchField;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
@@ -219,6 +221,9 @@
                             .getTableId().getValue()));
                     break;
                 case WRITE_METADATA:
+                    OFInstructionWriteMetadata m = (OFInstructionWriteMetadata) in;
+                    builder.writeMetadata(m.getMetadata().getValue(),
+                                          m.getMetadataMask().getValue());
                     break;
                 case WRITE_ACTIONS:
                     builder.deferred();
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer10.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer10.java
index 6d7e2e1..c9de450 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer10.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer10.java
@@ -167,6 +167,8 @@
                 break;
             case L0MODIFICATION:
             case GROUP:
+            case TABLE:
+            case METADATA:
                 log.warn("Instruction type {} not supported with protocol version {}",
                         i.type(), factory().getVersion());
                 break;
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
index a636a76..67c16fa 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
@@ -117,6 +117,9 @@
         if (treatment.tableTransition() != null) {
             instructions.add(buildTableGoto(treatment.tableTransition()));
         }
+        if (treatment.writeMetadata() != null) {
+            instructions.add(buildMetadata(treatment.writeMetadata()));
+        }
 
         long cookie = flowRule().id().value();
 
@@ -154,6 +157,9 @@
         if (treatment.tableTransition() != null) {
             instructions.add(buildTableGoto(treatment.tableTransition()));
         }
+        if (treatment.writeMetadata() != null) {
+            instructions.add(buildMetadata(treatment.writeMetadata()));
+        }
 
         long cookie = flowRule().id().value();
 
@@ -247,6 +253,12 @@
         return instruction;
     }
 
+    private OFInstruction buildMetadata(Instructions.MetadataInstruction m) {
+        OFInstruction instruction = factory().instructions().writeMetadata(
+                U64.of(m.metadata()), U64.of(m.metadataMask()));
+        return instruction;
+    }
+
     private OFAction buildL0Modification(Instruction i) {
         L0ModificationInstruction l0m = (L0ModificationInstruction) i;
         switch (l0m.subtype()) {