Add golden test for ApfGenerator Automatically generated via: //hardware/google/apf/apf2java/apf2java.sh (which is an APF disassembly to java test bash/sed script). The apf byte code itself was extracted from a GoogleGuest wifi connected device running: oriole-userdebug 14 UQ1A.231205.001 10959544 dev-keys and converted from hex via the apf_disassembler. Bug: 320199061 Test: TH Change-Id: I39d9b07478135ab2e9dde5f97964bd2369c83067
diff --git a/tests/unit/src/android/net/apf/ApfTest.java b/tests/unit/src/android/net/apf/ApfTest.java index 0ab33e9..85071f7 100644 --- a/tests/unit/src/android/net/apf/ApfTest.java +++ b/tests/unit/src/android/net/apf/ApfTest.java
@@ -17,6 +17,8 @@ package android.net.apf; import static android.net.apf.ApfV4Generator.APF_VERSION_4; +import static android.net.apf.ApfV4Generator.DROP_LABEL; +import static android.net.apf.ApfV4Generator.PASS_LABEL; import static android.net.apf.ApfV4Generator.Register.R0; import static android.net.apf.ApfV4Generator.Register.R1; import static android.net.apf.ApfJniUtils.compareBpfApf; @@ -37,6 +39,8 @@ import static android.system.OsConstants.IPPROTO_TCP; import static android.system.OsConstants.IPPROTO_UDP; +import static com.android.net.module.util.HexDump.hexStringToByteArray; +import static com.android.net.module.util.HexDump.toHexString; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ECHO_REQUEST_TYPE; import static org.junit.Assert.assertEquals; @@ -261,7 +265,7 @@ // Test jumping to pass label. gen = new ApfV4Generator(MIN_APF_VERSION); - gen.addJump(gen.PASS_LABEL); + gen.addJump(PASS_LABEL); byte[] program = gen.generate(); assertEquals(1, program.length); assertEquals((14 << 3) | (0 << 1) | 0, program[0]); @@ -269,7 +273,7 @@ // Test jumping to drop label. gen = new ApfV4Generator(MIN_APF_VERSION); - gen.addJump(gen.DROP_LABEL); + gen.addJump(DROP_LABEL); program = gen.generate(); assertEquals(2, program.length); assertEquals((14 << 3) | (1 << 1) | 0, program[0]); @@ -278,122 +282,122 @@ // Test jumping if equal to 0. gen = new ApfV4Generator(MIN_APF_VERSION); - gen.addJumpIfR0Equals(0, gen.DROP_LABEL); + gen.addJumpIfR0Equals(0, DROP_LABEL); assertDrop(gen); // Test jumping if not equal to 0. gen = new ApfV4Generator(MIN_APF_VERSION); - gen.addJumpIfR0NotEquals(0, gen.DROP_LABEL); + gen.addJumpIfR0NotEquals(0, DROP_LABEL); assertPass(gen); gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1); - gen.addJumpIfR0NotEquals(0, gen.DROP_LABEL); + gen.addJumpIfR0NotEquals(0, DROP_LABEL); assertDrop(gen); // Test jumping if registers equal. gen = new ApfV4Generator(MIN_APF_VERSION); - gen.addJumpIfR0EqualsR1(gen.DROP_LABEL); + gen.addJumpIfR0EqualsR1(DROP_LABEL); assertDrop(gen); // Test jumping if registers not equal. gen = new ApfV4Generator(MIN_APF_VERSION); - gen.addJumpIfR0NotEqualsR1(gen.DROP_LABEL); + gen.addJumpIfR0NotEqualsR1(DROP_LABEL); assertPass(gen); gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1); - gen.addJumpIfR0NotEqualsR1(gen.DROP_LABEL); + gen.addJumpIfR0NotEqualsR1(DROP_LABEL); assertDrop(gen); // Test load immediate. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1234567890); - gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890, DROP_LABEL); assertDrop(gen); // Test add. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addAdd(1234567890); - gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890, DROP_LABEL); assertDrop(gen); // Test add with a small signed negative value. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addAdd(-1); - gen.addJumpIfR0Equals(-1, gen.DROP_LABEL); + gen.addJumpIfR0Equals(-1, DROP_LABEL); assertDrop(gen); // Test subtract. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addAdd(-1234567890); - gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL); + gen.addJumpIfR0Equals(-1234567890, DROP_LABEL); assertDrop(gen); // Test or. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addOr(1234567890); - gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890, DROP_LABEL); assertDrop(gen); // Test and. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1234567890); gen.addAnd(123456789); - gen.addJumpIfR0Equals(1234567890 & 123456789, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890 & 123456789, DROP_LABEL); assertDrop(gen); // Test left shift. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1234567890); gen.addLeftShift(1); - gen.addJumpIfR0Equals(1234567890 << 1, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890 << 1, DROP_LABEL); assertDrop(gen); // Test right shift. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1234567890); gen.addRightShift(1); - gen.addJumpIfR0Equals(1234567890 >> 1, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890 >> 1, DROP_LABEL); assertDrop(gen); // Test multiply. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 123456789); gen.addMul(2); - gen.addJumpIfR0Equals(123456789 * 2, gen.DROP_LABEL); + gen.addJumpIfR0Equals(123456789 * 2, DROP_LABEL); assertDrop(gen); // Test divide. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1234567890); gen.addDiv(2); - gen.addJumpIfR0Equals(1234567890 / 2, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890 / 2, DROP_LABEL); assertDrop(gen); // Test divide by zero. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addDiv(0); - gen.addJump(gen.DROP_LABEL); + gen.addJump(DROP_LABEL); assertPass(gen); // Test add. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R1, 1234567890); gen.addAddR1(); - gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890, DROP_LABEL); assertDrop(gen); // Test subtract. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R1, -1234567890); gen.addAddR1(); - gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL); + gen.addJumpIfR0Equals(-1234567890, DROP_LABEL); assertDrop(gen); // Test or. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R1, 1234567890); gen.addOrR1(); - gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890, DROP_LABEL); assertDrop(gen); // Test and. @@ -401,7 +405,7 @@ gen.addLoadImmediate(R0, 1234567890); gen.addLoadImmediate(R1, 123456789); gen.addAndR1(); - gen.addJumpIfR0Equals(1234567890 & 123456789, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890 & 123456789, DROP_LABEL); assertDrop(gen); // Test left shift. @@ -409,7 +413,7 @@ gen.addLoadImmediate(R0, 1234567890); gen.addLoadImmediate(R1, 1); gen.addLeftShiftR1(); - gen.addJumpIfR0Equals(1234567890 << 1, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890 << 1, DROP_LABEL); assertDrop(gen); // Test right shift. @@ -417,7 +421,7 @@ gen.addLoadImmediate(R0, 1234567890); gen.addLoadImmediate(R1, -1); gen.addLeftShiftR1(); - gen.addJumpIfR0Equals(1234567890 >> 1, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890 >> 1, DROP_LABEL); assertDrop(gen); // Test multiply. @@ -425,7 +429,7 @@ gen.addLoadImmediate(R0, 123456789); gen.addLoadImmediate(R1, 2); gen.addMulR1(); - gen.addJumpIfR0Equals(123456789 * 2, gen.DROP_LABEL); + gen.addJumpIfR0Equals(123456789 * 2, DROP_LABEL); assertDrop(gen); // Test divide. @@ -433,136 +437,136 @@ gen.addLoadImmediate(R0, 1234567890); gen.addLoadImmediate(R1, 2); gen.addDivR1(); - gen.addJumpIfR0Equals(1234567890 / 2, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890 / 2, DROP_LABEL); assertDrop(gen); // Test divide by zero. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addDivR1(); - gen.addJump(gen.DROP_LABEL); + gen.addJump(DROP_LABEL); assertPass(gen); // Test byte load. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoad8(R0, 1); - gen.addJumpIfR0Equals(45, gen.DROP_LABEL); + gen.addJumpIfR0Equals(45, DROP_LABEL); assertDrop(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0); // Test out of bounds load. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoad8(R0, 16); - gen.addJumpIfR0Equals(0, gen.DROP_LABEL); + gen.addJumpIfR0Equals(0, DROP_LABEL); assertPass(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0); // Test half-word load. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoad16(R0, 1); - gen.addJumpIfR0Equals((45 << 8) | 67, gen.DROP_LABEL); + gen.addJumpIfR0Equals((45 << 8) | 67, DROP_LABEL); assertDrop(gen, new byte[]{123,45,67,0,0,0,0,0,0,0,0,0,0,0,0}, 0); // Test word load. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoad32(R0, 1); - gen.addJumpIfR0Equals((45 << 24) | (67 << 16) | (89 << 8) | 12, gen.DROP_LABEL); + gen.addJumpIfR0Equals((45 << 24) | (67 << 16) | (89 << 8) | 12, DROP_LABEL); assertDrop(gen, new byte[]{123,45,67,89,12,0,0,0,0,0,0,0,0,0,0}, 0); // Test byte indexed load. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R1, 1); gen.addLoad8Indexed(R0, 0); - gen.addJumpIfR0Equals(45, gen.DROP_LABEL); + gen.addJumpIfR0Equals(45, DROP_LABEL); assertDrop(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0); // Test out of bounds indexed load. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R1, 8); gen.addLoad8Indexed(R0, 8); - gen.addJumpIfR0Equals(0, gen.DROP_LABEL); + gen.addJumpIfR0Equals(0, DROP_LABEL); assertPass(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0); // Test half-word indexed load. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R1, 1); gen.addLoad16Indexed(R0, 0); - gen.addJumpIfR0Equals((45 << 8) | 67, gen.DROP_LABEL); + gen.addJumpIfR0Equals((45 << 8) | 67, DROP_LABEL); assertDrop(gen, new byte[]{123,45,67,0,0,0,0,0,0,0,0,0,0,0,0}, 0); // Test word indexed load. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R1, 1); gen.addLoad32Indexed(R0, 0); - gen.addJumpIfR0Equals((45 << 24) | (67 << 16) | (89 << 8) | 12, gen.DROP_LABEL); + gen.addJumpIfR0Equals((45 << 24) | (67 << 16) | (89 << 8) | 12, DROP_LABEL); assertDrop(gen, new byte[]{123,45,67,89,12,0,0,0,0,0,0,0,0,0,0}, 0); // Test jumping if greater than. gen = new ApfV4Generator(MIN_APF_VERSION); - gen.addJumpIfR0GreaterThan(0, gen.DROP_LABEL); + gen.addJumpIfR0GreaterThan(0, DROP_LABEL); assertPass(gen); gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1); - gen.addJumpIfR0GreaterThan(0, gen.DROP_LABEL); + gen.addJumpIfR0GreaterThan(0, DROP_LABEL); assertDrop(gen); // Test jumping if less than. gen = new ApfV4Generator(MIN_APF_VERSION); - gen.addJumpIfR0LessThan(0, gen.DROP_LABEL); + gen.addJumpIfR0LessThan(0, DROP_LABEL); assertPass(gen); gen = new ApfV4Generator(MIN_APF_VERSION); - gen.addJumpIfR0LessThan(1, gen.DROP_LABEL); + gen.addJumpIfR0LessThan(1, DROP_LABEL); assertDrop(gen); // Test jumping if any bits set. gen = new ApfV4Generator(MIN_APF_VERSION); - gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL); + gen.addJumpIfR0AnyBitsSet(3, DROP_LABEL); assertPass(gen); gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1); - gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL); + gen.addJumpIfR0AnyBitsSet(3, DROP_LABEL); assertDrop(gen); gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 3); - gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL); + gen.addJumpIfR0AnyBitsSet(3, DROP_LABEL); assertDrop(gen); // Test jumping if register greater than. gen = new ApfV4Generator(MIN_APF_VERSION); - gen.addJumpIfR0GreaterThanR1(gen.DROP_LABEL); + gen.addJumpIfR0GreaterThanR1(DROP_LABEL); assertPass(gen); gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 2); gen.addLoadImmediate(R1, 1); - gen.addJumpIfR0GreaterThanR1(gen.DROP_LABEL); + gen.addJumpIfR0GreaterThanR1(DROP_LABEL); assertDrop(gen); // Test jumping if register less than. gen = new ApfV4Generator(MIN_APF_VERSION); - gen.addJumpIfR0LessThanR1(gen.DROP_LABEL); + gen.addJumpIfR0LessThanR1(DROP_LABEL); assertPass(gen); gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R1, 1); - gen.addJumpIfR0LessThanR1(gen.DROP_LABEL); + gen.addJumpIfR0LessThanR1(DROP_LABEL); assertDrop(gen); // Test jumping if any bits set in register. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R1, 3); - gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL); + gen.addJumpIfR0AnyBitsSetR1(DROP_LABEL); assertPass(gen); gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R1, 3); gen.addLoadImmediate(R0, 1); - gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL); + gen.addJumpIfR0AnyBitsSetR1(DROP_LABEL); assertDrop(gen); gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R1, 3); gen.addLoadImmediate(R0, 3); - gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL); + gen.addJumpIfR0AnyBitsSetR1(DROP_LABEL); assertDrop(gen); // Test load from memory. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadFromMemory(R0, 0); - gen.addJumpIfR0Equals(0, gen.DROP_LABEL); + gen.addJumpIfR0Equals(0, DROP_LABEL); assertDrop(gen); // Test store to memory. @@ -570,69 +574,69 @@ gen.addLoadImmediate(R1, 1234567890); gen.addStoreToMemory(R1, 12); gen.addLoadFromMemory(R0, 12); - gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890, DROP_LABEL); assertDrop(gen); // Test filter age pre-filled memory. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadFromMemory(R0, gen.FILTER_AGE_MEMORY_SLOT); - gen.addJumpIfR0Equals(123, gen.DROP_LABEL); + gen.addJumpIfR0Equals(123, DROP_LABEL); assertDrop(gen, new byte[MIN_PKT_SIZE], 123); // Test packet size pre-filled memory. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadFromMemory(R0, gen.PACKET_SIZE_MEMORY_SLOT); - gen.addJumpIfR0Equals(MIN_PKT_SIZE, gen.DROP_LABEL); + gen.addJumpIfR0Equals(MIN_PKT_SIZE, DROP_LABEL); assertDrop(gen); // Test IPv4 header size pre-filled memory. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadFromMemory(R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); - gen.addJumpIfR0Equals(20, gen.DROP_LABEL); + gen.addJumpIfR0Equals(20, DROP_LABEL); assertDrop(gen, new byte[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x45}, 0); // Test not. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1234567890); gen.addNot(R0); - gen.addJumpIfR0Equals(~1234567890, gen.DROP_LABEL); + gen.addJumpIfR0Equals(~1234567890, DROP_LABEL); assertDrop(gen); // Test negate. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1234567890); gen.addNeg(R0); - gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL); + gen.addJumpIfR0Equals(-1234567890, DROP_LABEL); assertDrop(gen); // Test move. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R1, 1234567890); gen.addMove(R0); - gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890, DROP_LABEL); assertDrop(gen); gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1234567890); gen.addMove(R1); - gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890, DROP_LABEL); assertDrop(gen); // Test swap. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R1, 1234567890); gen.addSwap(); - gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); + gen.addJumpIfR0Equals(1234567890, DROP_LABEL); assertDrop(gen); gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1234567890); gen.addSwap(); - gen.addJumpIfR0Equals(0, gen.DROP_LABEL); + gen.addJumpIfR0Equals(0, DROP_LABEL); assertDrop(gen); // Test jump if bytes not equal. gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1); - gen.addJumpIfBytesAtR0NotEqual(new byte[]{123}, gen.DROP_LABEL); + gen.addJumpIfBytesAtR0NotEqual(new byte[]{123}, DROP_LABEL); program = gen.generate(); assertEquals(6, program.length); assertEquals((13 << 3) | (1 << 1) | 0, program[0]); @@ -644,20 +648,20 @@ assertDrop(program, new byte[MIN_PKT_SIZE], 0); gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1); - gen.addJumpIfBytesAtR0NotEqual(new byte[]{123}, gen.DROP_LABEL); + gen.addJumpIfBytesAtR0NotEqual(new byte[]{123}, DROP_LABEL); byte[] packet123 = {0,123,0,0,0,0,0,0,0,0,0,0,0,0,0}; assertPass(gen, packet123, 0); gen = new ApfV4Generator(MIN_APF_VERSION); - gen.addJumpIfBytesAtR0NotEqual(new byte[]{123}, gen.DROP_LABEL); + gen.addJumpIfBytesAtR0NotEqual(new byte[]{123}, DROP_LABEL); assertDrop(gen, packet123, 0); gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1); - gen.addJumpIfBytesAtR0NotEqual(new byte[]{1, 2, 30, 4, 5}, gen.DROP_LABEL); + gen.addJumpIfBytesAtR0NotEqual(new byte[]{1, 2, 30, 4, 5}, DROP_LABEL); byte[] packet12345 = {0,1,2,3,4,5,0,0,0,0,0,0,0,0,0}; assertDrop(gen, packet12345, 0); gen = new ApfV4Generator(MIN_APF_VERSION); gen.addLoadImmediate(R0, 1); - gen.addJumpIfBytesAtR0NotEqual(new byte[]{1, 2, 3, 4, 5}, gen.DROP_LABEL); + gen.addJumpIfBytesAtR0NotEqual(new byte[]{1, 2, 3, 4, 5}, DROP_LABEL); assertPass(gen, packet12345, 0); } @@ -807,7 +811,7 @@ ApfV4Generator gen = new ApfV4Generator(APF_VERSION_4); gen.addLoadImmediate(R1, 1000); gen.addLoadData(R0, -1006); // 1000 + -1006 = -6 (offset +10 with data_len=16) - gen.addJumpIfR0Equals(0x87654321, gen.DROP_LABEL); + gen.addJumpIfR0Equals(0x87654321, DROP_LABEL); byte[] program = gen.generate(); byte[] packet = new byte[MIN_PKT_SIZE]; @@ -863,35 +867,35 @@ ApfV4Generator gen = new ApfV4Generator(APF_VERSION_4); gen.addLoadImmediate(R0, 3); gen.addLoadData(R1, 7); - gen.addJump(gen.DROP_LABEL); + gen.addJump(DROP_LABEL); assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data); // Same program as before, but this time we're trying to load past the end of the data. gen = new ApfV4Generator(APF_VERSION_4); gen.addLoadImmediate(R0, 20); gen.addLoadData(R1, 15); // 20 + 15 > 32 - gen.addJump(gen.DROP_LABEL); // Not reached. + gen.addJump(DROP_LABEL); // Not reached. assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data); // Subtracting an immediate should work... gen = new ApfV4Generator(APF_VERSION_4); gen.addLoadImmediate(R0, 20); gen.addLoadData(R1, -4); - gen.addJump(gen.DROP_LABEL); + gen.addJump(DROP_LABEL); assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data); // ...and underflowing simply wraps around to the end of the buffer... gen = new ApfV4Generator(APF_VERSION_4); gen.addLoadImmediate(R0, 20); gen.addLoadData(R1, -30); - gen.addJump(gen.DROP_LABEL); + gen.addJump(DROP_LABEL); assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data); // ...but doesn't allow accesses before the start of the buffer gen = new ApfV4Generator(APF_VERSION_4); gen.addLoadImmediate(R0, 20); gen.addLoadData(R1, -1000); - gen.addJump(gen.DROP_LABEL); // Not reached. + gen.addJump(DROP_LABEL); // Not reached. assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data); } @@ -3401,4 +3405,157 @@ public void testNoMetricsWrittenForShortDuration_LegacyApfFilter() throws Exception { verifyNoMetricsWrittenForShortDuration(true /* isLegacy */); } -} + + @Test + public void testFullApfV4ProgramGeneration() throws IllegalInstructionException { + ApfV4Generator gen = new ApfV4Generator(APF_VERSION_4); + gen.addLoadImmediate(R1, -4); + gen.addLoadData(R0, 0); + gen.addAdd(1); + gen.addStoreData(R0, 0); + gen.addLoad16(R0, 12); + gen.addLoadImmediate(R1, -108); + gen.addJumpIfR0LessThan(0x600, "LABEL_504"); + gen.addLoadImmediate(R1, -112); + gen.addJumpIfR0Equals(0x88a2, "LABEL_504"); + gen.addJumpIfR0Equals(0x88a4, "LABEL_504"); + gen.addJumpIfR0Equals(0x88b8, "LABEL_504"); + gen.addJumpIfR0Equals(0x88cd, "LABEL_504"); + gen.addJumpIfR0Equals(0x88e1, "LABEL_504"); + gen.addJumpIfR0Equals(0x88e3, "LABEL_504"); + gen.addJumpIfR0NotEquals(0x806, "LABEL_116"); + gen.addLoadImmediate(R0, 14); + gen.addLoadImmediate(R1, -36); + gen.addJumpIfBytesAtR0NotEqual(hexStringToByteArray("000108000604"), "LABEL_498"); + gen.addLoad16(R0, 20); + gen.addJumpIfR0Equals(0x1, "LABEL_102"); + gen.addLoadImmediate(R1, -40); + gen.addJumpIfR0NotEquals(0x2, "LABEL_498"); + gen.addLoad32(R0, 28); + gen.addLoadImmediate(R1, -116); + gen.addJumpIfR0Equals(0x0, "LABEL_504"); + gen.addLoadImmediate(R0, 0); + gen.addLoadImmediate(R1, -44); + gen.addJumpIfBytesAtR0NotEqual(hexStringToByteArray("ffffffffffff"), "LABEL_498"); + + gen.defineLabel("LABEL_102"); + gen.addLoad32(R0, 38); + gen.addLoadImmediate(R1, -64); + gen.addJumpIfR0Equals(0x0, "LABEL_504"); + gen.addLoadImmediate(R1, -8); + gen.addJump("LABEL_498"); + + gen.defineLabel("LABEL_116"); + gen.addLoad16(R0, 12); + gen.addJumpIfR0NotEquals(0x800, "LABEL_207"); + gen.addLoad8(R0, 23); + gen.addJumpIfR0NotEquals(0x11, "LABEL_159"); + gen.addLoad16(R0, 20); + gen.addJumpIfR0AnyBitsSet(0x1fff, "LABEL_159"); + gen.addLoadFromMemory(R1, 13); + gen.addLoad16Indexed(R0, 16); + gen.addJumpIfR0NotEquals(0x44, "LABEL_159"); + gen.addLoadImmediate(R0, 50); + gen.addAddR1(); + gen.addJumpIfBytesAtR0NotEqual(hexStringToByteArray("e212507c6345"), "LABEL_159"); + gen.addLoadImmediate(R1, -12); + gen.addJump("LABEL_498"); + + gen.defineLabel("LABEL_159"); + gen.addLoad8(R0, 30); + gen.addAnd(240); + gen.addLoadImmediate(R1, -84); + gen.addJumpIfR0Equals(0xe0, "LABEL_504"); + gen.addLoadImmediate(R1, -76); + gen.addLoad32(R0, 30); + gen.addJumpIfR0Equals(0xffffffff, "LABEL_504"); + gen.addLoadImmediate(R1, -24); + gen.addLoadImmediate(R0, 0); + gen.addJumpIfBytesAtR0NotEqual(hexStringToByteArray("ffffffffffff"), "LABEL_498"); + gen.addLoadImmediate(R1, -72); + gen.addJump("LABEL_504"); + gen.addLoadImmediate(R1, -16); + gen.addJump("LABEL_498"); + + gen.defineLabel("LABEL_207"); + gen.addJumpIfR0Equals(0x86dd, "LABEL_231"); + gen.addLoadImmediate(R0, 0); + gen.addLoadImmediate(R1, -48); + gen.addJumpIfBytesAtR0NotEqual(hexStringToByteArray("ffffffffffff"), "LABEL_498"); + gen.addLoadImmediate(R1, -56); + gen.addJump("LABEL_504"); + + gen.defineLabel("LABEL_231"); + gen.addLoad8(R0, 20); + gen.addJumpIfR0Equals(0x3a, "LABEL_249"); + gen.addLoadImmediate(R1, -104); + gen.addLoad8(R0, 38); + gen.addJumpIfR0Equals(0xff, "LABEL_504"); + gen.addLoadImmediate(R1, -32); + gen.addJump("LABEL_498"); + + gen.defineLabel("LABEL_249"); + gen.addLoad8(R0, 54); + gen.addLoadImmediate(R1, -88); + gen.addJumpIfR0Equals(0x85, "LABEL_504"); + gen.addJumpIfR0NotEquals(0x88, "LABEL_283"); + gen.addLoadImmediate(R0, 38); + gen.addJumpIfBytesAtR0NotEqual(hexStringToByteArray("ff0200000000000000000000000000"), "LABEL_283"); + gen.addLoadImmediate(R1, -92); + gen.addJump("LABEL_504"); + + gen.defineLabel("LABEL_283"); + gen.addLoadFromMemory(R0, 14); + gen.addJumpIfR0NotEquals(0xa6, "LABEL_496"); + gen.addLoadFromMemory(R0, 15); + gen.addJumpIfR0GreaterThan(0x254, "LABEL_496"); + gen.addLoadImmediate(R0, 0); + gen.addJumpIfBytesAtR0NotEqual(hexStringToByteArray("e212507c6345648788fd6df086dd68"), "LABEL_496"); + gen.addLoadImmediate(R0, 18); + gen.addJumpIfBytesAtR0NotEqual(hexStringToByteArray("00703afffe800000000000002a0079e10abc1539fe80000000000000e01250fffe7c63458600"), "LABEL_496"); + gen.addLoadImmediate(R0, 58); + gen.addJumpIfBytesAtR0NotEqual(hexStringToByteArray("4000"), "LABEL_496"); + gen.addLoad16(R0, 60); + gen.addJumpIfR0LessThan(0x254, "LABEL_496"); + gen.addLoadImmediate(R0, 62); + gen.addJumpIfBytesAtR0NotEqual(hexStringToByteArray("0000000000000000"), "LABEL_496"); + gen.addLoadImmediate(R0, 78); + gen.addJumpIfBytesAtR0NotEqual(hexStringToByteArray("19050000"), "LABEL_496"); + gen.addLoad32(R0, 82); + gen.addJumpIfR0LessThan(0x254, "LABEL_496"); + gen.addLoadImmediate(R0, 86); + gen.addJumpIfBytesAtR0NotEqual(hexStringToByteArray("2001486048600000000000000000646420014860486000000000000000000064"), "LABEL_496"); + gen.addLoadImmediate(R0, 118); + gen.addJumpIfBytesAtR0NotEqual(hexStringToByteArray("030440c0"), "LABEL_496"); + gen.addLoad32(R0, 122); + gen.addJumpIfR0LessThan(0x254, "LABEL_496"); + gen.addLoad32(R0, 126); + gen.addJumpIfR0LessThan(0x254, "LABEL_496"); + gen.addLoadImmediate(R0, 130); + gen.addJumpIfBytesAtR0NotEqual(hexStringToByteArray("00000000"), "LABEL_496"); + gen.addLoadImmediate(R0, 134); + gen.addJumpIfBytesAtR0NotEqual(hexStringToByteArray("2a0079e10abc15390000000000000000"), "LABEL_496"); + gen.addLoadImmediate(R1, -60); + gen.addJump("LABEL_504"); + + gen.defineLabel("LABEL_496"); + gen.addLoadImmediate(R1, -28); + + gen.defineLabel("LABEL_498"); + gen.addLoadData(R0, 0); + gen.addAdd(1); + gen.addStoreData(R0, 0); + gen.addJump(PASS_LABEL); + + gen.defineLabel("LABEL_504"); + gen.addLoadData(R0, 0); + gen.addAdd(1); + gen.addStoreData(R0, 0); + gen.addJump(DROP_LABEL); + + byte[] program = gen.generate(); + final String programString = toHexString(program).toLowerCase(); + final String referenceProgramHexString = "6bfcb03a01b8120c6b949401e906006b907c01e288a27c01dd88a47c01d888b87c01d388cd7c01ce88e17c01c988e384004008066a0e6bdca401af000600010800060412147a1e016bd88401a300021a1c6b8c7c01a00000686bd4a4018c0006ffffffffffff1a266bc07c018900006bf874017e120c84005408000a17821f1112149c00181fffab0d2a108211446a3239a20506e212507c63456bf47401530a1e52f06bac7c014e00e06bb41a1e7e00000141ffffffff6be868a4012d0006ffffffffffff6bb874012e6bf07401237c001386dd686bd0a401100006ffffffffffff6bc87401110a147a0d3a6b980a267c010300ff6be072f90a366ba87af8858218886a26a2040fff02000000000000000000000000006ba472ddaa0e82d0a6aa0f8c00c9025468a2b60fe212507c6345648788fd6df086dd686a12a28b2600703afffe800000000000002a0079e10abc1539fe80000000000000e01250fffe7c634586006a3aa284024000123c94007d02546a3ea2700800000000000000006a4ea26704190500001a5294006002546a56a23b2020014860486000000000000000006464200148604860000000000000000000646a76a23204030440c01a7a94002b02541a7e94002402546c0082a21a04000000006c0086a204102a0079e10abc153900000000000000006bc472086be4b03a01b87206b03a01b87201"; + assertEquals(referenceProgramHexString, programString); + } +} \ No newline at end of file