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