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