| 1 | .. contents::
|
| 2 | .. sectnum::
|
| 3 |
|
| 4 | ==========================
|
| 5 | Linux implementation notes
|
| 6 | ==========================
|
| 7 |
|
| 8 | This document provides more details specific to the Linux kernel implementation of the eBPF instruction set.
|
| 9 |
|
| 10 | Byte swap instructions
|
| 11 | ======================
|
| 12 |
|
| 13 | ``BPF_FROM_LE`` and ``BPF_FROM_BE`` exist as aliases for ``BPF_TO_LE`` and ``BPF_TO_BE`` respectively.
|
| 14 |
|
| 15 | Jump instructions
|
| 16 | =================
|
| 17 |
|
| 18 | ``BPF_CALL | BPF_X | BPF_JMP`` (0x8d), where the helper function
|
| 19 | integer would be read from a specified register, is not currently supported
|
| 20 | by the verifier. Any programs with this instruction will fail to load
|
| 21 | until such support is added.
|
| 22 |
|
| 23 | Maps
|
| 24 | ====
|
| 25 |
|
| 26 | Linux only supports the 'map_val(map)' operation on array maps with a single element.
|
| 27 |
|
| 28 | Linux uses an fd_array to store maps associated with a BPF program. Thus,
|
| 29 | map_by_idx(imm) uses the fd at that index in the array.
|
| 30 |
|
| 31 | Variables
|
| 32 | =========
|
| 33 |
|
| 34 | The following 64-bit immediate instruction specifies that a variable address,
|
| 35 | which corresponds to some integer stored in the 'imm' field, should be loaded:
|
| 36 |
|
| 37 | ========================= ====== === ========================================= =========== ==============
|
| 38 | opcode construction opcode src pseudocode imm type dst type
|
| 39 | ========================= ====== === ========================================= =========== ==============
|
| 40 | BPF_IMM | BPF_DW | BPF_LD 0x18 0x3 dst = var_addr(imm) variable id data pointer
|
| 41 | ========================= ====== === ========================================= =========== ==============
|
| 42 |
|
| 43 | On Linux, this integer is a BTF ID.
|
| 44 |
|
| 45 | Legacy BPF Packet access instructions
|
| 46 | =====================================
|
| 47 |
|
| 48 | As mentioned in the `ISA standard documentation
|
| 49 | <instruction-set.html#legacy-bpf-packet-access-instructions>`_,
|
| 50 | Linux has special eBPF instructions for access to packet data that have been
|
| 51 | carried over from classic BPF to retain the performance of legacy socket
|
| 52 | filters running in the eBPF interpreter.
|
| 53 |
|
| 54 | The instructions come in two forms: ``BPF_ABS | <size> | BPF_LD`` and
|
| 55 | ``BPF_IND | <size> | BPF_LD``.
|
| 56 |
|
| 57 | These instructions are used to access packet data and can only be used when
|
| 58 | the program context is a pointer to a networking packet. ``BPF_ABS``
|
| 59 | accesses packet data at an absolute offset specified by the immediate data
|
| 60 | and ``BPF_IND`` access packet data at an offset that includes the value of
|
| 61 | a register in addition to the immediate data.
|
| 62 |
|
| 63 | These instructions have seven implicit operands:
|
| 64 |
|
| 65 | * Register R6 is an implicit input that must contain a pointer to a
|
| 66 | struct sk_buff.
|
| 67 | * Register R0 is an implicit output which contains the data fetched from
|
| 68 | the packet.
|
| 69 | * Registers R1-R5 are scratch registers that are clobbered by the
|
| 70 | instruction.
|
| 71 |
|
| 72 | These instructions have an implicit program exit condition as well. If an
|
| 73 | eBPF program attempts access data beyond the packet boundary, the
|
| 74 | program execution will be aborted.
|
| 75 |
|
| 76 | ``BPF_ABS | BPF_W | BPF_LD`` (0x20) means::
|
| 77 |
|
| 78 | R0 = ntohl(*(u32 *) ((struct sk_buff *) R6->data + imm))
|
| 79 |
|
| 80 | where ``ntohl()`` converts a 32-bit value from network byte order to host byte order.
|
| 81 |
|
| 82 | ``BPF_IND | BPF_W | BPF_LD`` (0x40) means::
|
| 83 |
|
| 84 | R0 = ntohl(*(u32 *) ((struct sk_buff *) R6->data + src + imm))
|