Skip to content

Program type BPF_PROG_TYPE_LWT_IN

v4.10

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 incoming 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 destination utilized by the packet thus allowing to extend the existing realms.
  • Apply additional per route/destination filters to prohibit certain outgoing or incoming packets based on BPF filters. In particular, this allows to maintain per destination 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 encapsulate 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
Field Read Write
len
pkt_type
mark
queue_mapping
protocol
vlan_present
vlan_tci
vlan_proto
priority
ingress_ifindex
ifindex
tc_index
cb
hash
tc_classid
data
data_end
napi_id
family
remote_ip4
local_ip4
remote_ip4
remote_ip6
local_ip6
remote_port
local_port
data_meta
flow_keys
tstamp
wire_len
gso_segs
sk
gso_size
tstamp_type
hwtstamp

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

KFuncs

Supported kfuncs