On Wed, May 6, 2020 at 10:40 PM Yonghong Song <yhs@xxxxxx> wrote: > > This patch added netlink and ipv6_route targets, using > the same seq_ops (except show() and minor changes for stop()) > for /proc/net/{netlink,ipv6_route}. > > The net namespace for these targets are the current net > namespace at file open stage, similar to > /proc/net/{netlink,ipv6_route} reference counting > the net namespace at seq_file open stage. > > Since module is not supported for now, ipv6_route is > supported only if the IPV6 is built-in, i.e., not compiled > as a module. The restriction can be lifted once module > is properly supported for bpf_iter. > > Signed-off-by: Yonghong Song <yhs@xxxxxx> > --- Looks correct. Acked-by: Andrii Nakryiko <andriin@xxxxxx> > fs/proc/proc_net.c | 19 +++++++++ > include/linux/proc_fs.h | 3 ++ > net/ipv6/ip6_fib.c | 65 +++++++++++++++++++++++++++++- > net/ipv6/route.c | 37 +++++++++++++++++ > net/netlink/af_netlink.c | 87 +++++++++++++++++++++++++++++++++++++++- > 5 files changed, 207 insertions(+), 4 deletions(-) > [...] > diff --git a/net/ipv6/route.c b/net/ipv6/route.c > index 3912aac7854d..25f6d3e619d0 100644 > --- a/net/ipv6/route.c > +++ b/net/ipv6/route.c > @@ -6393,6 +6393,30 @@ void __init ip6_route_init_special_entries(void) > #endif > } > > +#if IS_BUILTIN(CONFIG_IPV6) > +#if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_PROC_FS) > +DEFINE_BPF_ITER_FUNC(ipv6_route, struct bpf_iter_meta *meta, struct fib6_info *rt) > + > +static int __init bpf_iter_register(void) > +{ > + struct bpf_iter_reg reg_info = { > + .target = "ipv6_route", > + .seq_ops = &ipv6_route_seq_ops, > + .init_seq_private = bpf_iter_init_seq_net, > + .fini_seq_private = bpf_iter_fini_seq_net, > + .seq_priv_size = sizeof(struct ipv6_route_iter), > + }; > + > + return bpf_iter_reg_target(®_info); > +} > + > +static void bpf_iter_unregister(void) > +{ > + bpf_iter_unreg_target("ipv6_route"); Nit. This string duplication is unfortunate. If bpf_iter_unreg_target took same `struct bpf_iter_ret *` as bpf_iter_reg_target(), it would be symmetrical and not dependent on magic strings anymore. That reg_info struct would just be static const struct global variable passed to both register/unregister. > +} > +#endif > +#endif > + [...]