Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Acked-by: Kuniyuki Iwashima <kuniyu@amazon.co.jp>
Acked-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/20210701200548.1034629-1-kafai@fb.com

authored by

Martin KaFai Lau and committed by
Andrii Nakryiko
ad2d6137 525e2f9f

+30 -38
+30 -38
net/ipv4/tcp_ipv4.c
··· 2277 2277 #ifdef CONFIG_PROC_FS 2278 2278 /* Proc filesystem TCP sock list dumping. */ 2279 2279 2280 + static unsigned short seq_file_family(const struct seq_file *seq); 2281 + 2282 + static bool seq_sk_match(struct seq_file *seq, const struct sock *sk) 2283 + { 2284 + unsigned short family = seq_file_family(seq); 2285 + 2286 + /* AF_UNSPEC is used as a match all */ 2287 + return ((family == AF_UNSPEC || family == sk->sk_family) && 2288 + net_eq(sock_net(sk), seq_file_net(seq))); 2289 + } 2290 + 2280 2291 /* 2281 2292 * Get next listener socket follow cur. If cur is NULL, get first socket 2282 2293 * starting from bucket given in st->bucket; when st->bucket is zero the ··· 2295 2284 */ 2296 2285 static void *listening_get_next(struct seq_file *seq, void *cur) 2297 2286 { 2298 - struct tcp_seq_afinfo *afinfo; 2299 2287 struct tcp_iter_state *st = seq->private; 2300 - struct net *net = seq_file_net(seq); 2301 2288 struct inet_listen_hashbucket *ilb; 2302 2289 struct hlist_nulls_node *node; 2303 2290 struct sock *sk = cur; 2304 - 2305 - if (st->bpf_seq_afinfo) 2306 - afinfo = st->bpf_seq_afinfo; 2307 - else 2308 - afinfo = PDE_DATA(file_inode(seq->file)); 2309 2291 2310 2292 if (!sk) { 2311 2293 get_head: ··· 2315 2311 sk = sk_nulls_next(sk); 2316 2312 get_sk: 2317 2313 sk_nulls_for_each_from(sk, node) { 2318 - if (!net_eq(sock_net(sk), net)) 2319 - continue; 2320 - if (afinfo->family == AF_UNSPEC || 2321 - sk->sk_family == afinfo->family) 2314 + if (seq_sk_match(seq, sk)) 2322 2315 return sk; 2323 2316 } 2324 2317 spin_unlock(&ilb->lock); ··· 2352 2351 */ 2353 2352 static void *established_get_first(struct seq_file *seq) 2354 2353 { 2355 - struct tcp_seq_afinfo *afinfo; 2356 2354 struct tcp_iter_state *st = seq->private; 2357 - struct net *net = seq_file_net(seq); 2358 - void *rc = NULL; 2359 - 2360 - if (st->bpf_seq_afinfo) 2361 - afinfo = st->bpf_seq_afinfo; 2362 - else 2363 - afinfo = PDE_DATA(file_inode(seq->file)); 2364 2355 2365 2356 st->offset = 0; 2366 2357 for (; st->bucket <= tcp_hashinfo.ehash_mask; ++st->bucket) { ··· 2366 2373 2367 2374 spin_lock_bh(lock); 2368 2375 sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) { 2369 - if ((afinfo->family != AF_UNSPEC && 2370 - sk->sk_family != afinfo->family) || 2371 - !net_eq(sock_net(sk), net)) { 2372 - continue; 2373 - } 2374 - rc = sk; 2375 - goto out; 2376 + if (seq_sk_match(seq, sk)) 2377 + return sk; 2376 2378 } 2377 2379 spin_unlock_bh(lock); 2378 2380 } 2379 - out: 2380 - return rc; 2381 + 2382 + return NULL; 2381 2383 } 2382 2384 2383 2385 static void *established_get_next(struct seq_file *seq, void *cur) 2384 2386 { 2385 - struct tcp_seq_afinfo *afinfo; 2386 2387 struct sock *sk = cur; 2387 2388 struct hlist_nulls_node *node; 2388 2389 struct tcp_iter_state *st = seq->private; 2389 - struct net *net = seq_file_net(seq); 2390 - 2391 - if (st->bpf_seq_afinfo) 2392 - afinfo = st->bpf_seq_afinfo; 2393 - else 2394 - afinfo = PDE_DATA(file_inode(seq->file)); 2395 2390 2396 2391 ++st->num; 2397 2392 ++st->offset; ··· 2387 2406 sk = sk_nulls_next(sk); 2388 2407 2389 2408 sk_nulls_for_each_from(sk, node) { 2390 - if ((afinfo->family == AF_UNSPEC || 2391 - sk->sk_family == afinfo->family) && 2392 - net_eq(sock_net(sk), net)) 2409 + if (seq_sk_match(seq, sk)) 2393 2410 return sk; 2394 2411 } 2395 2412 ··· 2733 2754 .stop = bpf_iter_tcp_seq_stop, 2734 2755 }; 2735 2756 #endif 2757 + static unsigned short seq_file_family(const struct seq_file *seq) 2758 + { 2759 + const struct tcp_iter_state *st = seq->private; 2760 + const struct tcp_seq_afinfo *afinfo = st->bpf_seq_afinfo; 2761 + 2762 + /* Iterated from bpf_iter. Let the bpf prog to filter instead. */ 2763 + if (afinfo) 2764 + return AF_UNSPEC; 2765 + 2766 + /* Iterated from proc fs */ 2767 + afinfo = PDE_DATA(file_inode(seq->file)); 2768 + return afinfo->family; 2769 + } 2736 2770 2737 2771 static const struct seq_operations tcp4_seq_ops = { 2738 2772 .show = tcp4_seq_show,