mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	bpf, docs: Move legacy packet instructions to a separate file
Move legacy packet instructions to a separate file. Signed-off-by: Dave Thaler <dthaler@microsoft.com> Link: https://lore.kernel.org/r/20220927185958.14995-1-dthaler1968@googlemail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
		
							parent
							
								
									5ee35abb46
								
							
						
					
					
						commit
						6166da0a02
					
				
					 2 changed files with 68 additions and 35 deletions
				
			
		| 
						 | 
				
			
			@ -282,8 +282,6 @@ arithmetic operations in the imm field to encode the atomic operation:
 | 
			
		|||
 | 
			
		||||
  *(u64 *)(dst_reg + off16) += src_reg
 | 
			
		||||
 | 
			
		||||
``BPF_XADD`` is a deprecated name for ``BPF_ATOMIC | BPF_ADD``.
 | 
			
		||||
 | 
			
		||||
In addition to the simple atomic operations, there also is a modifier and
 | 
			
		||||
two complex atomic operations:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -331,36 +329,6 @@ There is currently only one such instruction.
 | 
			
		|||
Legacy BPF Packet access instructions
 | 
			
		||||
-------------------------------------
 | 
			
		||||
 | 
			
		||||
eBPF has special instructions for access to packet data that have been
 | 
			
		||||
carried over from classic BPF to retain the performance of legacy socket
 | 
			
		||||
filters running in the eBPF interpreter.
 | 
			
		||||
 | 
			
		||||
The instructions come in two forms: ``BPF_ABS | <size> | BPF_LD`` and
 | 
			
		||||
``BPF_IND | <size> | BPF_LD``.
 | 
			
		||||
 | 
			
		||||
These instructions are used to access packet data and can only be used when
 | 
			
		||||
the program context is a pointer to networking packet.  ``BPF_ABS``
 | 
			
		||||
accesses packet data at an absolute offset specified by the immediate data
 | 
			
		||||
and ``BPF_IND`` access packet data at an offset that includes the value of
 | 
			
		||||
a register in addition to the immediate data.
 | 
			
		||||
 | 
			
		||||
These instructions have seven implicit operands:
 | 
			
		||||
 | 
			
		||||
 * Register R6 is an implicit input that must contain pointer to a
 | 
			
		||||
   struct sk_buff.
 | 
			
		||||
 * Register R0 is an implicit output which contains the data fetched from
 | 
			
		||||
   the packet.
 | 
			
		||||
 * Registers R1-R5 are scratch registers that are clobbered after a call to
 | 
			
		||||
   ``BPF_ABS | BPF_LD`` or ``BPF_IND | BPF_LD`` instructions.
 | 
			
		||||
 | 
			
		||||
These instructions have an implicit program exit condition as well. When an
 | 
			
		||||
eBPF program is trying to access the data beyond the packet boundary, the
 | 
			
		||||
program execution will be aborted.
 | 
			
		||||
 | 
			
		||||
``BPF_ABS | BPF_W | BPF_LD`` means::
 | 
			
		||||
 | 
			
		||||
  R0 = ntohl(*(u32 *) (((struct sk_buff *) R6)->data + imm32))
 | 
			
		||||
 | 
			
		||||
``BPF_IND | BPF_W | BPF_LD`` means::
 | 
			
		||||
 | 
			
		||||
  R0 = ntohl(*(u32 *) (((struct sk_buff *) R6)->data + src_reg + imm32))
 | 
			
		||||
eBPF previously introduced special instructions for access to packet data that were
 | 
			
		||||
carried over from classic BPF. However, these instructions are
 | 
			
		||||
deprecated and should no longer be used.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										65
									
								
								Documentation/bpf/linux-notes.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								Documentation/bpf/linux-notes.rst
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,65 @@
 | 
			
		|||
.. contents::
 | 
			
		||||
.. sectnum::
 | 
			
		||||
 | 
			
		||||
==========================
 | 
			
		||||
Linux implementation notes
 | 
			
		||||
==========================
 | 
			
		||||
 | 
			
		||||
This document provides more details specific to the Linux kernel implementation of the eBPF instruction set.
 | 
			
		||||
 | 
			
		||||
Legacy BPF Packet access instructions
 | 
			
		||||
