[ONOS-6916] Fix bmv2 flow programmable and PiCriterionTranslator

ONOS can't add flows to the bmv2 switch

Change-Id: I66ec90d0e1ed097afeffd0498e65c239b628efa4
diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/AbstractCriterionTranslator.java b/core/net/src/main/java/org/onosproject/net/pi/impl/AbstractCriterionTranslator.java
index 19e4c3a..d403ec1 100644
--- a/core/net/src/main/java/org/onosproject/net/pi/impl/AbstractCriterionTranslator.java
+++ b/core/net/src/main/java/org/onosproject/net/pi/impl/AbstractCriterionTranslator.java
@@ -47,9 +47,9 @@
      */
     void initAsExactMatch(ImmutableByteSequence value, int bitWidth)
             throws ByteSequenceTrimException {
+        this.initType = PiMatchType.EXACT;
         this.value = fit(value, bitWidth);
         this.bitWidth = bitWidth;
-        this.initType = PiMatchType.EXACT;
     }
 
     /**
@@ -62,10 +62,10 @@
      */
     void initAsTernaryMatch(ImmutableByteSequence value, ImmutableByteSequence mask, int bitWidth)
             throws ByteSequenceTrimException {
+        this.initType = PiMatchType.TERNARY;
         this.value = fit(value, bitWidth);
         this.mask = fit(mask, bitWidth);
         this.bitWidth = bitWidth;
-        this.initType = PiMatchType.TERNARY;
     }
 
     /**
@@ -78,10 +78,19 @@
      */
     void initAsLpm(ImmutableByteSequence value, int prefixLength, int bitWidth)
             throws ByteSequenceTrimException {
+        this.initType = PiMatchType.LPM;
         this.value = fit(value, bitWidth);
         this.prefixLength = prefixLength;
         this.bitWidth = bitWidth;
-        this.initType = PiMatchType.LPM;
+    }
+
+    /**
+     * Computes the prefix padding size (in bits) based on value and bit width.
+     *
+     * @return prefix padding in bits
+     */
+    private int prefixPadding() {
+        return value.size() * Byte.SIZE - this.bitWidth;
     }
 
     @Override
@@ -112,7 +121,7 @@
     public Pair<ImmutableByteSequence, ImmutableByteSequence> ternaryMatch() {
         switch (initType) {
             case EXACT:
-                mask = ImmutableByteSequence.ofOnes(value.size());
+                mask = ImmutableByteSequence.prefixZeros(value.size(), prefixPadding());
                 break;
             case TERNARY:
                 break;
diff --git a/core/net/src/test/java/org/onosproject/net/pi/impl/PiFlowRuleTranslatorTest.java b/core/net/src/test/java/org/onosproject/net/pi/impl/PiFlowRuleTranslatorTest.java
index d5c880b..0423331 100644
--- a/core/net/src/test/java/org/onosproject/net/pi/impl/PiFlowRuleTranslatorTest.java
+++ b/core/net/src/test/java/org/onosproject/net/pi/impl/PiFlowRuleTranslatorTest.java
@@ -53,6 +53,8 @@
 public class PiFlowRuleTranslatorTest {
 
     private static final String BMV2_JSON_PATH = "/org/onosproject/net/pi/impl/default.json";
+    private static final short IN_PORT_MASK = 0x01ff; // 9-bit mask
+    private static final short ETH_TYPE_MASK = (short) 0xffff;
 
     private Random random = new Random();
     private PiPipeconf pipeconf;
@@ -138,12 +140,20 @@
         // check that values stored in entry are the same used for the flow rule
         assertThat("Incorrect inPort match param value",
                    inPortParam.value().asReadOnlyBuffer().getShort(), is(equalTo(inPort)));
+        assertThat("Incorrect inPort match param mask",
+                   inPortParam.mask().asReadOnlyBuffer().getShort(), is(equalTo(IN_PORT_MASK)));
         assertThat("Incorrect ethDestMac match param value",
                    ethDstParam.value().asArray(), is(equalTo(ethDstMac.toBytes())));
+        assertThat("Incorrect ethDestMac match param mask",
+                   ethDstParam.mask().asArray(), is(equalTo(MacAddress.BROADCAST.toBytes())));
         assertThat("Incorrect ethSrcMac match param value",
                    ethSrcParam.value().asArray(), is(equalTo(ethSrcMac.toBytes())));
+        assertThat("Incorrect ethSrcMac match param mask",
+                   ethSrcParam.mask().asArray(), is(equalTo(MacAddress.BROADCAST.toBytes())));
         assertThat("Incorrect ethType match param value",
                    ethTypeParam.value().asReadOnlyBuffer().getShort(), is(equalTo(ethType)));
+        assertThat("Incorrect ethType match param mask",
+                   ethTypeParam.mask().asReadOnlyBuffer().getShort(), is(equalTo(ETH_TYPE_MASK)));
         assertThat("Incorrect priority value",
                    entry1.priority().get(), is(equalTo(Integer.MAX_VALUE - rule1.priority())));
         assertThat("Incorrect timeout value",
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DefaultInterpreter.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DefaultInterpreter.java
index aef0719..fa6a8ea 100644
--- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DefaultInterpreter.java
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DefaultInterpreter.java
@@ -103,7 +103,7 @@
                 Instructions.OutputInstruction outInstruction = (Instructions.OutputInstruction) instruction;
                 PortNumber port = outInstruction.port();
                 if (!port.isLogical()) {
-                    PiAction.builder()
+                    return PiAction.builder()
                             .withId(PiActionId.of(SET_EGRESS_PORT))
                             .withParameter(new PiActionParam(PiActionParamId.of(PORT),
                                     ImmutableByteSequence.copyFrom(port.toLong())))
diff --git a/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/TableEntryEncoder.java b/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/TableEntryEncoder.java
index 9218f94..6b345eb 100644
--- a/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/TableEntryEncoder.java
+++ b/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/TableEntryEncoder.java
@@ -146,7 +146,7 @@
         tableEntryMsgBuilder.setTableId(tableInfo.getPreamble().getId());
 
         // Priority.
-        // FIXME: check on P4Runtime if/what is the defaulr priority.
+        // FIXME: check on P4Runtime if/what is the default priority.
         int priority = piTableEntry.priority().orElse(0);
         tableEntryMsgBuilder.setPriority(priority);