OpenFlowPacketProviderTest: better tests for packet-out with output:all

Actually check the values of the OF message
OpenFlowPacketProvider: add inPort match for OF 1.5 version

Adds matching for inPort to indicate how the inPort of the packet should
be treated when packet processing happens. This is relevant for
ALL/FLOOD actions so that the switch ignores that inPort, making it
easier to do proper flooding from the controller.

Change-Id: Id7475741cffcb5fb4b05e4750d4af8fc128ce2d6
diff --git a/providers/openflow/packet/src/main/java/org/onosproject/provider/of/packet/impl/OpenFlowPacketProvider.java b/providers/openflow/packet/src/main/java/org/onosproject/provider/of/packet/impl/OpenFlowPacketProvider.java
index 300ffcb..901103d 100644
--- a/providers/openflow/packet/src/main/java/org/onosproject/provider/of/packet/impl/OpenFlowPacketProvider.java
+++ b/providers/openflow/packet/src/main/java/org/onosproject/provider/of/packet/impl/OpenFlowPacketProvider.java
@@ -42,7 +42,10 @@
 import org.projectfloodlight.openflow.protocol.OFPortDesc;
 import org.projectfloodlight.openflow.protocol.OFVersion;
 import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.protocol.match.Match;
+import org.projectfloodlight.openflow.protocol.match.MatchField;
 import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10;
+import org.projectfloodlight.openflow.protocol.ver15.OFFactoryVer15;
 import org.projectfloodlight.openflow.types.OFBufferId;
 import org.projectfloodlight.openflow.types.OFPort;
 import org.slf4j.Logger;
@@ -146,11 +149,16 @@
                 .setPort(out)
                 .build();
         builder.setBufferId(OFBufferId.NO_BUFFER)
-                .setInPort(inPort)
                 .setActions(Collections.singletonList(act))
                 .setData(eth);
-        if (sw.factory().getVersion().getWireVersion() <= OFVersion.OF_14.getWireVersion()) {
-            builder.setInPort(OFPort.CONTROLLER);
+        int wireVersion = sw.factory().getVersion().getWireVersion();
+        if (wireVersion <= OFVersion.OF_14.getWireVersion()) {
+            builder.setInPort(inPort);
+        } else if (wireVersion <= OFVersion.OF_15.getWireVersion()) {
+            Match m = OFFactoryVer15.INSTANCE.matchWildcardAll().createBuilder()
+                    .setExact(MatchField.IN_PORT, inPort)
+                    .build();
+            builder.setMatch(m);
         }
 
         return builder.build();
diff --git a/providers/openflow/packet/src/test/java/org/onosproject/provider/of/packet/impl/OpenFlowPacketProviderTest.java b/providers/openflow/packet/src/test/java/org/onosproject/provider/of/packet/impl/OpenFlowPacketProviderTest.java
index 9a64611..c0acd5a 100644
--- a/providers/openflow/packet/src/test/java/org/onosproject/provider/of/packet/impl/OpenFlowPacketProviderTest.java
+++ b/providers/openflow/packet/src/test/java/org/onosproject/provider/of/packet/impl/OpenFlowPacketProviderTest.java
@@ -46,12 +46,17 @@
 import org.onosproject.openflow.controller.OpenFlowSwitchListener;
 import org.onosproject.openflow.controller.PacketListener;
 import org.onosproject.openflow.controller.RoleState;
+import org.projectfloodlight.openflow.protocol.OFActionType;
 import org.projectfloodlight.openflow.protocol.OFFactory;
 import org.projectfloodlight.openflow.protocol.OFMessage;
 import org.projectfloodlight.openflow.protocol.OFMeterFeatures;
 import org.projectfloodlight.openflow.protocol.OFPacketIn;
 import org.projectfloodlight.openflow.protocol.OFPacketInReason;
+import org.projectfloodlight.openflow.protocol.OFPacketOut;
 import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
 import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10;
 import org.projectfloodlight.openflow.types.MacAddress;
 import org.projectfloodlight.openflow.types.OFBufferId;
@@ -72,6 +77,7 @@
     private static final int PN2 = 200;
     private static final int PN3 = 300;
     private static final short VLANID = (short) 100;
+    private static final int IN_PORT_PN = 1;
 
     private static final DeviceId DID = DeviceId.deviceId("of:1");
     private static final DeviceId DID_MISSING = DeviceId.deviceId("of:2");
@@ -79,6 +85,7 @@
     private static final PortNumber P1 = PortNumber.portNumber(PN1);
     private static final PortNumber P2 = PortNumber.portNumber(PN2);
     private static final PortNumber P3 = PortNumber.portNumber(PN3);
+    private static final PortNumber IN_PORT = PortNumber.portNumber(IN_PORT_PN);
 
     private static final Instruction INST1 = Instructions.createOutput(P1);
     private static final Instruction INST2 = Instructions.createOutput(P2);
@@ -159,12 +166,21 @@
         assertEquals("message not sent", PLIST.size(), sw.sent.size());
         sw.sent.clear();
 
-        //Send with different inPort
-        OutboundPacket inPortPkt = outPacket(DID, TR_ALL, eth, PortNumber.portNumber(1));
+        //Send with different IN_PORT
+        OutboundPacket inPortPkt = outPacket(DID, TR_ALL, eth, IN_PORT);
         sw.setRole(RoleState.MASTER);
         provider.emit(inPortPkt);
         assertEquals("invalid switch", sw, controller.current);
         assertEquals("message not sent", PLIST_ALL.size(), sw.sent.size());
+        OFMessage ofMessage = sw.sent.get(0);
+        assertEquals("Wrong OF message type", OFType.PACKET_OUT, ofMessage.getType());
+        OFPacketOut packetOut = (OFPacketOut) ofMessage;
+        assertEquals("Wrong in port", OFPort.of(IN_PORT_PN), packetOut.getInPort());
+        assertEquals("Unexpected number of actions", 1, packetOut.getActions().size());
+        OFAction ofAction = packetOut.getActions().get(0);
+        assertEquals("Packet out action should be type output", OFActionType.OUTPUT, ofAction.getType());
+        OFActionOutput ofActionOutput = (OFActionOutput) ofAction;
+        assertEquals("Output should be ALL", OFPort.ALL, ofActionOutput.getPort());
         sw.sent.clear();
 
         //wrong Role