v5: update apf.h to match the latest design
Test: TH
Change-Id: Ifafe36ed62b3d6381bae56ee8ba59e27d4348e6c
diff --git a/disassembler.c b/disassembler.c
index 7e5678f..0845592 100644
--- a/disassembler.c
+++ b/disassembler.c
@@ -345,7 +345,7 @@
ASSERT_RET_INBOUND(ret);
offset += ret;
break;
- case ALLOC_EXT_OPCODE:
+ case ALLOCATE_EXT_OPCODE:
ret = print_opcode("alloc", output_buffer,
output_buffer_len, offset);
ASSERT_RET_INBOUND(ret);
@@ -356,7 +356,7 @@
ASSERT_RET_INBOUND(ret);
offset += ret;
break;
- case TRANS_EXT_OPCODE:
+ case TRANSMIT_EXT_OPCODE:
ret = print_opcode("trans", output_buffer,
output_buffer_len, offset);
ASSERT_RET_INBOUND(ret);
@@ -381,9 +381,9 @@
offset += ret;
break;
}
- case EDATACOPY:
- case EPKTCOPY: {
- if (imm == EPKTCOPY) {
+ case EDATACOPY_EXT_OPCODE:
+ case EPKTCOPY_EXT_OPCODE: {
+ if (imm == EPKTCOPY_EXT_OPCODE) {
ret = print_opcode("pcopy", output_buffer,
output_buffer_len, offset);
} else {
@@ -463,7 +463,7 @@
}
break;
}
- case MEMCOPY_OPCODE: {
+ case PKTDATACOPY_OPCODE: {
if (reg_num == 0) {
ret = print_opcode("pcopy", output_buffer, output_buffer_len,
offset);
diff --git a/v5/apf.h b/v5/apf.h
index 77c950a..bd7cb1f 100644
--- a/v5/apf.h
+++ b/v5/apf.h
@@ -134,7 +134,17 @@
#define MEMORY_OFFSET_PACKET_SIZE 14 // Size of packet in bytes.
#define MEMORY_OFFSET_FILTER_AGE 15 // Age since filter installed in seconds.
-// Leave 0 opcode unused as it's a good indicator of accidental incorrect execution (e.g. data).
+
+/* Unconditionally pass (if R=0) or drop (if R=1) packet.
+ * An optional unsigned immediate value can be provided to encode the counter number.
+ * 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".
+ */
+#define PASS_OPCODE 0
+#define DROP_OPCODE 0
#define LDB_OPCODE 1 // Load 1 byte from immediate offset, e.g. "ldb R0, [5]"
#define LDH_OPCODE 2 // Load 2 bytes from immediate offset, e.g. "ldh R0, [5]"
#define LDW_OPCODE 3 // Load 4 bytes from immediate offset, e.g. "ldw R0, [5]"
@@ -158,13 +168,19 @@
#define EXT_OPCODE 21 // Immediate value is one of *_EXT_OPCODE
#define LDDW_OPCODE 22 // Load 4 bytes from data address (register + simm): "lddw R0, [5+R1]"
#define STDW_OPCODE 23 // Store 4 bytes to data address (register + simm): "stdw R0, [5+R1]"
-#define WRITE_OPCODE 24 // Write 1, 2 or 4 bytes imm to the output buffer, e.g. "WRITE 5"
-/* Copy the data from input packet or APF data region to output buffer. Register bit is
- * used to specify the source of data copy: R=0 means copy from packet, R=1 means copy
- * from APF data region. The source offset is encoded in the first imm and the copy length
- * is encoded in the second imm. "e.g. MEMCOPY(R=0), 5, 5"
+/* Write 1, 2 or 4 bytes immediate to the output buffer and auto-increment the pointer to
+ * write. e.g. "write 5"
*/
-#define MEMCOPY_OPCODE 25
+#define WRITE_OPCODE 24
+/* Copy bytes from input packet/APF program/data region to output buffer and
+ * auto-increment the output buffer pointer.
+ * Register bit is used to specify the source of data copy.
+ * R=0 means copy from packet.
+ * R=1 means copy from APF program/data region.
+ * The copy length is stored in (u8)imm2.
+ * e.g. "pktcopy 5, 5" "datacopy 5, 5"
+ */
+#define PKTDATACOPY_OPCODE 25
// Extended opcodes. These all have an opcode of EXT_OPCODE
// and specify the actual opcode in the immediate field.
@@ -176,17 +192,37 @@
#define NEG_EXT_OPCODE 33 // Negate, e.g. "neg R0"
#define SWAP_EXT_OPCODE 34 // Swap, e.g. "swap R0,R1"
#define MOV_EXT_OPCODE 35 // Move, e.g. "move R0,R1"
-#define ALLOC_EXT_OPCODE 36 // Allocate buffer, "e.g. ALLOC R0"
-#define TRANS_EXT_OPCODE 37 // Transmit buffer, "e.g. TRANS R0"
-#define EWRITE1_EXT_OPCODE 38 // Write 1 byte from register to the output buffer, e.g. "EWRITE1 R0"
-#define EWRITE2_EXT_OPCODE 39 // Write 2 bytes from register to the output buffer, e.g. "EWRITE2 R0"
-#define EWRITE4_EXT_OPCODE 40 // Write 4 bytes from register to the output buffer, e.g. "EWRITE4 R0"
-// Copy the data from input packet to output buffer. The source offset is encoded as [Rx + second imm].
-// The copy length is encoded in the third imm. "e.g. EPKTCOPY [R0 + 5], 5"
-#define EPKTCOPY 41
-// Copy the data from APF data region to output buffer. The source offset is encoded as [Rx + second imm].
-// The copy length is encoded in the third imm. "e.g. EDATACOPY [R0 + 5], 5"
-#define EDATACOPY 42
+
+
+/* Allocate writable output buffer.
+ * R=0, use register R0 to store the length. R=1, encode the length in the u16 int imm2.
+ * "e.g. allocate R0"
+ * "e.g. allocate 123"
+ */
+#define ALLOCATE_EXT_OPCODE 36
+/* Transmit and deallocate the buffer (transmission can be delayed until the program
+ * terminates). R=0 means discard the buffer, R=1 means transmit the buffer.
+ * "e.g. trans"
+ * "e.g. discard"
+ */
+#define TRANSMIT_EXT_OPCODE 37
+#define DISCARD_EXT_OPCODE 37
+/* Write 1, 2 or 4 byte value from register to the output buffer and auto-increment the
+ * output buffer pointer.
+ * e.g. "ewrite1 r0"
+ */
+#define EWRITE1_EXT_OPCODE 38
+#define EWRITE2_EXT_OPCODE 39
+#define EWRITE4_EXT_OPCODE 40
+/* Copy bytes from input packet/APF program/data region to output buffer and
+ * auto-increment the output buffer pointer.
+ * The copy src offset is stored in R0.
+ * when R=0, the copy length is stored in (u8)imm2.
+ * when R=1, the copy length is stored in R1.
+ * e.g. "pktcopy r0, 5", "pktcopy r0, r1", "datacopy r0, 5", "datacopy r0, r1"
+ */
+#define EPKTCOPY_EXT_OPCODE 41
+#define EDATACOPY_EXT_OPCODE 42
/* Jumps if the UDP payload content (starting at R0) does not contain the specified QNAME,
* applying MDNS case insensitivity.
* R0: Offset to UDP payload content
@@ -197,6 +233,17 @@
* e.g.: "jdnsqmatch R0,label,0x0c,\002aa\005local\0\0"
*/
#define JDNSQMATCH_EXT_OPCODE 43
+/* Jumps if the UDP payload content (starting at R0) does not contain one
+ * of the specified NAMEs in answers/authority/additional records, applying
+ * case insensitivity.
+ * R=0/1 meaning 'does not match'/'matches'
+ * R0: Offset to UDP payload content
+ * imm1: Opcode
+ * imm2: Label offset
+ * imm3(bytes): TLV-encoded QNAME list (null-terminated)
+ * e.g.: "jdnsamatch R0,label,0x0c,\002aa\005local\0\0"
+ */
+#define JDNSAMATCH_EXT_OPCODE 44
#define EXTRACT_OPCODE(i) (((i) >> 3) & 31)
#define EXTRACT_REGISTER(i) ((i) & 1)
diff --git a/v5/apf_interpreter.c b/v5/apf_interpreter.c
index 09f623d..a92138f 100644
--- a/v5/apf_interpreter.c
+++ b/v5/apf_interpreter.c
@@ -156,7 +156,17 @@
#define MEMORY_OFFSET_PACKET_SIZE 14 /* Size of packet in bytes. */
#define MEMORY_OFFSET_FILTER_AGE 15 /* Age since filter installed in seconds. */
-/* Leave 0 opcode unused as it's a good indicator of accidental incorrect execution (e.g. data). */
+
+/* Unconditionally pass (if R=0) or drop (if R=1) packet.
+ * An optional unsigned immediate value can be provided to encode the counter number.
+ * 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".
+ */
+#define PASS_OPCODE 0
+#define DROP_OPCODE 0
#define LDB_OPCODE 1 /* Load 1 byte from immediate offset, e.g. "ldb R0, [5]" */
#define LDH_OPCODE 2 /* Load 2 bytes from immediate offset, e.g. "ldh R0, [5]" */
#define LDW_OPCODE 3 /* Load 4 bytes from immediate offset, e.g. "ldw R0, [5]" */
@@ -180,13 +190,19 @@
#define EXT_OPCODE 21 /* Immediate value is one of *_EXT_OPCODE */
#define LDDW_OPCODE 22 /* Load 4 bytes from data address (register + simm): "lddw R0, [5+R1]" */
#define STDW_OPCODE 23 /* Store 4 bytes to data address (register + simm): "stdw R0, [5+R1]" */
-#define WRITE_OPCODE 24 /* Write 1, 2 or 4 bytes imm to the output buffer, e.g. "WRITE 5" */
-/* Copy the data from input packet or APF data region to output buffer. Register bit is
- * used to specify the source of data copy: R=0 means copy from packet, R=1 means copy
- * from APF data region. The source offset is encoded in the first imm and the copy length
- * is encoded in the second imm. "e.g. MEMCOPY(R=0), 5, 5"
+/* Write 1, 2 or 4 bytes immediate to the output buffer and auto-increment the pointer to
+ * write. e.g. "write 5"
*/
-#define MEMCOPY_OPCODE 25
+#define WRITE_OPCODE 24
+/* Copy bytes from input packet/APF program/data region to output buffer and
+ * auto-increment the output buffer pointer.
+ * Register bit is used to specify the source of data copy.
+ * R=0 means copy from packet.
+ * R=1 means copy from APF program/data region.
+ * The copy length is stored in (u8)imm2.
+ * e.g. "pktcopy 5, 5" "datacopy 5, 5"
+ */
+#define PKTDATACOPY_OPCODE 25
/* Extended opcodes. These all have an opcode of EXT_OPCODE */
/* and specify the actual opcode in the immediate field. */
@@ -198,17 +214,37 @@
#define NEG_EXT_OPCODE 33 /* Negate, e.g. "neg R0" */
#define SWAP_EXT_OPCODE 34 /* Swap, e.g. "swap R0,R1" */
#define MOV_EXT_OPCODE 35 /* Move, e.g. "move R0,R1" */
-#define ALLOC_EXT_OPCODE 36 /* Allocate buffer, "e.g. ALLOC R0" */
-#define TRANS_EXT_OPCODE 37 /* Transmit buffer, "e.g. TRANS R0" */
-#define EWRITE1_EXT_OPCODE 38 /* Write 1 byte from register to the output buffer, e.g. "EWRITE1 R0" */
-#define EWRITE2_EXT_OPCODE 39 /* Write 2 bytes from register to the output buffer, e.g. "EWRITE2 R0" */
-#define EWRITE4_EXT_OPCODE 40 /* Write 4 bytes from register to the output buffer, e.g. "EWRITE4 R0" */
-/* Copy the data from input packet to output buffer. The source offset is encoded as [Rx + second imm]. */
-/* The copy length is encoded in the third imm. "e.g. EPKTCOPY [R0 + 5], 5" */
-#define EPKTCOPY 41
-/* Copy the data from APF data region to output buffer. The source offset is encoded as [Rx + second imm]. */
-/* The copy length is encoded in the third imm. "e.g. EDATACOPY [R0 + 5], 5" */
-#define EDATACOPY 42
+
+
+/* Allocate writable output buffer.
+ * R=0, use register R0 to store the length. R=1, encode the length in the u16 int imm2.
+ * "e.g. allocate R0"
+ * "e.g. allocate 123"
+ */
+#define ALLOCATE_EXT_OPCODE 36
+/* Transmit and deallocate the buffer (transmission can be delayed until the program
+ * terminates). R=0 means discard the buffer, R=1 means transmit the buffer.
+ * "e.g. trans"
+ * "e.g. discard"
+ */
+#define TRANSMIT_EXT_OPCODE 37
+#define DISCARD_EXT_OPCODE 37
+/* Write 1, 2 or 4 byte value from register to the output buffer and auto-increment the
+ * output buffer pointer.
+ * e.g. "ewrite1 r0"
+ */
+#define EWRITE1_EXT_OPCODE 38
+#define EWRITE2_EXT_OPCODE 39
+#define EWRITE4_EXT_OPCODE 40
+/* Copy bytes from input packet/APF program/data region to output buffer and
+ * auto-increment the output buffer pointer.
+ * The copy src offset is stored in R0.
+ * when R=0, the copy length is stored in (u8)imm2.
+ * when R=1, the copy length is stored in R1.
+ * e.g. "pktcopy r0, 5", "pktcopy r0, r1", "datacopy r0, 5", "datacopy r0, r1"
+ */
+#define EPKTCOPY_EXT_OPCODE 41
+#define EDATACOPY_EXT_OPCODE 42
/* Jumps if the UDP payload content (starting at R0) does not contain the specified QNAME,
* applying MDNS case insensitivity.
* R0: Offset to UDP payload content
@@ -219,6 +255,17 @@
* e.g.: "jdnsqmatch R0,label,0x0c,\002aa\005local\0\0"
*/
#define JDNSQMATCH_EXT_OPCODE 43
+/* Jumps if the UDP payload content (starting at R0) does not contain one
+ * of the specified NAMEs in answers/authority/additional records, applying
+ * case insensitivity.
+ * R=0/1 meaning 'does not match'/'matches'
+ * R0: Offset to UDP payload content
+ * imm1: Opcode
+ * imm2: Label offset
+ * imm3(bytes): TLV-encoded QNAME list (null-terminated)
+ * e.g.: "jdnsamatch R0,label,0x0c,\002aa\005local\0\0"
+ */
+#define JDNSAMATCH_EXT_OPCODE 44
#define EXTRACT_OPCODE(i) (((i) >> 3) & 31)
#define EXTRACT_REGISTER(i) ((i) & 1)
@@ -748,7 +795,7 @@
OTHER_REG = tmp;
break;
}
- case ALLOC_EXT_OPCODE:
+ case ALLOCATE_EXT_OPCODE:
ASSERT_RETURN(allocated_buffer == NULL);
if (reg_num == 0) {
allocated_buffer_len = REG;
@@ -761,7 +808,7 @@
ASSERT_RETURN(allocated_buffer != NULL);
memory[MEMORY_OFFSET_OUTPUT_BUFFER_OFFSET] = 0;
break;
- case TRANS_EXT_OPCODE:
+ case TRANSMIT_EXT_OPCODE:
ASSERT_RETURN(allocated_buffer != NULL);
u32 pkt_len = memory[MEMORY_OFFSET_OUTPUT_BUFFER_OFFSET];
/* If pkt_len > allocate_buffer_len, it means sth. wrong */
@@ -854,7 +901,7 @@
memory[MEMORY_OFFSET_OUTPUT_BUFFER_OFFSET] = offs;
break;
}
- case MEMCOPY_OPCODE: {
+ case PKTDATACOPY_OPCODE: {
ASSERT_RETURN(allocated_buffer != NULL);
u32 src_offs = imm;
u32 copy_len;
diff --git a/v5/apf_interpreter_source.c b/v5/apf_interpreter_source.c
index 2bbd551..523f90f 100644
--- a/v5/apf_interpreter_source.c
+++ b/v5/apf_interpreter_source.c
@@ -281,7 +281,7 @@
OTHER_REG = tmp;
break;
}
- case ALLOC_EXT_OPCODE:
+ case ALLOCATE_EXT_OPCODE:
ASSERT_RETURN(allocated_buffer == NULL);
if (reg_num == 0) {
allocated_buffer_len = REG;
@@ -294,7 +294,7 @@
ASSERT_RETURN(allocated_buffer != NULL);
memory[MEMORY_OFFSET_OUTPUT_BUFFER_OFFSET] = 0;
break;
- case TRANS_EXT_OPCODE:
+ case TRANSMIT_EXT_OPCODE:
ASSERT_RETURN(allocated_buffer != NULL);
u32 pkt_len = memory[MEMORY_OFFSET_OUTPUT_BUFFER_OFFSET];
// If pkt_len > allocate_buffer_len, it means sth. wrong
@@ -387,7 +387,7 @@
memory[MEMORY_OFFSET_OUTPUT_BUFFER_OFFSET] = offs;
break;
}
- case MEMCOPY_OPCODE: {
+ case PKTDATACOPY_OPCODE: {
ASSERT_RETURN(allocated_buffer != NULL);
u32 src_offs = imm;
u32 copy_len;