Program type BPF_PROG_TYPE_LWT_IN
LWT (Light Weight Tunnel) Input programs attach to the ingress path of a light weight tunnel.
Usage
This program type can be attached to route, the program will be called for incomming packets from said route. For example
ip route add 192.168.253.2/32 encap bpf in 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.
This input variant of the LWT programs can read the packet and make a PASS/DROP decision but it isn't allowed to modify the packet.
After v5.1 the LWT input program can encpasulate the packet with the bpf_lwt_push_encap
helper function and the BPF_LWT_ENCAP_IP
mode.
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 in obj {elf file}.o section {prog section} dev veth0
Example
Example
/* Copyright (c) 2016 Thomas Graf <tgraf@tgraf.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
struct {
__uint(type, BPF_MAP_TYPE_PERCPU_HASH);
__type(key, u64);
__type(value, u64);
__uint(pinning, LIBBPF_PIN_BY_NAME);
__uint(max_entries, 1024);
} lwt_len_hist_map SEC(".maps");
static unsigned int log2(unsigned int v)
{
unsigned int r;
unsigned int shift;
r = (v > 0xFFFF) << 4; v >>= r;
shift = (v > 0xFF) << 3; v >>= shift; r |= shift;
shift = (v > 0xF) << 2; v >>= shift; r |= shift;
shift = (v > 0x3) << 1; v >>= shift; r |= shift;
r |= (v >> 1);
return r;
}
static unsigned int log2l(unsigned long v)
{
unsigned int hi = v >> 32;
if (hi)
return log2(hi) + 32;
else
return log2(v);
}
SEC("len_hist")
int do_len_hist(struct __sk_buff *skb)
{
__u64 *value, key, init_val = 1;
key = log2l(skb->len);
value = bpf_map_lookup_elem(&lwt_len_hist_map, &key);
if (value)
__sync_fetch_and_add(value, 1);
else
bpf_map_update_elem(&lwt_len_hist_map, &key, &init_val, BPF_ANY);
return BPF_OK;
}
char _license[] SEC("license") = "GPL";`
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_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