=====================================
 | 
			
		||||
 | 
			
		||||
As mentioned in the `ISA standard documentation <instruction-set.rst#legacy-bpf-packet-access-instructions>`_,
 | 
			
		||||
Linux has special eBPF instructions for access to packet data that have been
 | 
			
		||||
carried over from classic BPF to retain the performance of legacy socket
 | 
			
		||||
filters running in the eBPF interpreter.
 | 
			
		||||
 | 
			
		||||
The instructions come in two forms: ``BPF_ABS | <size> | BPF_LD`` and
 | 
			
		||||
``BPF_IND | <size> | BPF_LD``.
 | 
			
		||||
 | 
			
		||||
These instructions are used to access packet data and can only be used when
 | 
			
		||||
the program context is a pointer to a networking packet.  ``BPF_ABS``
 | 
			
		||||
accesses packet data at an absolute offset specified by the immediate data
 | 
			
		||||
and ``BPF_IND`` access packet data at an offset that includes the value of
 | 
			
		||||
a register in addition to the immediate data.
 | 
			
		||||
 | 
			
		||||
These instructions have seven implicit operands:
 | 
			
		||||
 | 
			
		||||
* Register R6 is an implicit input that must contain a pointer to a
 | 
			
		||||
  struct sk_buff.
 | 
			
		||||
* Register R0 is an implicit output which contains the data fetched from
 | 
			
		||||
  the packet.
 | 
			
		||||
* Registers R1-R5 are scratch registers that are clobbered by the
 | 
			
		||||
  instruction.
 | 
			
		||||
 | 
			
		||||
These instructions have an implicit program exit condition as well. If an
 | 
			
		||||
eBPF program attempts access data beyond the packet boundary, the
 | 
			
		||||
program execution will be aborted.
 | 
			
		||||
 | 
			
		||||
``BPF_ABS | BPF_W | BPF_LD`` (0x20) means::
 | 
			
		||||
 | 
			
		||||
  R0 = ntohl(*(u32 *) ((struct sk_buff *) R6->data + imm))
 | 
			
		||||
 | 
			
		||||
where ``ntohl()`` converts a 32-bit value from network byte order to host byte order.
 | 
			
		||||
 | 
			
		||||
``BPF_IND | BPF_W | BPF_LD`` (0x40) means::
 | 
			
		||||
 | 
			
		||||
  R0 = ntohl(*(u32 *) ((struct sk_buff *) R6->data + src + imm))
 | 
			
		||||
 | 
			
		||||
Appendix
 | 
			
		||||
========
 | 
			
		||||
 | 
			
		||||
For reference, the following table lists legacy Linux-specific opcodes in order by value.
 | 
			
		||||
 | 
			
		||||
======  ====  ===================================================  =============
 | 
			
		||||
opcode  imm   description                                          reference
 | 
			
		||||
======  ====  ===================================================  =============
 | 
			
		||||
0x20    any   dst = ntohl(\*(uint32_t \*)(R6->data + imm))         `Legacy BPF Packet access instructions`_
 | 
			
		||||
0x28    any   dst = ntohs(\*(uint16_t \*)(R6->data + imm))         `Legacy BPF Packet access instructions`_
 | 
			
		||||
0x30    any   dst = (\*(uint8_t \*)(R6->data + imm))               `Legacy BPF Packet access instructions`_
 | 
			
		||||
0x38    any   dst = ntohll(\*(uint64_t \*)(R6->data + imm))        `Legacy BPF Packet access instructions`_
 | 
			
		||||
0x40    any   dst = ntohl(\*(uint32_t \*)(R6->data + src + imm))   `Legacy BPF Packet access instructions`_
 | 
			
		||||
0x48    any   dst = ntohs(\*(uint16_t \*)(R6->data + src + imm))   `Legacy BPF Packet access instructions`_
 | 
			
		||||
0x50    any   dst = \*(uint8_t \*)(R6->data + src + imm))          `Legacy BPF Packet access instructions`_
 | 
			
		||||
0x58    any   dst = ntohll(\*(uint64_t \*)(R6->data + src + imm))  `Legacy BPF Packet access instructions`_
 | 
			
		||||
		Loading…
	
		Reference in a new issue