Merge "Added DROP opcode support to ApfGenerator for immediate return." into main am: 1633b047c8

Original change: https://android-review.googlesource.com/c/platform/packages/modules/NetworkStack/+/2862528

Change-Id: I523f386b37c394ed502176a461f35a74f2136381
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/src/android/net/apf/ApfGenerator.java b/src/android/net/apf/ApfGenerator.java
index 638980e..fe5628c 100644
--- a/src/android/net/apf/ApfGenerator.java
+++ b/src/android/net/apf/ApfGenerator.java
@@ -42,6 +42,7 @@
     private enum Opcodes {
         LABEL(-1),
         PASS(0),   // Unconditionally pass packet, requires R=0, LEN=0, e.g. "pass"
+        DROP(0),   // Unconditionally drop packet, requires R=1, LEN=0, e.g. "drop"
         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]"
@@ -931,6 +932,16 @@
     }
 
     /**
+     * Add an instruction to the end of the program to let the program immediately return DROP.
+     */
+    public ApfGenerator addDrop() throws IllegalInstructionException {
+        requireApfVersion(MIN_APF_VERSION_IN_DEV);
+        Instruction instruction = new Instruction(Opcodes.DROP, Register.R1);
+        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 2a82452..447495c 100644
--- a/tests/unit/src/android/net/apf/ApfV5Test.kt
+++ b/tests/unit/src/android/net/apf/ApfV5Test.kt
@@ -15,9 +15,11 @@
  */
 package android.net.apf
 
+import android.net.apf.ApfGenerator.IllegalInstructionException
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
 import kotlin.test.assertContentEquals
+import kotlin.test.assertFailsWith
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -29,6 +31,12 @@
 class ApfV5Test {
 
     @Test
+    fun testApfInstructionVersionCheck() {
+        var gen = ApfGenerator(ApfGenerator.MIN_APF_VERSION)
+        assertFailsWith<IllegalInstructionException> { gen.addDrop() }
+    }
+
+    @Test
     fun testApfInstructionsEncoding() {
         var gen = ApfGenerator(ApfGenerator.MIN_APF_VERSION)
         gen.addPass()
@@ -37,6 +45,12 @@
         assertContentEquals(byteArrayOf(encodeInstruction(0, 0, 0)), program)
 
         gen = ApfGenerator(ApfGenerator.MIN_APF_VERSION_IN_DEV)
+        gen.addDrop()
+        program = gen.generate()
+        // encoding DROP opcode: opcode=0, imm_len=0, R=1
+        assertContentEquals(byteArrayOf(encodeInstruction(0, 0, 1)), 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)