mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-16 15:36:16 +07:00
085c20cacf
This patch will dump out the bpf_sk_storages of a sk if the request has the INET_DIAG_REQ_SK_BPF_STORAGES nlattr. An array of SK_DIAG_BPF_STORAGE_REQ_MAP_FD can be specified in INET_DIAG_REQ_SK_BPF_STORAGES to select which bpf_sk_storage to dump. If no map_fd is specified, all bpf_sk_storages of a sk will be dumped. bpf_sk_storages can be added to the system at runtime. It is difficult to find a proper static value for cb->min_dump_alloc. This patch learns the nlattr size required to dump the bpf_sk_storages of a sk. If it happens to be the very first nlmsg of a dump and it cannot fit the needed bpf_sk_storages, it will try to expand the skb by "pskb_expand_head()". Instead of expanding it in inet_sk_diag_fill(), it is expanded at a sleepable context in __inet_diag_dump() so __GFP_DIRECT_RECLAIM can be used. In __inet_diag_dump(), it will retry as long as the skb is empty and the cb->min_dump_alloc becomes larger than before. cb->min_dump_alloc is bounded by KMALLOC_MAX_SIZE. The min_dump_alloc is also changed from 'u16' to 'u32' to accommodate a sk that may have a few large bpf_sk_storages. The updated cb->min_dump_alloc will also be used to allocate the skb in the next dump. This logic already exists in netlink_dump(). Here is the sample output of a locally modified 'ss' and it could be made more readable by using BTF later: [root@arch-fb-vm1 ~]# ss --bpf-map-id 14 --bpf-map-id 13 -t6an 'dst [::1]:8989' State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess ESTAB 0 0 [::1]:51072 [::1]:8989 bpf_map_id:14 value:[ 3feb ] bpf_map_id:13 value:[ 3f ] ESTAB 0 0 [::1]:51070 [::1]:8989 bpf_map_id:14 value:[ 3feb ] bpf_map_id:13 value:[ 3f ] [root@arch-fb-vm1 ~]# ~/devshare/github/iproute2/misc/ss --bpf-maps -t6an 'dst [::1]:8989' State Recv-Q Send-Q Local Address:Port Peer Address:Port Process ESTAB 0 0 [::1]:51072 [::1]:8989 bpf_map_id:14 value:[ 3feb ] bpf_map_id:13 value:[ 3f ] bpf_map_id:12 value:[ 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000... total:65407 ] ESTAB 0 0 [::1]:51070 [::1]:8989 bpf_map_id:14 value:[ 3feb ] bpf_map_id:13 value:[ 3f ] bpf_map_id:12 value:[ 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000... total:65407 ] Signed-off-by: Martin KaFai Lau <kafai@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Song Liu <songliubraving@fb.com> Link: https://lore.kernel.org/bpf/20200225230427.1976129-1-kafai@fb.com
77 lines
2.3 KiB
C
77 lines
2.3 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _INET_DIAG_H_
|
|
#define _INET_DIAG_H_ 1
|
|
|
|
#include <uapi/linux/inet_diag.h>
|
|
|
|
struct net;
|
|
struct sock;
|
|
struct inet_hashinfo;
|
|
struct nlattr;
|
|
struct nlmsghdr;
|
|
struct sk_buff;
|
|
struct netlink_callback;
|
|
|
|
struct inet_diag_handler {
|
|
void (*dump)(struct sk_buff *skb,
|
|
struct netlink_callback *cb,
|
|
const struct inet_diag_req_v2 *r);
|
|
|
|
int (*dump_one)(struct netlink_callback *cb,
|
|
const struct inet_diag_req_v2 *req);
|
|
|
|
void (*idiag_get_info)(struct sock *sk,
|
|
struct inet_diag_msg *r,
|
|
void *info);
|
|
|
|
int (*idiag_get_aux)(struct sock *sk,
|
|
bool net_admin,
|
|
struct sk_buff *skb);
|
|
|
|
size_t (*idiag_get_aux_size)(struct sock *sk,
|
|
bool net_admin);
|
|
|
|
int (*destroy)(struct sk_buff *in_skb,
|
|
const struct inet_diag_req_v2 *req);
|
|
|
|
__u16 idiag_type;
|
|
__u16 idiag_info_size;
|
|
};
|
|
|
|
struct bpf_sk_storage_diag;
|
|
struct inet_diag_dump_data {
|
|
struct nlattr *req_nlas[__INET_DIAG_REQ_MAX];
|
|
#define inet_diag_nla_bc req_nlas[INET_DIAG_REQ_BYTECODE]
|
|
#define inet_diag_nla_bpf_stgs req_nlas[INET_DIAG_REQ_SK_BPF_STORAGES]
|
|
|
|
struct bpf_sk_storage_diag *bpf_stg_diag;
|
|
};
|
|
|
|
struct inet_connection_sock;
|
|
int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
|
|
struct sk_buff *skb, struct netlink_callback *cb,
|
|
const struct inet_diag_req_v2 *req,
|
|
u16 nlmsg_flags, bool net_admin);
|
|
void inet_diag_dump_icsk(struct inet_hashinfo *h, struct sk_buff *skb,
|
|
struct netlink_callback *cb,
|
|
const struct inet_diag_req_v2 *r);
|
|
int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo,
|
|
struct netlink_callback *cb,
|
|
const struct inet_diag_req_v2 *req);
|
|
|
|
struct sock *inet_diag_find_one_icsk(struct net *net,
|
|
struct inet_hashinfo *hashinfo,
|
|
const struct inet_diag_req_v2 *req);
|
|
|
|
int inet_diag_bc_sk(const struct nlattr *_bc, struct sock *sk);
|
|
|
|
void inet_diag_msg_common_fill(struct inet_diag_msg *r, struct sock *sk);
|
|
|
|
int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
|
|
struct inet_diag_msg *r, int ext,
|
|
struct user_namespace *user_ns, bool net_admin);
|
|
|
|
extern int inet_diag_register(const struct inet_diag_handler *handler);
|
|
extern void inet_diag_unregister(const struct inet_diag_handler *handler);
|
|
#endif /* _INET_DIAG_H_ */
|