Commit | Line | Data |
---|---|---|
f3212ad5 DH |
1 | .. SPDX-License-Identifier: GPL-2.0-only |
2 | .. Copyright (C) 2022 Red Hat, Inc. | |
3 | ||
4 | ======================= | |
5 | BPF_MAP_TYPE_SK_STORAGE | |
6 | ======================= | |
7 | ||
8 | .. note:: | |
9 | - ``BPF_MAP_TYPE_SK_STORAGE`` was introduced in kernel version 5.2 | |
10 | ||
11 | ``BPF_MAP_TYPE_SK_STORAGE`` is used to provide socket-local storage for BPF | |
12 | programs. A map of type ``BPF_MAP_TYPE_SK_STORAGE`` declares the type of storage | |
13 | to be provided and acts as the handle for accessing the socket-local | |
14 | storage. The values for maps of type ``BPF_MAP_TYPE_SK_STORAGE`` are stored | |
15 | locally with each socket instead of with the map. The kernel is responsible for | |
16 | allocating storage for a socket when requested and for freeing the storage when | |
17 | either the map or the socket is deleted. | |
18 | ||
19 | .. note:: | |
20 | - The key type must be ``int`` and ``max_entries`` must be set to ``0``. | |
21 | - The ``BPF_F_NO_PREALLOC`` flag must be used when creating a map for | |
22 | socket-local storage. | |
23 | ||
24 | Usage | |
25 | ===== | |
26 | ||
27 | Kernel BPF | |
28 | ---------- | |
29 | ||
30 | bpf_sk_storage_get() | |
31 | ~~~~~~~~~~~~~~~~~~~~ | |
32 | ||
33 | .. code-block:: c | |
34 | ||
35 | void *bpf_sk_storage_get(struct bpf_map *map, void *sk, void *value, u64 flags) | |
36 | ||
d2b497a9 DH |
37 | Socket-local storage for ``map`` can be retrieved from socket ``sk`` using the |
38 | ``bpf_sk_storage_get()`` helper. If the ``BPF_LOCAL_STORAGE_GET_F_CREATE`` | |
39 | flag is used then ``bpf_sk_storage_get()`` will create the storage for ``sk`` | |
40 | if it does not already exist. ``value`` can be used together with | |
41 | ``BPF_LOCAL_STORAGE_GET_F_CREATE`` to initialize the storage value, otherwise | |
42 | it will be zero initialized. Returns a pointer to the storage on success, or | |
f3212ad5 DH |
43 | ``NULL`` in case of failure. |
44 | ||
45 | .. note:: | |
46 | - ``sk`` is a kernel ``struct sock`` pointer for LSM or tracing programs. | |
47 | - ``sk`` is a ``struct bpf_sock`` pointer for other program types. | |
48 | ||
49 | bpf_sk_storage_delete() | |
50 | ~~~~~~~~~~~~~~~~~~~~~~~ | |
51 | ||
52 | .. code-block:: c | |
53 | ||
54 | long bpf_sk_storage_delete(struct bpf_map *map, void *sk) | |
55 | ||
d2b497a9 DH |
56 | Socket-local storage for ``map`` can be deleted from socket ``sk`` using the |
57 | ``bpf_sk_storage_delete()`` helper. Returns ``0`` on success, or negative | |
58 | error in case of failure. | |
f3212ad5 DH |
59 | |
60 | User space | |
61 | ---------- | |
62 | ||
63 | bpf_map_update_elem() | |
64 | ~~~~~~~~~~~~~~~~~~~~~ | |
65 | ||
66 | .. code-block:: c | |
67 | ||
68 | int bpf_map_update_elem(int map_fd, const void *key, const void *value, __u64 flags) | |
69 | ||
d2b497a9 DH |
70 | Socket-local storage for map ``map_fd`` can be added or updated locally to a |
71 | socket using the ``bpf_map_update_elem()`` libbpf function. The socket is | |
72 | identified by a `socket` ``fd`` stored in the pointer ``key``. The pointer | |
73 | ``value`` has the data to be added or updated to the socket ``fd``. The type | |
74 | and size of ``value`` should be the same as the value type of the map | |
75 | definition. | |
f3212ad5 | 76 | |
d2b497a9 DH |
77 | The ``flags`` parameter can be used to control the update behaviour: |
78 | ||
79 | - ``BPF_ANY`` will create storage for `socket` ``fd`` or update existing storage. | |
80 | - ``BPF_NOEXIST`` will create storage for `socket` ``fd`` only if it did not | |
81 | already exist, otherwise the call will fail with ``-EEXIST``. | |
82 | - ``BPF_EXIST`` will update existing storage for `socket` ``fd`` if it already | |
83 | exists, otherwise the call will fail with ``-ENOENT``. | |
f3212ad5 DH |
84 | |
85 | Returns ``0`` on success, or negative error in case of failure. | |
86 | ||
87 | bpf_map_lookup_elem() | |
88 | ~~~~~~~~~~~~~~~~~~~~~ | |
89 | ||
90 | .. code-block:: c | |
91 | ||
92 | int bpf_map_lookup_elem(int map_fd, const void *key, void *value) | |
93 | ||
d2b497a9 DH |
94 | Socket-local storage for map ``map_fd`` can be retrieved from a socket using |
95 | the ``bpf_map_lookup_elem()`` libbpf function. The storage is retrieved from | |
96 | the socket identified by a `socket` ``fd`` stored in the pointer | |
97 | ``key``. Returns ``0`` on success, or negative error in case of failure. | |
f3212ad5 DH |
98 | |
99 | bpf_map_delete_elem() | |
100 | ~~~~~~~~~~~~~~~~~~~~~ | |
101 | ||
102 | .. code-block:: c | |
103 | ||
104 | int bpf_map_delete_elem(int map_fd, const void *key) | |
105 | ||
d2b497a9 DH |
106 | Socket-local storage for map ``map_fd`` can be deleted from a socket using the |
107 | ``bpf_map_delete_elem()`` libbpf function. The storage is deleted from the | |
108 | socket identified by a `socket` ``fd`` stored in the pointer ``key``. Returns | |
109 | ``0`` on success, or negative error in case of failure. | |
f3212ad5 DH |
110 | |
111 | Examples | |
112 | ======== | |
113 | ||
114 | Kernel BPF | |
115 | ---------- | |
116 | ||
117 | This snippet shows how to declare socket-local storage in a BPF program: | |
118 | ||
119 | .. code-block:: c | |
120 | ||
121 | struct { | |
122 | __uint(type, BPF_MAP_TYPE_SK_STORAGE); | |
123 | __uint(map_flags, BPF_F_NO_PREALLOC); | |
124 | __type(key, int); | |
125 | __type(value, struct my_storage); | |
126 | } socket_storage SEC(".maps"); | |
127 | ||
128 | This snippet shows how to retrieve socket-local storage in a BPF program: | |
129 | ||
130 | .. code-block:: c | |
131 | ||
132 | SEC("sockops") | |
133 | int _sockops(struct bpf_sock_ops *ctx) | |
134 | { | |
135 | struct my_storage *storage; | |
136 | struct bpf_sock *sk; | |
137 | ||
138 | sk = ctx->sk; | |
139 | if (!sk) | |
140 | return 1; | |
141 | ||
142 | storage = bpf_sk_storage_get(&socket_storage, sk, 0, | |
143 | BPF_LOCAL_STORAGE_GET_F_CREATE); | |
144 | if (!storage) | |
145 | return 1; | |
146 | ||
147 | /* Use 'storage' here */ | |
148 | ||
149 | return 1; | |
150 | } | |
151 | ||
152 | ||
153 | Please see the ``tools/testing/selftests/bpf`` directory for functional | |
154 | examples. | |
155 | ||
156 | References | |
157 | ========== | |
158 | ||
159 | https://lwn.net/ml/netdev/20190426171103.61892-1-kafai@fb.com/ |