OutboundPacket: add inPort method

Allows to provide a different input port to be considered when emitting
the packet. It is useful on OpenFlow devices so one can use ALL or FLOOD
actions as output and not have the packet sent back on the input port.

Default is controller port, as it was before.

The required changes were also implemented in OpenFlowPacketProvider

Change-Id: I0a050b983b5de9935254599e8093dc59ad7a4ccf
diff --git a/core/api/src/main/java/org/onosproject/net/packet/DefaultOutboundPacket.java b/core/api/src/main/java/org/onosproject/net/packet/DefaultOutboundPacket.java
index 9747720..e66d15f 100644
--- a/core/api/src/main/java/org/onosproject/net/packet/DefaultOutboundPacket.java
+++ b/core/api/src/main/java/org/onosproject/net/packet/DefaultOutboundPacket.java
@@ -15,13 +15,13 @@
  */
 package org.onosproject.net.packet;
 
-import java.nio.ByteBuffer;
-import java.util.Objects;
-
+import com.google.common.base.MoreObjects;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.TrafficTreatment;
 
-import com.google.common.base.MoreObjects;
+import java.nio.ByteBuffer;
+import java.util.Objects;
 
 /**
  * Default implementation of an immutable outbound packet.
@@ -30,6 +30,7 @@
     private final DeviceId sendThrough;
     private final TrafficTreatment treatment;
     private final ByteBuffer data;
+    private final PortNumber inPort;
 
     /**
      * Creates an immutable outbound packet.
@@ -43,6 +44,24 @@
         this.sendThrough = sendThrough;
         this.treatment = treatment;
         this.data = data;
+        this.inPort = null;
+    }
+
+    /**
+     * Creates an immutable outbound packet.
+     *
+     * @param sendThrough identifier through which to send the packet
+     * @param treatment   list of packet treatments
+     * @param data        raw packet data
+     * @param inPort      input port to be used for the packet
+     */
+    public DefaultOutboundPacket(DeviceId sendThrough,
+                                 TrafficTreatment treatment, ByteBuffer data,
+                                 PortNumber inPort) {
+        this.sendThrough = sendThrough;
+        this.treatment = treatment;
+        this.data = data;
+        this.inPort = inPort;
     }
 
     @Override
@@ -62,8 +81,13 @@
     }
 
     @Override
+    public PortNumber inPort() {
+        return inPort;
+    }
+
+    @Override
     public int hashCode() {
-        return Objects.hash(sendThrough, treatment, data);
+        return Objects.hash(sendThrough, treatment, data, inPort);
     }
 
     @Override
@@ -75,7 +99,8 @@
             final DefaultOutboundPacket other = (DefaultOutboundPacket) obj;
             return Objects.equals(this.sendThrough, other.sendThrough) &&
                     Objects.equals(this.treatment, other.treatment) &&
-                    Objects.equals(this.data, other.data);
+                    Objects.equals(this.data, other.data) &&
+                    Objects.equals(this.inPort, other.inPort);
         }
         return false;
     }
@@ -84,6 +109,7 @@
         return MoreObjects.toStringHelper(this)
                 .add("sendThrough", sendThrough)
                 .add("treatment", treatment)
+                .add("inPort", inPort)
                 .toString();
     }
 }