Program type BPF_PROG_TYPE_LWT_XMIT
Extension programs can be used to dynamically extend another BPF program.
Usage
This program type can be attached to route, the program will be called when transmitting to said route. For example
ip route add 192.168.253.2/32 encap bpf out obj {elf file}.o section {prog section} dev veth0
The initial use cases listed for this program type are:
- Collect statistics and generate sampling data for a subset of traffic based on the dst utilized by the packet thus allowing to extend the existing realms.
- Apply additional per route/dst filters to prohibit certain outgoing or incoming packets based on BPF filters. In particular, this allows to maintain per dst custom state across multiple packets in BPF maps and apply filters based on statistics and behaviour observed over time.
- Attachment of L2 headers at transmit where resolving the L2 address is not required.
LWT xmit programs are called after the IP header has been assembled and thus it can safely modify the packet. The program can also prepend a L2 header to the packet using the bpf_skb_change_head
helper function.
Context
Socket SKB programs are called by the kernel with a __sk_buff context.
This program type isn't allowed to read from and write to all fields of the context since doing so might break assumptions in the kernel or because data isn't available at the point where the program is hooked into the kernel.
Context fields
Attachment
This program type can only be attached via netlink or commands such as ip
from (iproute2) which use netlink under the hood:
ip route add 192.168.253.2/32 encap bpf xmit obj {elf file}.o section {prog section} dev veth0
Example
Docs could be improved
This part of the docs is incomplete, contributions are very welcome
Helper functions
Not all helper functions are available in all program types. These are the helper calls available for LWT programs:
Supported helper functions
- bpf_skb_get_tunnel_key
- bpf_skb_set_tunnel_key
- bpf_skb_get_tunnel_opt
- bpf_skb_set_tunnel_opt
- bpf_redirect
- bpf_clone_redirect
- bpf_skb_change_tail
- bpf_skb_change_head
- bpf_skb_store_bytes
- bpf_csum_update
- bpf_csum_level
- bpf_l3_csum_replace
- bpf_l4_csum_replace
- bpf_set_hash_invalid
- bpf_lwt_push_encap
- bpf_skb_load_bytes
- bpf_skb_pull_data
- bpf_csum_diff
- bpf_get_cgroup_classid
- bpf_get_route_realm
- bpf_get_hash_recalc
- bpf_perf_event_output
- bpf_get_smp_processor_id
- bpf_skb_under_cgroup
- bpf_map_lookup_elem
- bpf_map_update_elem
- bpf_map_delete_elem
- bpf_map_push_elem
- bpf_map_pop_elem
- bpf_map_peek_elem
- bpf_map_lookup_percpu_elem
- bpf_get_prandom_u32
- bpf_get_smp_processor_id
- bpf_get_numa_node_id
- bpf_tail_call
- bpf_ktime_get_ns
- bpf_ktime_get_boot_ns
- bpf_ringbuf_output
- bpf_ringbuf_reserve
- bpf_ringbuf_submit
- bpf_ringbuf_discard
- bpf_ringbuf_query
- bpf_for_each_map_elem
- bpf_loop
- bpf_strncmp
- bpf_spin_lock
- bpf_spin_unlock
- bpf_jiffies64
- bpf_per_cpu_ptr
- bpf_this_cpu_ptr
- bpf_timer_init
- bpf_timer_set_callback
- bpf_timer_start
- bpf_timer_cancel
- bpf_trace_printk
- bpf_get_current_task
- bpf_get_current_task_btf
- bpf_probe_read_user
- bpf_probe_read_kernel
- bpf_probe_read_user_str
- bpf_probe_read_kernel_str
- bpf_snprintf_btf
- bpf_snprintf
- bpf_task_pt_regs
- bpf_trace_vprintk
KFuncs
Supported kfuncs
- bpf_cast_to_kern_ctx
- bpf_dynptr_adjust
- bpf_dynptr_clone
- bpf_dynptr_from_skb
- bpf_dynptr_is_null
- bpf_dynptr_is_rdonly
- bpf_dynptr_size
- bpf_dynptr_slice
- bpf_dynptr_slice_rdwr
- bpf_iter_css_destroy
- bpf_iter_css_new
- bpf_iter_css_next
- bpf_iter_css_task_destroy
- bpf_iter_css_task_new
- bpf_iter_css_task_next
- bpf_iter_num_destroy
- bpf_iter_num_new
- bpf_iter_num_next
- bpf_iter_task_destroy
- bpf_iter_task_new
- bpf_iter_task_next
- bpf_iter_task_vma_destroy
- bpf_iter_task_vma_new
- bpf_iter_task_vma_next
- bpf_map_sum_elem_count
- bpf_rcu_read_lock
- bpf_rcu_read_unlock
- bpf_rdonly_cast