| .. | .. | 
|---|
|  | 1 | +// SPDX-License-Identifier: GPL-2.0-only | 
|---|
| 1 | 2 | /* | 
|---|
| 2 | 3 | *  linux/fs/proc/net.c | 
|---|
| 3 | 4 | * | 
|---|
| .. | .. | 
|---|
| 73 | 74 | return 0; | 
|---|
| 74 | 75 | } | 
|---|
| 75 | 76 |  | 
|---|
| 76 |  | -static const struct file_operations proc_net_seq_fops = { | 
|---|
| 77 |  | -	.open		= seq_open_net, | 
|---|
| 78 |  | -	.read		= seq_read, | 
|---|
| 79 |  | -	.write		= proc_simple_write, | 
|---|
| 80 |  | -	.llseek		= seq_lseek, | 
|---|
| 81 |  | -	.release	= seq_release_net, | 
|---|
|  | 77 | +static const struct proc_ops proc_net_seq_ops = { | 
|---|
|  | 78 | +	.proc_open	= seq_open_net, | 
|---|
|  | 79 | +	.proc_read	= seq_read, | 
|---|
|  | 80 | +	.proc_write	= proc_simple_write, | 
|---|
|  | 81 | +	.proc_lseek	= seq_lseek, | 
|---|
|  | 82 | +	.proc_release	= seq_release_net, | 
|---|
| 82 | 83 | }; | 
|---|
|  | 84 | + | 
|---|
|  | 85 | +int bpf_iter_init_seq_net(void *priv_data, struct bpf_iter_aux_info *aux) | 
|---|
|  | 86 | +{ | 
|---|
|  | 87 | +#ifdef CONFIG_NET_NS | 
|---|
|  | 88 | +	struct seq_net_private *p = priv_data; | 
|---|
|  | 89 | + | 
|---|
|  | 90 | +	p->net = get_net(current->nsproxy->net_ns); | 
|---|
|  | 91 | +#endif | 
|---|
|  | 92 | +	return 0; | 
|---|
|  | 93 | +} | 
|---|
|  | 94 | + | 
|---|
|  | 95 | +void bpf_iter_fini_seq_net(void *priv_data) | 
|---|
|  | 96 | +{ | 
|---|
|  | 97 | +#ifdef CONFIG_NET_NS | 
|---|
|  | 98 | +	struct seq_net_private *p = priv_data; | 
|---|
|  | 99 | + | 
|---|
|  | 100 | +	put_net(p->net); | 
|---|
|  | 101 | +#endif | 
|---|
|  | 102 | +} | 
|---|
| 83 | 103 |  | 
|---|
| 84 | 104 | struct proc_dir_entry *proc_create_net_data(const char *name, umode_t mode, | 
|---|
| 85 | 105 | struct proc_dir_entry *parent, const struct seq_operations *ops, | 
|---|
| .. | .. | 
|---|
| 91 | 111 | if (!p) | 
|---|
| 92 | 112 | return NULL; | 
|---|
| 93 | 113 | pde_force_lookup(p); | 
|---|
| 94 |  | -	p->proc_fops = &proc_net_seq_fops; | 
|---|
|  | 114 | +	p->proc_ops = &proc_net_seq_ops; | 
|---|
| 95 | 115 | p->seq_ops = ops; | 
|---|
| 96 | 116 | p->state_size = state_size; | 
|---|
| 97 | 117 | return proc_register(parent, p); | 
|---|
| .. | .. | 
|---|
| 135 | 155 | if (!p) | 
|---|
| 136 | 156 | return NULL; | 
|---|
| 137 | 157 | pde_force_lookup(p); | 
|---|
| 138 |  | -	p->proc_fops = &proc_net_seq_fops; | 
|---|
|  | 158 | +	p->proc_ops = &proc_net_seq_ops; | 
|---|
| 139 | 159 | p->seq_ops = ops; | 
|---|
| 140 | 160 | p->state_size = state_size; | 
|---|
| 141 | 161 | p->write = write; | 
|---|
| .. | .. | 
|---|
| 166 | 186 | return single_release(ino, f); | 
|---|
| 167 | 187 | } | 
|---|
| 168 | 188 |  | 
|---|
| 169 |  | -static const struct file_operations proc_net_single_fops = { | 
|---|
| 170 |  | -	.open		= single_open_net, | 
|---|
| 171 |  | -	.read		= seq_read, | 
|---|
| 172 |  | -	.write		= proc_simple_write, | 
|---|
| 173 |  | -	.llseek		= seq_lseek, | 
|---|
| 174 |  | -	.release	= single_release_net, | 
|---|
|  | 189 | +static const struct proc_ops proc_net_single_ops = { | 
|---|
|  | 190 | +	.proc_open	= single_open_net, | 
|---|
|  | 191 | +	.proc_read	= seq_read, | 
|---|
|  | 192 | +	.proc_write	= proc_simple_write, | 
|---|
|  | 193 | +	.proc_lseek	= seq_lseek, | 
|---|
|  | 194 | +	.proc_release	= single_release_net, | 
|---|
| 175 | 195 | }; | 
|---|
| 176 | 196 |  | 
|---|
| 177 | 197 | struct proc_dir_entry *proc_create_net_single(const char *name, umode_t mode, | 
|---|
| .. | .. | 
|---|
| 184 | 204 | if (!p) | 
|---|
| 185 | 205 | return NULL; | 
|---|
| 186 | 206 | pde_force_lookup(p); | 
|---|
| 187 |  | -	p->proc_fops = &proc_net_single_fops; | 
|---|
|  | 207 | +	p->proc_ops = &proc_net_single_ops; | 
|---|
| 188 | 208 | p->single_show = show; | 
|---|
| 189 | 209 | return proc_register(parent, p); | 
|---|
| 190 | 210 | } | 
|---|
| .. | .. | 
|---|
| 227 | 247 | if (!p) | 
|---|
| 228 | 248 | return NULL; | 
|---|
| 229 | 249 | pde_force_lookup(p); | 
|---|
| 230 |  | -	p->proc_fops = &proc_net_single_fops; | 
|---|
|  | 250 | +	p->proc_ops = &proc_net_single_ops; | 
|---|
| 231 | 251 | p->single_show = show; | 
|---|
| 232 | 252 | p->write = write; | 
|---|
| 233 | 253 | return proc_register(parent, p); | 
|---|
| .. | .. | 
|---|
| 342 | 362 |  | 
|---|
| 343 | 363 | proc_set_user(netd, uid, gid); | 
|---|
| 344 | 364 |  | 
|---|
|  | 365 | +	/* Seed dentry revalidation for /proc/${pid}/net */ | 
|---|
|  | 366 | +	pde_force_lookup(netd); | 
|---|
|  | 367 | + | 
|---|
| 345 | 368 | err = -EEXIST; | 
|---|
| 346 | 369 | net_statd = proc_net_mkdir(net, "stat", netd); | 
|---|
| 347 | 370 | if (!net_statd) | 
|---|