diff options
author | Yuyang Huang <yuyanghuang@google.com> | 2023-10-10 17:07:08 +0900 |
---|---|---|
committer | Yuyang Huang <yuyanghuang@google.com> | 2023-10-13 16:26:49 +0900 |
commit | ebbf60d82b6c466af599a6c2af59b46a916d158b (patch) | |
tree | d50b79d0bcb61b3d0a3c845dcac3b093a58199c9 | |
parent | 178ebe0278d3b20e8993a17e3e7962c553a62ed3 (diff) | |
download | apf-ebbf60d82b6c466af599a6c2af59b46a916d158b.tar.gz |
Support TRANS opcode
The TRANS opcode will trigger the call to apf_transmit_buffer() to
actually transmit the packet. The APF program will continue to execute
without waiting the packet transmit to be finished.
Bug: 293811969
Test: TH
Change-Id: I4150d7b087591f59b9b1f619f7309dc56d85062d
-rw-r--r-- | v5/apf.h | 5 | ||||
-rw-r--r-- | v5/apf_interpreter.c | 23 |
2 files changed, 28 insertions, 0 deletions
@@ -124,6 +124,10 @@ // Number of temporary memory slots, see ldm/stm instructions. #define MEMORY_ITEMS 16 // Upon program execution, some temporary memory slots are prefilled: + +// Offset inside the output buffer where the next byte of output packet should +// be written to. +#define MEMORY_OFFSET_OUTPUT_BUFFER_OFFSET 10 #define MEMORY_OFFSET_PROGRAM_SIZE 11 // Size of program (in bytes) #define MEMORY_OFFSET_DATA_SIZE 12 // Total size of program + data #define MEMORY_OFFSET_IPV4_HEADER_SIZE 13 // 4*([APF_FRAME_HEADER_SIZE]&15) @@ -166,6 +170,7 @@ #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 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 cfb69e2..3cef719 100644 --- a/v5/apf_interpreter.c +++ b/v5/apf_interpreter.c @@ -70,6 +70,7 @@ int apf_run(uint8_t* program, uint32_t program_len, uint32_t ram_len, // Memory slot values. uint32_t memory[MEMORY_ITEMS] = {}; // Fill in pre-filled memory slot values. + memory[MEMORY_OFFSET_OUTPUT_BUFFER_OFFSET] = 0; memory[MEMORY_OFFSET_PROGRAM_SIZE] = program_len; memory[MEMORY_OFFSET_DATA_SIZE] = ram_len; memory[MEMORY_OFFSET_PACKET_SIZE] = packet_len; @@ -280,9 +281,31 @@ int apf_run(uint8_t* program, uint32_t program_len, uint32_t ram_len, REG = OTHER_REG; break; case ALLOC_EXT_OPCODE: + ASSERT_RETURN(allocated_buffer == NULL); allocate_buffer_len = REG; allocated_buffer = apf_allocate_buffer(allocate_buffer_len); ASSERT_RETURN(allocated_buffer != NULL); + memory[MEMORY_OFFSET_OUTPUT_BUFFER_OFFSET] = 0; + break; + case TRANS_EXT_OPCODE: + ASSERT_RETURN(allocated_buffer != NULL); + uint32_t pkt_len = + memory[MEMORY_OFFSET_OUTPUT_BUFFER_OFFSET]; + // If pkt_len > allocate_buffer_len, it means sth. wrong + // happened and the allocated_buffer should be deallocated. + if (pkt_len > allocate_buffer_len) { + apf_transmit_buffer( + allocated_buffer, + 0 /* len */, + 0 /* dscp */); + return PASS_PACKET; + } + // TODO: calculate packet checksum and get dscp + apf_transmit_buffer( + allocated_buffer, + pkt_len, + 0 /* dscp */); + allocated_buffer = NULL; break; // Unknown extended opcode default: |