Program type BPF_PROG_TYPE_CGROUP_SOCK
cGroup socket programs are attached to cGroups and triggered when sockets are created, released or bound by a process in the cGroup.
Usage
cGroup socket programs are invoked when a socket is created, released or bound depending on the attach type which can be one of the following:
BPF_CGROUP_INET_SOCK_CREATE
BPF_CGROUP_INET_SOCK_RELEASE
BPF_CGROUP_INET4_POST_BIND
BPF_CGROUP_INET6_POST_BIND
The ELF sections typically used for the respective attach types are:
cgroup/sock_create
cgroup/sock_release
cgroup/post_bind4
cgroup/post_bind6
All attach types can be used for monitoring. The create and release attach types can modify the bound_dev_if
, mark
and priority
fields, the rest of the attach types can only read the fields. Lastly, all attach types can block the operation by returning 0
, returning 1
allows the operation to proceed.
Context
The context for cGroup socket programs is a struct bpf_sock
.
C structure
struct bpf_sock {
__u32 bound_dev_if;
__u32 family;
__u32 type;
__u32 protocol;
__u32 mark;
__u32 priority;
/* IP address also allows 1 and 2 bytes access */
__u32 src_ip4;
__u32 src_ip6[4];
__u32 src_port; /* host byte order */
__be16 dst_port; /* network byte order */
__u16 :16; /* zero padding */
__u32 dst_ip4;
__u32 dst_ip6[4];
__u32 state;
__s32 rx_queue_mapping;
};
bound_dev_if
This field contains the device index of the network device the socket is bound to. BPF_CGROUP_INET_SOCK_CREATE
and BPF_CGROUP_INET_SOCK_RELEASE
attached programs can modify this field.
family
This field contains the address family of the socket. Its value is one of AF_*
values defined in include/linux/socket.h
.
type
This field contains the socket type. Its value is one of SOCK_*
values defined in include/linux/net.h
.
protocol
This field contains the socket protocol. Its value is one of IPPROTO_*
values defined in include/uapi/linux/in.h
.
mark
This field contains the socket mark. BPF_CGROUP_INET_SOCK_CREATE
and BPF_CGROUP_INET_SOCK_RELEASE
attached programs can modify this field.
priority
This field contains the socket priority. BPF_CGROUP_INET_SOCK_CREATE
and BPF_CGROUP_INET_SOCK_RELEASE
attached programs can modify this field.
src_ip4
This field contains the source IPv4 address of the socket. BPF_CGROUP_INET4_POST_BIND
and BPF_CGROUP_INET6_POST_BIND
attached programs can read this field. Other attach types are not allowed to read or write this field.
src_ip6
This field contains the source IPv6 address of the socket. BPF_CGROUP_INET4_POST_BIND
and BPF_CGROUP_INET6_POST_BIND
attached programs can read this field. Other attach types are not allowed to read or write this field.
src_port
This field contains the source port of the socket. BPF_CGROUP_INET4_POST_BIND
and BPF_CGROUP_INET6_POST_BIND
attached programs can read this field. Other attach types are not allowed to read or write this field.
dst_port
This field contains the destination port of the socket. BPF_CGROUP_INET4_POST_BIND
and BPF_CGROUP_INET6_POST_BIND
attached programs can read this field. Other attach types are not allowed to read or write this field.
dst_ip4
This field contains the destination IPv4 address of the socket. BPF_CGROUP_INET4_POST_BIND
and BPF_CGROUP_INET6_POST_BIND
attached programs can read this field. Other attach types are not allowed to read or write this field.
dst_ip6
This field contains the destination IPv6 address of the socket. BPF_CGROUP_INET4_POST_BIND
and BPF_CGROUP_INET6_POST_BIND
attached programs can read this field. Other attach types are not allowed to read or write this field.
state
This field contains the connection state of the socket.
The states will be one of:
enum {
BPF_TCP_ESTABLISHED = 1,
BPF_TCP_SYN_SENT,
BPF_TCP_SYN_RECV,
BPF_TCP_FIN_WAIT1,
BPF_TCP_FIN_WAIT2,
BPF_TCP_TIME_WAIT,
BPF_TCP_CLOSE,
BPF_TCP_CLOSE_WAIT,
BPF_TCP_LAST_ACK,
BPF_TCP_LISTEN,
BPF_TCP_CLOSING, /* Now a valid state */
BPF_TCP_NEW_SYN_RECV
};
rx_queue_mapping
This field contains the receive queue number for the connection. The Rx queue
is marked in tcp_finish_connect()
and is otherwise -1
.
Attachment
cGroup socket buffer programs are attached to cGroups via the BPF_PROG_ATTACH
syscall or via BPF link.
Example
Example BPF program:
// SPDX-License-Identifier: GPL-2.0-only
#include <sys/socket.h>
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
int invocations = 0, in_use = 0;
struct {
__uint(type, BPF_MAP_TYPE_SK_STORAGE);
__uint(map_flags, BPF_F_NO_PREALLOC);
__type(key, int);
__type(value, int);
} sk_map SEC(".maps");
SEC("cgroup/sock_create")
int sock(struct bpf_sock *ctx)
{
int *sk_storage;
if (ctx->type != SOCK_DGRAM)
return 1;
sk_storage = bpf_sk_storage_get(&sk_map, ctx, 0,
BPF_SK_STORAGE_GET_F_CREATE);
if (!sk_storage)
return 0;
*sk_storage = 0xdeadbeef;
__sync_fetch_and_add(&invocations, 1);
if (in_use > 0) {
/* BPF_CGROUP_INET_SOCK_RELEASE is _not_ called
* when we return an error from the BPF
* program!
*/
return 0;
}
__sync_fetch_and_add(&in_use, 1);
return 1;
}
SEC("cgroup/sock_release")
int sock_release(struct bpf_sock *ctx)
{
int *sk_storage;
if (ctx->type != SOCK_DGRAM)
return 1;
sk_storage = bpf_sk_storage_get(&sk_map, ctx, 0, 0);
if (!sk_storage || *sk_storage != 0xdeadbeef)
return 0;
__sync_fetch_and_add(&invocations, 1);
__sync_fetch_and_add(&in_use, -1);
return 1;
}
Helper functions
Supported helper functions
bpf_get_current_uid_gid
bpf_get_local_storage
bpf_get_socket_cookie
bpf_get_netns_cookie
bpf_perf_event_output
bpf_get_current_pid_tgid
bpf_get_current_comm
bpf_get_current_cgroup_id
bpf_get_current_ancestor_cgroup_id
bpf_get_cgroup_classid
bpf_sk_storage_get
bpf_ktime_get_coarse_ns
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
bpf_cgrp_storage_get
bpf_cgrp_storage_delete
bpf_dynptr_data
bpf_dynptr_from_mem
bpf_dynptr_read
bpf_dynptr_write
bpf_kptr_xchg
bpf_ktime_get_tai_ns
bpf_ringbuf_discard_dynptr
bpf_ringbuf_reserve_dynptr
bpf_ringbuf_submit_dynptr
bpf_user_ringbuf_drain
KFuncs
There are currently no kfuncs supported for this program type