blob: b1667a3b88f594e24554c4d8fd239761dc3d2cba [file] [log] [blame]
Yuyang Huangae57be02023-10-16 17:49:31 +09001/*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package android.net.apf
17
Yuyang Huangaf0d3722024-01-12 13:38:44 +090018import android.net.apf.ApfV4Generator.IllegalInstructionException
19import android.net.apf.ApfV4Generator.MIN_APF_VERSION
Yuyang Huangaf0d3722024-01-12 13:38:44 +090020import android.net.apf.ApfV4Generator.Register.R0
21import android.net.apf.ApfV4Generator.Register.R1
Yuyang Huangae57be02023-10-16 17:49:31 +090022import androidx.test.filters.SmallTest
23import androidx.test.runner.AndroidJUnit4
Yuyang Huang1e5bfaf2023-12-11 00:21:54 +090024import java.lang.IllegalArgumentException
Yuyang Huangae57be02023-10-16 17:49:31 +090025import kotlin.test.assertContentEquals
Yuyang Huangce1493a2023-12-07 15:29:40 +090026import kotlin.test.assertFailsWith
Yuyang Huangae57be02023-10-16 17:49:31 +090027import org.junit.Test
28import org.junit.runner.RunWith
29
30/**
31 * Tests for APFv6 specific instructions.
32 */
33@RunWith(AndroidJUnit4::class)
34@SmallTest
35class ApfV5Test {
36
37 @Test
Yuyang Huanga112cc82023-12-13 17:55:47 +090038 fun testDataInstructionMustComeFirst() {
Yuyang Huangd89cdbe2024-02-01 09:49:07 +090039 var gen = ApfV6Generator()
Yuyang Huanga112cc82023-12-13 17:55:47 +090040 gen.addAllocateR0()
41 assertFailsWith<IllegalInstructionException> { gen.addData(ByteArray(3) { 0x01 }) }
Yuyang Huang1e5bfaf2023-12-11 00:21:54 +090042 }
43
44 @Test
Yuyang Huang3ac843c2023-12-13 16:40:15 +090045 fun testApfInstructionEncodingSizeCheck() {
Yuyang Huangd89cdbe2024-02-01 09:49:07 +090046 var gen = ApfV6Generator()
Yuyang Huang3ac843c2023-12-13 16:40:15 +090047 assertFailsWith<IllegalArgumentException> { gen.addAllocate(65536) }
48 assertFailsWith<IllegalArgumentException> { gen.addAllocate(-1) }
Yuyang Huang293f7e72023-12-31 14:24:03 +090049 assertFailsWith<IllegalArgumentException> { gen.addDataCopy(-1, 1) }
50 assertFailsWith<IllegalArgumentException> { gen.addPacketCopy(-1, 1) }
51 assertFailsWith<IllegalArgumentException> { gen.addDataCopy(1, 256) }
52 assertFailsWith<IllegalArgumentException> { gen.addPacketCopy(1, 256) }
53 assertFailsWith<IllegalArgumentException> { gen.addDataCopy(1, -1) }
54 assertFailsWith<IllegalArgumentException> { gen.addPacketCopy(1, -1) }
Yuyang Huangd0390612024-01-01 16:21:16 +090055 assertFailsWith<IllegalArgumentException> { gen.addPacketCopyFromR0(256) }
56 assertFailsWith<IllegalArgumentException> { gen.addDataCopyFromR0(256) }
Yuyang Huang96697842024-01-02 21:53:48 +090057 assertFailsWith<IllegalArgumentException> { gen.addPacketCopyFromR0(-1) }
58 assertFailsWith<IllegalArgumentException> { gen.addDataCopyFromR0(-1) }
Yuyang Huanga01e0d72024-01-03 17:14:47 +090059 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsQ(
Yuyang Huangaf0d3722024-01-12 13:38:44 +090060 byteArrayOf(1, 'A'.code.toByte(), 0, 0), 256, ApfV4Generator.DROP_LABEL) }
Yuyang Huanga01e0d72024-01-03 17:14:47 +090061 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsQ(
Yuyang Huangaf0d3722024-01-12 13:38:44 +090062 byteArrayOf(1, 'a'.code.toByte(), 0, 0), 0x0c, ApfV4Generator.DROP_LABEL) }
Yuyang Huanga01e0d72024-01-03 17:14:47 +090063 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsQ(
Yuyang Huangaf0d3722024-01-12 13:38:44 +090064 byteArrayOf(1, '.'.code.toByte(), 0, 0), 0x0c, ApfV4Generator.DROP_LABEL) }
Yuyang Huanga01e0d72024-01-03 17:14:47 +090065 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsQ(
Yuyang Huangaf0d3722024-01-12 13:38:44 +090066 byteArrayOf(0, 0), 0xc0, ApfV4Generator.DROP_LABEL) }
Yuyang Huanga01e0d72024-01-03 17:14:47 +090067 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsQ(
Yuyang Huangaf0d3722024-01-12 13:38:44 +090068 byteArrayOf(1, 'A'.code.toByte()), 0xc0, ApfV4Generator.DROP_LABEL) }
Yuyang Huanga01e0d72024-01-03 17:14:47 +090069 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsQ(
70 byteArrayOf(64) + ByteArray(64) { 'A'.code.toByte() } + byteArrayOf(0, 0),
Yuyang Huangaf0d3722024-01-12 13:38:44 +090071 0xc0, ApfV4Generator.DROP_LABEL) }
Yuyang Huanga01e0d72024-01-03 17:14:47 +090072 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsQ(
73 byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte(), 0),
Yuyang Huangaf0d3722024-01-12 13:38:44 +090074 0xc0, ApfV4Generator.DROP_LABEL) }
Yuyang Huanga01e0d72024-01-03 17:14:47 +090075 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsQ(
76 byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte()),
Yuyang Huangaf0d3722024-01-12 13:38:44 +090077 0xc0, ApfV4Generator.DROP_LABEL) }
Yuyang Huanga01e0d72024-01-03 17:14:47 +090078 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsQ(
Yuyang Huangaf0d3722024-01-12 13:38:44 +090079 byteArrayOf(1, 'A'.code.toByte(), 0, 0), 256, ApfV4Generator.DROP_LABEL) }
Yuyang Huanga01e0d72024-01-03 17:14:47 +090080 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsQ(
Yuyang Huangaf0d3722024-01-12 13:38:44 +090081 byteArrayOf(1, 'a'.code.toByte(), 0, 0), 0x0c, ApfV4Generator.DROP_LABEL) }
Yuyang Huanga01e0d72024-01-03 17:14:47 +090082 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsQ(
Yuyang Huangaf0d3722024-01-12 13:38:44 +090083 byteArrayOf(1, '.'.code.toByte(), 0, 0), 0x0c, ApfV4Generator.DROP_LABEL) }
Yuyang Huanga01e0d72024-01-03 17:14:47 +090084 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsQ(
Yuyang Huangaf0d3722024-01-12 13:38:44 +090085 byteArrayOf(0, 0), 0xc0, ApfV4Generator.DROP_LABEL) }
Yuyang Huanga01e0d72024-01-03 17:14:47 +090086 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsQ(
Yuyang Huangaf0d3722024-01-12 13:38:44 +090087 byteArrayOf(1, 'A'.code.toByte()), 0xc0, ApfV4Generator.DROP_LABEL) }
Yuyang Huanga01e0d72024-01-03 17:14:47 +090088 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsQ(
89 byteArrayOf(64) + ByteArray(64) { 'A'.code.toByte() } + byteArrayOf(0, 0),
Yuyang Huangaf0d3722024-01-12 13:38:44 +090090 0xc0, ApfV4Generator.DROP_LABEL) }
Yuyang Huanga01e0d72024-01-03 17:14:47 +090091 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsQ(
92 byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte(), 0),
Yuyang Huangaf0d3722024-01-12 13:38:44 +090093 0xc0, ApfV4Generator.DROP_LABEL) }
Yuyang Huanga01e0d72024-01-03 17:14:47 +090094 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsQ(
95 byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte()),
Yuyang Huangaf0d3722024-01-12 13:38:44 +090096 0xc0, ApfV4Generator.DROP_LABEL) }
Yuyang Huangdd2d0d92024-01-06 12:01:31 +090097 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsA(
Yuyang Huangaf0d3722024-01-12 13:38:44 +090098 byteArrayOf(1, 'a'.code.toByte(), 0, 0), ApfV4Generator.DROP_LABEL) }
Yuyang Huangdd2d0d92024-01-06 12:01:31 +090099 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsA(
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900100 byteArrayOf(1, '.'.code.toByte(), 0, 0), ApfV4Generator.DROP_LABEL) }
Yuyang Huangdd2d0d92024-01-06 12:01:31 +0900101 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsA(
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900102 byteArrayOf(0, 0), ApfV4Generator.DROP_LABEL) }
Yuyang Huangdd2d0d92024-01-06 12:01:31 +0900103 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsA(
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900104 byteArrayOf(1, 'A'.code.toByte()), ApfV4Generator.DROP_LABEL) }
Yuyang Huangdd2d0d92024-01-06 12:01:31 +0900105 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsA(
106 byteArrayOf(64) + ByteArray(64) { 'A'.code.toByte() } + byteArrayOf(0, 0),
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900107 ApfV4Generator.DROP_LABEL) }
Yuyang Huangdd2d0d92024-01-06 12:01:31 +0900108 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsA(
109 byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte(), 0),
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900110 ApfV4Generator.DROP_LABEL) }
Yuyang Huangdd2d0d92024-01-06 12:01:31 +0900111 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsA(
112 byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte()),
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900113 ApfV4Generator.DROP_LABEL) }
Yuyang Huangdd2d0d92024-01-06 12:01:31 +0900114 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsA(
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900115 byteArrayOf(1, 'a'.code.toByte(), 0, 0), ApfV4Generator.DROP_LABEL) }
Yuyang Huangdd2d0d92024-01-06 12:01:31 +0900116 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsA(
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900117 byteArrayOf(1, '.'.code.toByte(), 0, 0), ApfV4Generator.DROP_LABEL) }
Yuyang Huangdd2d0d92024-01-06 12:01:31 +0900118 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsA(
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900119 byteArrayOf(0, 0), ApfV4Generator.DROP_LABEL) }
Yuyang Huangdd2d0d92024-01-06 12:01:31 +0900120 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsA(
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900121 byteArrayOf(1, 'A'.code.toByte()), ApfV4Generator.DROP_LABEL) }
Yuyang Huangdd2d0d92024-01-06 12:01:31 +0900122 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsA(
123 byteArrayOf(64) + ByteArray(64) { 'A'.code.toByte() } + byteArrayOf(0, 0),
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900124 ApfV4Generator.DROP_LABEL) }
Yuyang Huangdd2d0d92024-01-06 12:01:31 +0900125 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsA(
126 byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte(), 0),
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900127 ApfV4Generator.DROP_LABEL) }
Yuyang Huangdd2d0d92024-01-06 12:01:31 +0900128 assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsA(
129 byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte()),
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900130 ApfV4Generator.DROP_LABEL) }
Yuyang Huangce1493a2023-12-07 15:29:40 +0900131 }
132
133 @Test
Yuyang Huangae57be02023-10-16 17:49:31 +0900134 fun testApfInstructionsEncoding() {
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900135 var gen = ApfV4Generator(MIN_APF_VERSION)
Yuyang Huangdcdb4442023-12-07 14:56:21 +0900136 gen.addPass()
Yuyang Huangae57be02023-10-16 17:49:31 +0900137 var program = gen.generate()
Yuyang Huangdcdb4442023-12-07 14:56:21 +0900138 // encoding PASS opcode: opcode=0, imm_len=0, R=0
Yuyang Huang1e5bfaf2023-12-11 00:21:54 +0900139 assertContentEquals(
140 byteArrayOf(encodeInstruction(opcode = 0, immLength = 0, register = 0)), program)
Yuyang Huang98b99f22024-01-29 06:35:27 +0900141 assertContentEquals(
142 listOf("0: pass"),
143 ApfJniUtils.disassembleApf(program).map { it.trim() } )
Yuyang Huangdcdb4442023-12-07 14:56:21 +0900144
Yuyang Huangd89cdbe2024-02-01 09:49:07 +0900145 gen = ApfV6Generator()
Yuyang Huangce1493a2023-12-07 15:29:40 +0900146 gen.addDrop()
147 program = gen.generate()
148 // encoding DROP opcode: opcode=0, imm_len=0, R=1
Yuyang Huang1e5bfaf2023-12-11 00:21:54 +0900149 assertContentEquals(
150 byteArrayOf(encodeInstruction(opcode = 0, immLength = 0, register = 1)), program)
Yuyang Huang98b99f22024-01-29 06:35:27 +0900151 assertContentEquals(
152 listOf("0: drop"),
153 ApfJniUtils.disassembleApf(program).map { it.trim() } )
Yuyang Huang1e5bfaf2023-12-11 00:21:54 +0900154
Yuyang Huangd89cdbe2024-02-01 09:49:07 +0900155 gen = ApfV6Generator()
Yuyang Huang1e5bfaf2023-12-11 00:21:54 +0900156 gen.addCountAndPass(129)
157 program = gen.generate()
158 // encoding COUNT(PASS) opcode: opcode=0, imm_len=size_of(imm), R=0, imm=counterNumber
159 assertContentEquals(
160 byteArrayOf(encodeInstruction(opcode = 0, immLength = 1, register = 0),
161 0x81.toByte()), program)
Yuyang Huang98b99f22024-01-29 06:35:27 +0900162 assertContentEquals(
163 listOf("0: pass 129"),
164 ApfJniUtils.disassembleApf(program).map { it.trim() } )
Yuyang Huang1e5bfaf2023-12-11 00:21:54 +0900165
Yuyang Huangd89cdbe2024-02-01 09:49:07 +0900166 gen = ApfV6Generator()
Yuyang Huang1e5bfaf2023-12-11 00:21:54 +0900167 gen.addCountAndDrop(1000)
168 program = gen.generate()
169 // encoding COUNT(DROP) opcode: opcode=0, imm_len=size_of(imm), R=1, imm=counterNumber
170 assertContentEquals(
171 byteArrayOf(encodeInstruction(opcode = 0, immLength = 2, register = 1),
172 0x03, 0xe8.toByte()), program)
Yuyang Huang98b99f22024-01-29 06:35:27 +0900173 assertContentEquals(
174 listOf("0: drop 1000"),
175 ApfJniUtils.disassembleApf(program).map { it.trim() } )
Yuyang Huangce1493a2023-12-07 15:29:40 +0900176
Yuyang Huangd89cdbe2024-02-01 09:49:07 +0900177 gen = ApfV6Generator()
Yuyang Huang3ac843c2023-12-13 16:40:15 +0900178 gen.addAllocateR0()
179 gen.addAllocate(1500)
Yuyang Huangdcdb4442023-12-07 14:56:21 +0900180 program = gen.generate()
Yuyang Huang3ac843c2023-12-13 16:40:15 +0900181 // encoding ALLOC opcode: opcode=21(EXT opcode number), imm=36(TRANS opcode number).
182 // R=0 means length stored in R0. R=1 means the length stored in imm1.
183 assertContentEquals(byteArrayOf(
184 encodeInstruction(opcode = 21, immLength = 1, register = 0), 36,
185 encodeInstruction(opcode = 21, immLength = 1, register = 1), 36, 0x05,
186 0xDC.toByte()),
187 program)
Yuyang Huang626414e2024-01-29 06:52:57 +0900188 assertContentEquals(listOf("0: allocate r0", "2: allocate 1500"),
189 ApfJniUtils.disassembleApf(program).map { it.trim() })
Yuyang Huangae57be02023-10-16 17:49:31 +0900190
Yuyang Huangd89cdbe2024-02-01 09:49:07 +0900191 gen = ApfV6Generator()
Yuyang Huangfd74ce42023-12-12 20:10:45 +0900192 gen.addTransmit()
193 gen.addDiscard()
Yuyang Huangae57be02023-10-16 17:49:31 +0900194 program = gen.generate()
Yuyang Huangfd74ce42023-12-12 20:10:45 +0900195 // encoding TRANSMIT/DISCARD opcode: opcode=21(EXT opcode number),
196 // imm=37(TRANSMIT/DISCARD opcode number),
197 // R=0 means discard the buffer. R=1 means transmit the buffer.
198 assertContentEquals(byteArrayOf(
199 encodeInstruction(opcode = 21, immLength = 1, register = 0), 37,
200 encodeInstruction(opcode = 21, immLength = 1, register = 1), 37,
201 ), program)
Yuyang Huang39dbbce2024-01-29 07:15:48 +0900202 assertContentEquals(listOf("0: discard", "2: transmit"),
203 ApfJniUtils.disassembleApf(program).map { it.trim() })
Yuyang Huang73c6d2d2023-10-19 13:32:37 +0900204
Yuyang Huangd89cdbe2024-02-01 09:49:07 +0900205 gen = ApfV6Generator()
Yuyang Huanga112cc82023-12-13 17:55:47 +0900206 val largeByteArray = ByteArray(256) { 0x01 }
207 gen.addData(largeByteArray)
208 program = gen.generate()
209 // encoding DATA opcode: opcode=14(JMP), R=1
210 assertContentEquals(byteArrayOf(
211 encodeInstruction(opcode = 14, immLength = 2, register = 1), 0x01, 0x00) +
212 largeByteArray, program)
Yuyang Huangf97b28a2024-01-29 09:36:25 +0900213 assertContentEquals(listOf("0: data 256," + "01".repeat(256) ),
214 ApfJniUtils.disassembleApf(program).map { it.trim() })
Yuyang Huanga112cc82023-12-13 17:55:47 +0900215
Yuyang Huangd89cdbe2024-02-01 09:49:07 +0900216 gen = ApfV6Generator()
Yuyang Huangadf69672024-01-02 10:18:11 +0900217 gen.addWriteU8(0x01)
218 gen.addWriteU16(0x0102)
219 gen.addWriteU32(0x01020304)
220 gen.addWriteU8(0x00)
221 gen.addWriteU8(0x80)
222 gen.addWriteU16(0x0000)
223 gen.addWriteU16(0x8000)
224 gen.addWriteU32(0x00000000)
225 gen.addWriteU32(0x80000000)
Yuyang Huang4ac891f2023-12-20 11:49:11 +0900226 program = gen.generate()
227 assertContentEquals(byteArrayOf(
228 encodeInstruction(24, 1, 0), 0x01,
229 encodeInstruction(24, 2, 0), 0x01, 0x02,
230 encodeInstruction(24, 4, 0), 0x01, 0x02, 0x03, 0x04,
231 encodeInstruction(24, 1, 0), 0x00,
232 encodeInstruction(24, 1, 0), 0x80.toByte(),
233 encodeInstruction(24, 2, 0), 0x00, 0x00,
234 encodeInstruction(24, 2, 0), 0x80.toByte(), 0x00,
235 encodeInstruction(24, 4, 0), 0x00, 0x00, 0x00, 0x00,
236 encodeInstruction(24, 4, 0), 0x80.toByte(), 0x00, 0x00,
237 0x00), program)
Yuyang Huang7affd672024-01-29 13:04:43 +0900238 assertContentEquals(listOf(
239 "0: write 0x01",
240 "2: write 0x0102",
241 "5: write 0x01020304",
242 "10: write 0x00",
243 "12: write 0x80",
244 "14: write 0x0000",
245 "17: write 0x8000",
246 "20: write 0x00000000",
247 "25: write 0x80000000"
Yuyang Huang15b45782024-01-18 07:19:11 +0900248 ),
Yuyang Huang7affd672024-01-29 13:04:43 +0900249 ApfJniUtils.disassembleApf(program).map { it.trim() })
Yuyang Huange84a9692024-01-01 11:49:49 +0900250
Yuyang Huangd89cdbe2024-02-01 09:49:07 +0900251 gen = ApfV6Generator()
Yuyang Huange84a9692024-01-01 11:49:49 +0900252 gen.addWriteU8(R0)
253 gen.addWriteU16(R0)
254 gen.addWriteU32(R0)
255 gen.addWriteU8(R1)
256 gen.addWriteU16(R1)
257 gen.addWriteU32(R1)
258 program = gen.generate()
259 assertContentEquals(byteArrayOf(
260 encodeInstruction(21, 1, 0), 38,
261 encodeInstruction(21, 1, 0), 39,
262 encodeInstruction(21, 1, 0), 40,
263 encodeInstruction(21, 1, 1), 38,
264 encodeInstruction(21, 1, 1), 39,
265 encodeInstruction(21, 1, 1), 40
266 ), program)
Yuyang Huangf0b46cb2024-01-30 03:37:17 +0900267 assertContentEquals(listOf(
268 "0: ewrite1 r0",
269 "2: ewrite2 r0",
270 "4: ewrite4 r0",
271 "6: ewrite1 r1",
272 "8: ewrite2 r1",
273 "10: ewrite4 r1"), ApfJniUtils.disassembleApf(program).map { it.trim() })
Yuyang Huang73c6d2d2023-10-19 13:32:37 +0900274
Yuyang Huangd89cdbe2024-02-01 09:49:07 +0900275 gen = ApfV6Generator()
Yuyang Huang293f7e72023-12-31 14:24:03 +0900276 gen.addDataCopy(0, 10)
277 gen.addDataCopy(1, 5)
278 gen.addPacketCopy(1000, 255)
279 program = gen.generate()
280 assertContentEquals(byteArrayOf(
281 encodeInstruction(25, 0, 1), 10,
282 encodeInstruction(25, 1, 1), 1, 5,
283 encodeInstruction(25, 2, 0),
284 0x03.toByte(), 0xe8.toByte(), 0xff.toByte(),
285 ), program)
Yuyang Huange8003982024-01-30 04:06:18 +0900286 assertContentEquals(listOf(
287 "0: dcopy 0, 10",
288 "2: dcopy 1, 5",
289 "5: pcopy 1000, 255"), ApfJniUtils.disassembleApf(program).map { it.trim() })
Yuyang Huang293f7e72023-12-31 14:24:03 +0900290
Yuyang Huangd89cdbe2024-02-01 09:49:07 +0900291 gen = ApfV6Generator()
Yuyang Huangbed904a2024-01-30 11:22:49 +0900292 gen.addDataCopyFromR0(5)
Yuyang Huangd0390612024-01-01 16:21:16 +0900293 gen.addPacketCopyFromR0(5)
294 gen.addDataCopyFromR0LenR1()
Yuyang Huangbed904a2024-01-30 11:22:49 +0900295 gen.addPacketCopyFromR0LenR1()
Yuyang Huangd0390612024-01-01 16:21:16 +0900296 program = gen.generate()
297 assertContentEquals(byteArrayOf(
Yuyang Huangbed904a2024-01-30 11:22:49 +0900298 encodeInstruction(21, 1, 1), 41, 5,
Yuyang Huangd0390612024-01-01 16:21:16 +0900299 encodeInstruction(21, 1, 0), 41, 5,
300 encodeInstruction(21, 1, 1), 42,
Yuyang Huangbed904a2024-01-30 11:22:49 +0900301 encodeInstruction(21, 1, 0), 42,
Yuyang Huangd0390612024-01-01 16:21:16 +0900302 ), program)
Yuyang Huangbed904a2024-01-30 11:22:49 +0900303 assertContentEquals(listOf(
304 "0: edatacopy r0, 5",
305 "3: epktcopy r0, 5",
306 "6: edatacopy r0, r1",
307 "8: epktcopy r0, r1"), ApfJniUtils.disassembleApf(program).map{ it.trim() })
Yuyang Huang0f49d0a2024-01-04 19:14:22 +0900308
Yuyang Huangd89cdbe2024-02-01 09:49:07 +0900309 gen = ApfV6Generator()
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900310 gen.addJumpIfBytesAtR0Equal(byteArrayOf('a'.code.toByte()), ApfV4Generator.DROP_LABEL)
Yuyang Huang0f49d0a2024-01-04 19:14:22 +0900311 program = gen.generate()
312 assertContentEquals(
313 byteArrayOf(encodeInstruction(opcode = 20, immLength = 1, register = 1),
314 1, 1, 'a'.code.toByte()), program)
Yuyang Huangbffcf262024-02-04 07:52:48 +0900315 assertContentEquals(listOf(
316 "0: jebs r0, 0x1, DROP, 61"),
317 ApfJniUtils.disassembleApf(program).map{ it.trim() })
Yuyang Huanga01e0d72024-01-03 17:14:47 +0900318
319 val qnames = byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte(), 0, 0)
Yuyang Huangd89cdbe2024-02-01 09:49:07 +0900320 gen = ApfV6Generator()
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900321 gen.addJumpIfPktAtR0DoesNotContainDnsQ(qnames, 0x0c, ApfV4Generator.DROP_LABEL)
322 gen.addJumpIfPktAtR0ContainDnsQ(qnames, 0x0c, ApfV4Generator.DROP_LABEL)
Yuyang Huanga01e0d72024-01-03 17:14:47 +0900323 program = gen.generate()
324 assertContentEquals(byteArrayOf(
Yuyang Huang823351f2024-01-08 14:28:42 +0900325 encodeInstruction(21, 1, 0), 43, 11, 0x0c.toByte(),
Yuyang Huanga01e0d72024-01-03 17:14:47 +0900326 ) + qnames + byteArrayOf(
Yuyang Huang823351f2024-01-08 14:28:42 +0900327 encodeInstruction(21, 1, 1), 43, 1, 0x0c.toByte(),
Yuyang Huanga01e0d72024-01-03 17:14:47 +0900328 ) + qnames, program)
Yuyang Huang49ab8822024-02-04 09:39:00 +0900329 assertContentEquals(listOf(
330 "0: jdnsqne r0, DROP, 12, 014101420000",
331 "10: jdnsqeq r0, DROP, 12, 014101420000"),
332 ApfJniUtils.disassembleApf(program).map{ it.trim() })
Yuyang Huangdd2d0d92024-01-06 12:01:31 +0900333
Yuyang Huangd89cdbe2024-02-01 09:49:07 +0900334 gen = ApfV6Generator()
Yuyang Huangaf0d3722024-01-12 13:38:44 +0900335 gen.addJumpIfPktAtR0DoesNotContainDnsA(qnames, ApfV4Generator.DROP_LABEL)
336 gen.addJumpIfPktAtR0ContainDnsA(qnames, ApfV4Generator.DROP_LABEL)
Yuyang Huangdd2d0d92024-01-06 12:01:31 +0900337 program = gen.generate()
338 assertContentEquals(byteArrayOf(
339 encodeInstruction(21, 1, 0), 44, 10,
340 ) + qnames + byteArrayOf(
341 encodeInstruction(21, 1, 1), 44, 1,
342 ) + qnames, program)
Yuyang Huangae57be02023-10-16 17:49:31 +0900343 }
344
345 private fun encodeInstruction(opcode: Int, immLength: Int, register: Int): Byte {
Yuyang Huang73c6d2d2023-10-19 13:32:37 +0900346 val immLengthEncoding = if (immLength == 4) 3 else immLength
347 return opcode.shl(3).or(immLengthEncoding.shl(1)).or(register).toByte()
Yuyang Huangae57be02023-10-16 17:49:31 +0900348 }
Yuyang Huangae57be02023-10-16 17:49:31 +0900349}