Add support for ARP_TPA, ARP_THA Set Field Instructions

Signed-off-by: souvikdas95 <souvikdas95@yahoo.co.in>
Change-Id: I9fe44d8ece8dd268bff4ec4befc31a8ea24ac9aa
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 72cfd3f..ffad4f7 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
@@ -505,6 +505,16 @@
         }
 
         @Override
+        public Builder setArpTpa(IpAddress addr) {
+            return add(Instructions.modArpTpa(addr));
+        }
+
+        @Override
+        public Builder setArpTha(MacAddress addr) {
+            return add(Instructions.modArpTha(addr));
+        }
+
+        @Override
         public Builder setArpOp(short op) {
             return add(Instructions.modL3ArpOp(op));
         }
diff --git a/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java b/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
index 50c3018..9fde774 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
@@ -420,6 +420,22 @@
         Builder setArpSha(MacAddress addr);
 
         /**
+         * Sets the arp dst ip address.
+         *
+         * @param addr an ip
+         * @return a treatment builder
+         */
+        Builder setArpTpa(IpAddress addr);
+
+        /**
+         * Sets the arp dst mac address.
+         *
+         * @param addr a macaddress
+         * @return a treatment builder
+         */
+        Builder setArpTha(MacAddress addr);
+
+        /**
          * Sets the arp operation.
          *
          * @param op the value of arp operation.
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
index d1fc61f..621c007 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
@@ -321,6 +321,28 @@
     }
 
     /**
+     * Creates a L3 ARP IP src modification.
+     *
+     * @param addr the ip address to modify to
+     * @return a L3 modification
+     */
+    public static L3ModificationInstruction modArpTpa(IpAddress addr) {
+        checkNotNull(addr, "Dst l3 ARP IP address cannot be null");
+        return new ModArpIPInstruction(L3SubType.ARP_TPA, addr);
+    }
+
+    /**
+     * Creates a l3 ARP Ether src modification.
+     *
+     * @param addr the mac address to modify to
+     * @return a l3 modification
+     */
+    public static L3ModificationInstruction modArpTha(MacAddress addr) {
+        checkNotNull(addr, "Dst l3 ARP address cannot be null");
+        return new ModArpEthInstruction(L3SubType.ARP_THA, addr);
+    }
+
+    /**
      * Creates a l3 ARP operation modification.
      *
      * @param op the ARP operation to modify to
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java
index cc15360..9edbdb8 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java
@@ -82,6 +82,16 @@
         ARP_SHA,
 
         /**
+         * ARP IP dst modification.
+         */
+        ARP_TPA,
+
+        /**
+         * ARP Ether dst modification.
+         */
+        ARP_THA,
+
+        /**
          * Arp operation modification.
          */
         ARP_OP,
diff --git a/core/api/src/test/java/org/onosproject/net/flow/instructions/InstructionsTest.java b/core/api/src/test/java/org/onosproject/net/flow/instructions/InstructionsTest.java
index 68dc489..3b6fbb4 100644
--- a/core/api/src/test/java/org/onosproject/net/flow/instructions/InstructionsTest.java
+++ b/core/api/src/test/java/org/onosproject/net/flow/instructions/InstructionsTest.java
@@ -1221,6 +1221,21 @@
     }
 
     /**
+     * Test the modArpTpa() method.
+     */
+    @Test
+    public void testModArpTpaMethod() {
+        final Instruction instruction = Instructions.modArpTpa(ip41);
+        final L3ModificationInstruction.ModArpIPInstruction modArpIPInstruction =
+                checkAndConvert(instruction,
+                                Instruction.Type.L3MODIFICATION,
+                                L3ModificationInstruction.ModArpIPInstruction.class);
+        assertThat(modArpIPInstruction.subtype(),
+                   is(L3ModificationInstruction.L3SubType.ARP_TPA));
+        assertThat(modArpIPInstruction.ip(), is(ip41));
+    }
+
+    /**
      * Tests the equals(), hashCode() and toString() methods of the
      * ModArpIPInstruction class.
      */
@@ -1254,6 +1269,21 @@
     }
 
     /**
+     * Test the modArpTha() method.
+     */
+    @Test
+    public void testModArpThaMethod() {
+        final Instruction instruction = Instructions.modArpTha(mac1);
+        final L3ModificationInstruction.ModArpEthInstruction modArpEthInstruction =
+                checkAndConvert(instruction,
+                                Instruction.Type.L3MODIFICATION,
+                                L3ModificationInstruction.ModArpEthInstruction.class);
+        assertThat(modArpEthInstruction.subtype(),
+                   is(L3ModificationInstruction.L3SubType.ARP_THA));
+        assertThat(modArpEthInstruction.mac(), is(mac1));
+    }
+
+    /**
      * Tests the equals(), hashCode() and toString() methods of the
      * ModArpIPInstruction class.
      */
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java
index 41e8e2c..74b20f7 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java
@@ -1378,17 +1378,31 @@
                 break;
 
             case ARP_SPA:
-                ModArpIPInstruction arpIpInstr = (ModArpIPInstruction) l3instruction;
-                if (arpIpInstr.ip().isIp4()) {
-                    builder.matchArpSpa((Ip4Address) arpIpInstr.ip());
+                ModArpIPInstruction srcArpIpInstr = (ModArpIPInstruction) l3instruction;
+                if (srcArpIpInstr.ip().isIp4()) {
+                    builder.matchArpSpa((Ip4Address) srcArpIpInstr.ip());
                 } else {
                     throw new IntentCompilationException(UNSUPPORTED_ARP);
                 }
                 break;
 
             case ARP_SHA:
-                ModArpEthInstruction arpEthInstr = (ModArpEthInstruction) l3instruction;
-                builder.matchArpSha(arpEthInstr.mac());
+                ModArpEthInstruction srcArpEthInstr = (ModArpEthInstruction) l3instruction;
+                builder.matchArpSha(srcArpEthInstr.mac());
+                break;
+
+            case ARP_TPA:
+                ModArpIPInstruction dstArpIpInstr = (ModArpIPInstruction) l3instruction;
+                if (dstArpIpInstr.ip().isIp4()) {
+                    builder.matchArpTpa((Ip4Address) dstArpIpInstr.ip());
+                } else {
+                    throw new IntentCompilationException(UNSUPPORTED_ARP);
+                }
+                break;
+
+            case ARP_THA:
+                ModArpEthInstruction dstArpEthInstr = (ModArpEthInstruction) l3instruction;
+                builder.matchArpTha(dstArpEthInstr.mac());
                 break;
 
             case ARP_OP:
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompiler.java
index b6e956e..7e0e660 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompiler.java
@@ -280,6 +280,8 @@
             case IPV6_FLABEL:
             case ARP_SPA:
             case ARP_SHA:
+            case ARP_TPA:
+            case ARP_THA:
             case ARP_OP:
             case TTL_OUT:
             case TTL_IN:
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 abc2e60..275df8c 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
@@ -470,13 +470,22 @@
                 oxm = factory().oxms().ipv6Flabel(IPv6FlowLabel.of(flowLabel));
                 break;
             case ARP_SPA:
-                ModArpIPInstruction aip = (ModArpIPInstruction) i;
-                ip4 = aip.ip().getIp4Address();
+                ModArpIPInstruction sAip = (ModArpIPInstruction) i;
+                ip4 = sAip.ip().getIp4Address();
                 oxm = factory().oxms().arpSpa(IPv4Address.of(ip4.toInt()));
                 break;
             case ARP_SHA:
-                ModArpEthInstruction ei = (ModArpEthInstruction) i;
-                oxm = factory().oxms().arpSha(MacAddress.of(ei.mac().toLong()));
+                ModArpEthInstruction sAei = (ModArpEthInstruction) i;
+                oxm = factory().oxms().arpSha(MacAddress.of(sAei.mac().toLong()));
+                break;
+            case ARP_TPA:
+                ModArpIPInstruction dAip = (ModArpIPInstruction) i;
+                ip4 = dAip.ip().getIp4Address();
+                oxm = factory().oxms().arpTpa(IPv4Address.of(ip4.toInt()));
+                break;
+            case ARP_THA:
+                ModArpEthInstruction dAei = (ModArpEthInstruction) i;
+                oxm = factory().oxms().arpTha(MacAddress.of(dAei.mac().toLong()));
                 break;
             case ARP_OP:
                 ModArpOpInstruction oi = (ModArpOpInstruction) i;
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java
index b63dfe7..2b4dafb 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java
@@ -818,7 +818,16 @@
             builder.setIpDscp(ipDscp.getValue().getDscpValue());
             break;
         case ARP_THA:
+            @SuppressWarnings("unchecked")
+            OFOxm<org.projectfloodlight.openflow.types.MacAddress> arptha =
+                    (OFOxm<org.projectfloodlight.openflow.types.MacAddress>) oxm;
+            builder.setArpTha(MacAddress.valueOf(arptha.getValue().getLong()));
+            break;
         case ARP_TPA:
+            @SuppressWarnings("unchecked")
+            OFOxm<IPv4Address> arptpa = (OFOxm<IPv4Address>) oxm;
+            builder.setArpTpa(Ip4Address.valueOf(arptpa.getValue().getInt()));
+            break;
         case BSN_EGR_PORT_GROUP_ID:
         case BSN_GLOBAL_VRF_ALLOWED:
         case BSN_IN_PORTS_128: