Commit ad2d6137 authored by Martin KaFai Lau's avatar Martin KaFai Lau Committed by Andrii Nakryiko

tcp: seq_file: Refactor net and family matching

This patch refactors the net and family matching into
two new helpers, seq_sk_match() and seq_file_family().

seq_file_family() is in the later part of the file to prepare
the change of a following patch.
Signed-off-by: default avatarMartin KaFai Lau <kafai@fb.com>
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Acked-by: default avatarKuniyuki Iwashima <kuniyu@amazon.co.jp>
Acked-by: default avatarYonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/20210701200548.1034629-1-kafai@fb.com
parent 525e2f9f
...@@ -2277,6 +2277,17 @@ EXPORT_SYMBOL(tcp_v4_destroy_sock); ...@@ -2277,6 +2277,17 @@ EXPORT_SYMBOL(tcp_v4_destroy_sock);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
/* Proc filesystem TCP sock list dumping. */ /* Proc filesystem TCP sock list dumping. */
static unsigned short seq_file_family(const struct seq_file *seq);
static bool seq_sk_match(struct seq_file *seq, const struct sock *sk)
{
unsigned short family = seq_file_family(seq);
/* AF_UNSPEC is used as a match all */
return ((family == AF_UNSPEC || family == sk->sk_family) &&
net_eq(sock_net(sk), seq_file_net(seq)));
}
/* /*
* Get next listener socket follow cur. If cur is NULL, get first socket * Get next listener socket follow cur. If cur is NULL, get first socket
* starting from bucket given in st->bucket; when st->bucket is zero the * starting from bucket given in st->bucket; when st->bucket is zero the
...@@ -2284,18 +2295,11 @@ EXPORT_SYMBOL(tcp_v4_destroy_sock); ...@@ -2284,18 +2295,11 @@ EXPORT_SYMBOL(tcp_v4_destroy_sock);
*/ */
static void *listening_get_next(struct seq_file *seq, void *cur) static void *listening_get_next(struct seq_file *seq, void *cur)
{ {
struct tcp_seq_afinfo *afinfo;
struct tcp_iter_state *st = seq->private; struct tcp_iter_state *st = seq->private;
struct net *net = seq_file_net(seq);
struct inet_listen_hashbucket *ilb; struct inet_listen_hashbucket *ilb;
struct hlist_nulls_node *node; struct hlist_nulls_node *node;
struct sock *sk = cur; struct sock *sk = cur;
if (st->bpf_seq_afinfo)
afinfo = st->bpf_seq_afinfo;
else
afinfo = PDE_DATA(file_inode(seq->file));
if (!sk) { if (!sk) {
get_head: get_head:
ilb = &tcp_hashinfo.listening_hash[st->bucket]; ilb = &tcp_hashinfo.listening_hash[st->bucket];
...@@ -2311,10 +2315,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur) ...@@ -2311,10 +2315,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur)
sk = sk_nulls_next(sk); sk = sk_nulls_next(sk);
get_sk: get_sk:
sk_nulls_for_each_from(sk, node) { sk_nulls_for_each_from(sk, node) {
if (!net_eq(sock_net(sk), net)) if (seq_sk_match(seq, sk))
continue;
if (afinfo->family == AF_UNSPEC ||
sk->sk_family == afinfo->family)
return sk; return sk;
} }
spin_unlock(&ilb->lock); spin_unlock(&ilb->lock);
...@@ -2351,15 +2352,7 @@ static inline bool empty_bucket(const struct tcp_iter_state *st) ...@@ -2351,15 +2352,7 @@ static inline bool empty_bucket(const struct tcp_iter_state *st)
*/ */
static void *established_get_first(struct seq_file *seq) static void *established_get_first(struct seq_file *seq)
{ {
struct tcp_seq_afinfo *afinfo;
struct tcp_iter_state *st = seq->private; struct tcp_iter_state *st = seq->private;
struct net *net = seq_file_net(seq);
void *rc = NULL;
if (st->bpf_seq_afinfo)
afinfo = st->bpf_seq_afinfo;
else
afinfo = PDE_DATA(file_inode(seq->file));
st->offset = 0; st->offset = 0;
for (; st->bucket <= tcp_hashinfo.ehash_mask; ++st->bucket) { for (; st->bucket <= tcp_hashinfo.ehash_mask; ++st->bucket) {
...@@ -2373,32 +2366,20 @@ static void *established_get_first(struct seq_file *seq) ...@@ -2373,32 +2366,20 @@ static void *established_get_first(struct seq_file *seq)
spin_lock_bh(lock); spin_lock_bh(lock);
sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) { sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
if ((afinfo->family != AF_UNSPEC && if (seq_sk_match(seq, sk))
sk->sk_family != afinfo->family) || return sk;
!net_eq(sock_net(sk), net)) {
continue;
}
rc = sk;
goto out;
} }
spin_unlock_bh(lock); spin_unlock_bh(lock);
} }
out:
return rc; return NULL;
} }
static void *established_get_next(struct seq_file *seq, void *cur) static void *established_get_next(struct seq_file *seq, void *cur)
{ {
struct tcp_seq_afinfo *afinfo;
struct sock *sk = cur; struct sock *sk = cur;
struct hlist_nulls_node *node; struct hlist_nulls_node *node;
struct tcp_iter_state *st = seq->private; struct tcp_iter_state *st = seq->private;
struct net *net = seq_file_net(seq);
if (st->bpf_seq_afinfo)
afinfo = st->bpf_seq_afinfo;
else
afinfo = PDE_DATA(file_inode(seq->file));
++st->num; ++st->num;
++st->offset; ++st->offset;
...@@ -2406,9 +2387,7 @@ static void *established_get_next(struct seq_file *seq, void *cur) ...@@ -2406,9 +2387,7 @@ static void *established_get_next(struct seq_file *seq, void *cur)
sk = sk_nulls_next(sk); sk = sk_nulls_next(sk);
sk_nulls_for_each_from(sk, node) { sk_nulls_for_each_from(sk, node) {
if ((afinfo->family == AF_UNSPEC || if (seq_sk_match(seq, sk))
sk->sk_family == afinfo->family) &&
net_eq(sock_net(sk), net))
return sk; return sk;
} }
...@@ -2754,6 +2733,19 @@ static const struct seq_operations bpf_iter_tcp_seq_ops = { ...@@ -2754,6 +2733,19 @@ static const struct seq_operations bpf_iter_tcp_seq_ops = {
.stop = bpf_iter_tcp_seq_stop, .stop = bpf_iter_tcp_seq_stop,
}; };
#endif #endif
static unsigned short seq_file_family(const struct seq_file *seq)
{
const struct tcp_iter_state *st = seq->private;
const struct tcp_seq_afinfo *afinfo = st->bpf_seq_afinfo;
/* Iterated from bpf_iter. Let the bpf prog to filter instead. */
if (afinfo)
return AF_UNSPEC;
/* Iterated from proc fs */
afinfo = PDE_DATA(file_inode(seq->file));
return afinfo->family;
}
static const struct seq_operations tcp4_seq_ops = { static const struct seq_operations tcp4_seq_ops = {
.show = tcp4_seq_show, .show = tcp4_seq_show,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment