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

Change-Id: I705015c4d7ac881c273a01b36b05d39d9cd9ba87
diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
index 049f49a..31148ab 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
@@ -43,6 +43,7 @@
     private final List<Instruction> deferred;
     private final List<Instruction> all;
     private final Instructions.TableTypeTransition table;
+    private final Instructions.MetadataInstruction meta;
 
     private final boolean hasClear;
 
@@ -60,6 +61,7 @@
         this.all = this.immediate;
         this.hasClear = false;
         this.table = null;
+        this.meta = null;
     }
 
     /**
@@ -73,13 +75,14 @@
     private DefaultTrafficTreatment(List<Instruction> deferred,
                                    List<Instruction> immediate,
                                    Instructions.TableTypeTransition table,
-                                   boolean clear) {
+                                   boolean clear,
+                                   Instructions.MetadataInstruction meta) {
         this.immediate = ImmutableList.copyOf(checkNotNull(immediate));
         this.deferred = ImmutableList.copyOf(checkNotNull(deferred));
         this.all = ListUtils.union(this.immediate, this.deferred);
         this.table = table;
+        this.meta = meta;
         this.hasClear = clear;
-
     }
 
     @Override
@@ -107,6 +110,11 @@
         return hasClear;
     }
 
+    @Override
+    public Instructions.MetadataInstruction writeMetadata() {
+        return meta;
+    }
+
     /**
      * Returns a new traffic treatment builder.
      *
@@ -139,7 +147,7 @@
     //FIXME: Order of instructions may affect hashcode
     @Override
     public int hashCode() {
-        return Objects.hash(immediate, deferred, table);
+        return Objects.hash(immediate, deferred, table, meta);
     }
 
     @Override
@@ -151,7 +159,8 @@
             DefaultTrafficTreatment that = (DefaultTrafficTreatment) obj;
             return Objects.equals(immediate, that.immediate) &&
                     Objects.equals(deferred, that.deferred) &&
-                    Objects.equals(table, that.table);
+                    Objects.equals(table, that.table) &&
+                    Objects.equals(meta, that.meta);
 
         }
         return false;
@@ -164,6 +173,7 @@
                 .add("deferred", deferred)
                 .add("transition", table == null ? "None" : table.toString())
                 .add("cleared", hasClear)
+                .add("metadata", meta)
                 .toString();
     }
 
@@ -177,6 +187,8 @@
 
         Instructions.TableTypeTransition table;
 
+        Instructions.MetadataInstruction meta;
+
         List<Instruction> deferred = Lists.newLinkedList();
 
         List<Instruction> immediate = Lists.newLinkedList();
@@ -213,6 +225,9 @@
                 case TABLE:
                     table = (Instructions.TableTypeTransition) instruction;
                     break;
+                case METADATA:
+                    meta = (Instructions.MetadataInstruction) instruction;
+                    break;
                 default:
                     throw new IllegalArgumentException("Unknown instruction type: " +
                                                                instruction.type());
@@ -355,6 +370,11 @@
         }
 
         @Override
+        public Builder writeMetadata(long metadata, long metadataMask) {
+            return add(Instructions.writeMetadata(metadata, metadataMask));
+        }
+
+        @Override
         public TrafficTreatment build() {
             //Don't add DROP instruction by default when instruction
             //set is empty. This will be handled in DefaultSingleTablePipeline
@@ -364,7 +384,7 @@
             //        && table == null && !clear) {
             //    drop();
             //}
-            return new DefaultTrafficTreatment(deferred, immediate, table, clear);
+            return new DefaultTrafficTreatment(deferred, immediate, table, clear, meta);
         }
 
     }