162306a36Sopenharmony_ci.. contents:: 262306a36Sopenharmony_ci.. sectnum:: 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci========================== 562306a36Sopenharmony_ciLinux implementation notes 662306a36Sopenharmony_ci========================== 762306a36Sopenharmony_ci 862306a36Sopenharmony_ciThis document provides more details specific to the Linux kernel implementation of the eBPF instruction set. 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ciByte swap instructions 1162306a36Sopenharmony_ci====================== 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci``BPF_FROM_LE`` and ``BPF_FROM_BE`` exist as aliases for ``BPF_TO_LE`` and ``BPF_TO_BE`` respectively. 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ciJump instructions 1662306a36Sopenharmony_ci================= 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci``BPF_CALL | BPF_X | BPF_JMP`` (0x8d), where the helper function 1962306a36Sopenharmony_ciinteger would be read from a specified register, is not currently supported 2062306a36Sopenharmony_ciby the verifier. Any programs with this instruction will fail to load 2162306a36Sopenharmony_ciuntil such support is added. 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ciMaps 2462306a36Sopenharmony_ci==== 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ciLinux only supports the 'map_val(map)' operation on array maps with a single element. 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ciLinux uses an fd_array to store maps associated with a BPF program. Thus, 2962306a36Sopenharmony_cimap_by_idx(imm) uses the fd at that index in the array. 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ciVariables 3262306a36Sopenharmony_ci========= 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ciThe following 64-bit immediate instruction specifies that a variable address, 3562306a36Sopenharmony_ciwhich corresponds to some integer stored in the 'imm' field, should be loaded: 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci========================= ====== === ========================================= =========== ============== 3862306a36Sopenharmony_ciopcode construction opcode src pseudocode imm type dst type 3962306a36Sopenharmony_ci========================= ====== === ========================================= =========== ============== 4062306a36Sopenharmony_ciBPF_IMM | BPF_DW | BPF_LD 0x18 0x3 dst = var_addr(imm) variable id data pointer 4162306a36Sopenharmony_ci========================= ====== === ========================================= =========== ============== 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ciOn Linux, this integer is a BTF ID. 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ciLegacy BPF Packet access instructions 4662306a36Sopenharmony_ci===================================== 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ciAs mentioned in the `ISA standard documentation 4962306a36Sopenharmony_ci<instruction-set.html#legacy-bpf-packet-access-instructions>`_, 5062306a36Sopenharmony_ciLinux has special eBPF instructions for access to packet data that have been 5162306a36Sopenharmony_cicarried over from classic BPF to retain the performance of legacy socket 5262306a36Sopenharmony_cifilters running in the eBPF interpreter. 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ciThe instructions come in two forms: ``BPF_ABS | <size> | BPF_LD`` and 5562306a36Sopenharmony_ci``BPF_IND | <size> | BPF_LD``. 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ciThese instructions are used to access packet data and can only be used when 5862306a36Sopenharmony_cithe program context is a pointer to a networking packet. ``BPF_ABS`` 5962306a36Sopenharmony_ciaccesses packet data at an absolute offset specified by the immediate data 6062306a36Sopenharmony_ciand ``BPF_IND`` access packet data at an offset that includes the value of 6162306a36Sopenharmony_cia register in addition to the immediate data. 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ciThese instructions have seven implicit operands: 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci* Register R6 is an implicit input that must contain a pointer to a 6662306a36Sopenharmony_ci struct sk_buff. 6762306a36Sopenharmony_ci* Register R0 is an implicit output which contains the data fetched from 6862306a36Sopenharmony_ci the packet. 6962306a36Sopenharmony_ci* Registers R1-R5 are scratch registers that are clobbered by the 7062306a36Sopenharmony_ci instruction. 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ciThese instructions have an implicit program exit condition as well. If an 7362306a36Sopenharmony_cieBPF program attempts access data beyond the packet boundary, the 7462306a36Sopenharmony_ciprogram execution will be aborted. 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci``BPF_ABS | BPF_W | BPF_LD`` (0x20) means:: 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci R0 = ntohl(*(u32 *) ((struct sk_buff *) R6->data + imm)) 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ciwhere ``ntohl()`` converts a 32-bit value from network byte order to host byte order. 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci``BPF_IND | BPF_W | BPF_LD`` (0x40) means:: 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci R0 = ntohl(*(u32 *) ((struct sk_buff *) R6->data + src + imm)) 85