Skip to content

Program type BPF_PROG_TYPE_CGROUP_SOCK

v4.10

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

v4.10

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

v4.10

This field contains the address family of the socket. Its value is one of AF_* values defined in include/linux/socket.h.

type

v4.10

This field contains the socket type. Its value is one of SOCK_* values defined in include/linux/net.h.

protocol

v4.10

This field contains the socket protocol. Its value is one of IPPROTO_* values defined in include/uapi/linux/in.h.

mark

v4.14

This field contains the socket mark. BPF_CGROUP_INET_SOCK_CREATE and BPF_CGROUP_INET_SOCK_RELEASE attached programs can modify this field.

priority

v4.14

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

v5.1

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

v5.1

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

v5.1

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

v5.1

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

v5.1

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

v5.1

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

v5.1

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

v5.8

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

KFuncs

There are currently no kfuncs supported for this program type