Merge "Added PASS opcode support to ApfGenerator for immediate return." into main
diff --git a/src/android/net/apf/ApfGenerator.java b/src/android/net/apf/ApfGenerator.java
index e14364e..638980e 100644
--- a/src/android/net/apf/ApfGenerator.java
+++ b/src/android/net/apf/ApfGenerator.java
@@ -41,6 +41,7 @@
     }
     private enum Opcodes {
         LABEL(-1),
+        PASS(0),   // Unconditionally pass packet, requires R=0, LEN=0, e.g. "pass"
         LDB(1),    // Load 1 byte from immediate offset, e.g. "ldb R0, [5]"
         LDH(2),    // Load 2 bytes from immediate offset, e.g. "ldh R0, [5]"
         LDW(3),    // Load 4 bytes from immediate offset, e.g. "ldw R0, [5]"
@@ -436,7 +437,9 @@
     public static final int LAST_PREFILLED_MEMORY_SLOT = FILTER_AGE_MEMORY_SLOT;
 
     // This version number syncs up with APF_VERSION in hardware/google/apf/apf_interpreter.h
-    private static final int MIN_APF_VERSION = 2;
+    public static final int MIN_APF_VERSION = 2;
+    public static final int MIN_APF_VERSION_IN_DEV = 5;
+
 
     private final ArrayList<Instruction> mInstructions = new ArrayList<Instruction>();
     private final HashMap<String, Instruction> mLabels = new HashMap<String, Instruction>();
@@ -919,6 +922,15 @@
     }
 
     /**
+     * Add an instruction to the end of the program to let the program immediately return PASS.
+     */
+    public ApfGenerator addPass() throws IllegalInstructionException {
+        Instruction instruction = new Instruction(Opcodes.PASS, Register.R0);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
      * Add an instruction to the end of the program to call the apf_allocate_buffer() function.
      *
      * @param register the register value contains the buffer size.
diff --git a/tests/unit/src/android/net/apf/ApfV5Test.kt b/tests/unit/src/android/net/apf/ApfV5Test.kt
index 8cfa316..2a82452 100644
--- a/tests/unit/src/android/net/apf/ApfV5Test.kt
+++ b/tests/unit/src/android/net/apf/ApfV5Test.kt
@@ -30,19 +30,25 @@
 
     @Test
     fun testApfInstructionsEncoding() {
-        var gen = ApfGenerator(MIN_APF_VERSION)
-        gen.addAlloc(ApfGenerator.Register.R0)
+        var gen = ApfGenerator(ApfGenerator.MIN_APF_VERSION)
+        gen.addPass()
         var program = gen.generate()
+        // encoding PASS opcode: opcode=0, imm_len=0, R=0
+        assertContentEquals(byteArrayOf(encodeInstruction(0, 0, 0)), program)
+
+        gen = ApfGenerator(ApfGenerator.MIN_APF_VERSION_IN_DEV)
+        gen.addAlloc(ApfGenerator.Register.R0)
+        program = gen.generate()
         assertContentEquals(byteArrayOf(encodeInstruction(21, 1, 0), 36), program)
         assertContentEquals(arrayOf("       0: alloc r0"), ApfJniUtils.disassembleApf(program))
 
-        gen = ApfGenerator(MIN_APF_VERSION)
+        gen = ApfGenerator(ApfGenerator.MIN_APF_VERSION_IN_DEV)
         gen.addTrans(ApfGenerator.Register.R1)
         program = gen.generate()
         assertContentEquals(byteArrayOf(encodeInstruction(21, 1, 1), 37), program)
         assertContentEquals(arrayOf("       0: trans r1"), ApfJniUtils.disassembleApf(program))
 
-        gen = ApfGenerator(MIN_APF_VERSION)
+        gen = ApfGenerator(ApfGenerator.MIN_APF_VERSION_IN_DEV)
         gen.addWrite(0x01, 1)
         gen.addWrite(0x0102, 2)
         gen.addWrite(0x01020304, 4)
@@ -57,7 +63,7 @@
                 "       2: write 0x0102",
                 "       5: write 0x01020304"), ApfJniUtils.disassembleApf(program))
 
-        gen = ApfGenerator(MIN_APF_VERSION)
+        gen = ApfGenerator(ApfGenerator.MIN_APF_VERSION_IN_DEV)
         gen.addWrite(ApfGenerator.Register.R0, 1)
         gen.addWrite(ApfGenerator.Register.R0, 2)
         gen.addWrite(ApfGenerator.Register.R0, 4)
@@ -72,7 +78,7 @@
                 "       2: write r0, 2",
                 "       4: write r0, 4"), ApfJniUtils.disassembleApf(program))
 
-        gen = ApfGenerator(MIN_APF_VERSION)
+        gen = ApfGenerator(ApfGenerator.MIN_APF_VERSION_IN_DEV)
         gen.addDataCopy(1, 5)
         gen.addPacketCopy(1000, 255)
         program = gen.generate()
@@ -85,7 +91,7 @@
                 "       0: dcopy 1, 5",
                 "       3: pcopy 1000, 255"), ApfJniUtils.disassembleApf(program))
 
-        gen = ApfGenerator(MIN_APF_VERSION)
+        gen = ApfGenerator(ApfGenerator.MIN_APF_VERSION_IN_DEV)
         gen.addDataCopy(ApfGenerator.Register.R1, 0, 5)
         gen.addPacketCopy(ApfGenerator.Register.R0, 1000, 255)
         program = gen.generate()
@@ -103,8 +109,4 @@
         val immLengthEncoding = if (immLength == 4) 3 else immLength
         return opcode.shl(3).or(immLengthEncoding.shl(1)).or(register).toByte()
     }
-
-    companion object {
-        private const val MIN_APF_VERSION = 5
-    }
 }