// SPDX-License-Identifier: GPL-2.0/* Copyright (c) 2019 Facebook */#include<linux/rculist.h>#include<linux/list.h>#include<linux/hash.h>#include<linux/types.h>#include<linux/spinlock.h>#include<linux/bpf.h>#include<linux/btf_ids.h>#include<net/bpf_sk_storage.h>#include<net/sock.h>#include<uapi/linux/sock_diag.h>#include<uapi/linux/btf.h>#define SK_STORAGE_CREATE_FLAG_MASK \ (BPF_F_NO_PREALLOC | BPF_F_CLONE)structbucket{structhlist_headlist;raw_spinlock_tlock;};/* Thp map is not the primary owner of a bpf_sk_storage_elem. * Instead, the sk->sk_bpf_storage is. * * The map (bpf_sk_storage_map) is for two purposes * 1. Define the size of the "sk local storage". It is * the map's value_size. * * 2. Maintain a list to keep track of all elems such * that they can be cleaned up during the map destruction. * * When a bpf local storage is being looked up for a * particular sk, the "bpf_map" pointer is actually used * as the "key" to search in the list of elem in * sk->sk_bpf_storage. * * Hence, consider sk->sk_bpf_storage is the mini-map * with the "bpf_map" pointer as the searching key. */structbpf_sk_storage_map{structbpf_mapmap;/* Lookup elem does not require accessing the map. * * Updating/Deleting requires a bucket lock to * link/unlink the elem from the map. Having * multiple buckets to improve contention. */structbucket*buckets;u32bucket_log;u16elem_size;u16cache_idx;};structbpf_sk_storage_data{/* smap is used as the searching key when looking up * from sk->sk_bpf_storage. * * Put it in the same cacheline as the data to minimize * the number of cachelines access during the cache hit case. */structbpf_sk_storage_map__rcu*smap;u8data[]__aligned(8);};/* Linked to bpf_sk_storage and bpf_sk_storage_map */structbpf_sk_storage_elem{structhlist_nodemap_node;/* Linked to bpf_sk_storage_map */structhlist_nodesnode;/* Linked to bpf_sk_storage