diff options
author | Yuyang Huang <yuyanghuang@google.com> | 2023-12-14 02:25:30 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-12-14 02:25:30 +0000 |
commit | e1b32d7e604492c2151f56dff38de36d4324cc30 (patch) | |
tree | 3fc08983382239dd041ba8b75834b40ce746fd36 | |
parent | 5334d51b9505a1efc582647f86cd670cbafdf030 (diff) | |
parent | 835b82edb0bcea247f5d558b655f0ac609058095 (diff) | |
download | NetworkStack-e1b32d7e604492c2151f56dff38de36d4324cc30.tar.gz |
Merge "Extend PASS and DROP opcode encoding to support incremental counter" into main am: 835b82edb0
Original change: https://android-review.googlesource.com/c/platform/packages/modules/NetworkStack/+/2869935
Change-Id: I0d0c90d4628ba0d43fa25620cc853f0f9d22f786
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | src/android/net/apf/ApfGenerator.java | 44 | ||||
-rw-r--r-- | tests/unit/src/android/net/apf/ApfV5Test.kt | 32 |
2 files changed, 72 insertions, 4 deletions
diff --git a/src/android/net/apf/ApfGenerator.java b/src/android/net/apf/ApfGenerator.java index fe5628c5..e63dddbe 100644 --- a/src/android/net/apf/ApfGenerator.java +++ b/src/android/net/apf/ApfGenerator.java @@ -41,8 +41,15 @@ public class ApfGenerator { } 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" + // Unconditionally pass (if R=0) or drop (if R=1) packet. + // An optional unsigned immediate value can be provided to encode the counter number. + // If the value is non-zero, the instruction increments the counter. + // The counter is located (-4 * counter number) bytes from the end of the data region. + // It is a U32 big-endian value and is always incremented by 1. + // This is more or less equivalent to: lddw R0, -N4; add R0,1; stdw R0, -N4; {pass,drop} + // e.g. "pass", "pass 1", "drop", "drop 1" + PASS(0), + DROP(0), 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]" @@ -932,6 +939,19 @@ public class ApfGenerator { } /** + * Add an instruction to the end of the program to increment the counter value and + * immediately return PASS. + */ + public ApfGenerator addCountAndPass(int counterNumber) throws IllegalInstructionException { + requireApfVersion(MIN_APF_VERSION_IN_DEV); + checkCounterNumber(counterNumber); + Instruction instruction = new Instruction(Opcodes.PASS, Register.R0); + instruction.addUnsignedImm(counterNumber); + addInstruction(instruction); + return this; + } + + /** * Add an instruction to the end of the program to let the program immediately return DROP. */ public ApfGenerator addDrop() throws IllegalInstructionException { @@ -942,6 +962,19 @@ public class ApfGenerator { } /** + * Add an instruction to the end of the program to increment the counter value and + * immediately return DROP. + */ + public ApfGenerator addCountAndDrop(int counterNumber) throws IllegalInstructionException { + requireApfVersion(MIN_APF_VERSION_IN_DEV); + checkCounterNumber(counterNumber); + Instruction instruction = new Instruction(Opcodes.DROP, Register.R1); + instruction.addUnsignedImm(counterNumber); + 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. @@ -1128,6 +1161,13 @@ public class ApfGenerator { } } + private void checkCounterNumber(int counterNumber) { + if (counterNumber < 1 || counterNumber > 1000) { + throw new IllegalArgumentException( + "Counter number must be in range (0, 1000], counterNumber: " + counterNumber); + } + } + /** * Add an instruction to the end of the program to load 32 bits from the data memory into * {@code register}. The source address is computed by adding the signed immediate diff --git a/tests/unit/src/android/net/apf/ApfV5Test.kt b/tests/unit/src/android/net/apf/ApfV5Test.kt index 447495c8..1c21bb00 100644 --- a/tests/unit/src/android/net/apf/ApfV5Test.kt +++ b/tests/unit/src/android/net/apf/ApfV5Test.kt @@ -18,6 +18,7 @@ package android.net.apf import android.net.apf.ApfGenerator.IllegalInstructionException import androidx.test.filters.SmallTest import androidx.test.runner.AndroidJUnit4 +import java.lang.IllegalArgumentException import kotlin.test.assertContentEquals import kotlin.test.assertFailsWith import org.junit.Test @@ -34,6 +35,15 @@ class ApfV5Test { fun testApfInstructionVersionCheck() { var gen = ApfGenerator(ApfGenerator.MIN_APF_VERSION) assertFailsWith<IllegalInstructionException> { gen.addDrop() } + assertFailsWith<IllegalInstructionException> { gen.addCountAndDrop(12) } + assertFailsWith<IllegalInstructionException> { gen.addCountAndPass(1000) } + } + + @Test + fun testApfInstructionArgumentCheck() { + var gen = ApfGenerator(ApfGenerator.MIN_APF_VERSION_IN_DEV) + assertFailsWith<IllegalArgumentException> { gen.addCountAndPass(0) } + assertFailsWith<IllegalArgumentException> { gen.addCountAndDrop(0) } } @Test @@ -42,13 +52,31 @@ class ApfV5Test { gen.addPass() var program = gen.generate() // encoding PASS opcode: opcode=0, imm_len=0, R=0 - assertContentEquals(byteArrayOf(encodeInstruction(0, 0, 0)), program) + assertContentEquals( + byteArrayOf(encodeInstruction(opcode = 0, immLength = 0, register = 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) + assertContentEquals( + byteArrayOf(encodeInstruction(opcode = 0, immLength = 0, register = 1)), program) + + gen = ApfGenerator(ApfGenerator.MIN_APF_VERSION_IN_DEV) + gen.addCountAndPass(129) + program = gen.generate() + // encoding COUNT(PASS) opcode: opcode=0, imm_len=size_of(imm), R=0, imm=counterNumber + assertContentEquals( + byteArrayOf(encodeInstruction(opcode = 0, immLength = 1, register = 0), + 0x81.toByte()), program) + + gen = ApfGenerator(ApfGenerator.MIN_APF_VERSION_IN_DEV) + gen.addCountAndDrop(1000) + program = gen.generate() + // encoding COUNT(DROP) opcode: opcode=0, imm_len=size_of(imm), R=1, imm=counterNumber + assertContentEquals( + byteArrayOf(encodeInstruction(opcode = 0, immLength = 2, register = 1), + 0x03, 0xe8.toByte()), program) gen = ApfGenerator(ApfGenerator.MIN_APF_VERSION_IN_DEV) gen.addAlloc(ApfGenerator.Register.R0) |