On Mon, Sep 25, 2023 at 10:59 PM Daniel Borkmann <daniel@xxxxxxxxxxxxx> wrote: > > This adds BPF link support for meta device (BPF_LINK_TYPE_META). Similar > as with tcx or XDP, the BPF link for meta contains the device. > > The bpf_mprog API has been reused for its implementation. For details, see > also commit e420bed0250 ("bpf: Add fd-based tcx multi-prog infra with link > support"). > > This is now the second user of bpf_mprog after tcx, and in meta case the > implementation is also a bit more straight forward since it does not need > to deal with miniq. > > The UAPI extensions for the BPF_LINK_CREATE command are similar as for tcx, > that is, relative_{fd,id} and expected_revision. > > Signed-off-by: Daniel Borkmann <daniel@xxxxxxxxxxxxx> > --- > drivers/net/meta.c | 211 ++++++++++++++++++++++++++++++++- > include/net/meta.h | 7 ++ > include/uapi/linux/bpf.h | 11 ++ > kernel/bpf/syscall.c | 2 +- > tools/include/uapi/linux/bpf.h | 11 ++ > 5 files changed, 240 insertions(+), 2 deletions(-) > [...] > diff --git a/include/net/meta.h b/include/net/meta.h > index 20fc61d05970..f1abe1d6d02d 100644 > --- a/include/net/meta.h > +++ b/include/net/meta.h > @@ -7,6 +7,7 @@ > > #ifdef CONFIG_META > int meta_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog); > +int meta_link_attach(const union bpf_attr *attr, struct bpf_prog *prog); > int meta_prog_detach(const union bpf_attr *attr, struct bpf_prog *prog); > int meta_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr); > #else > @@ -16,6 +17,12 @@ static inline int meta_prog_attach(const union bpf_attr *attr, > return -EINVAL; > } > > +static inline int meta_link_attach(const union bpf_attr *attr, > + struct bpf_prog *prog) > +{ > + return -EINVAL; > +} > + > static inline int meta_prog_detach(const union bpf_attr *attr, > struct bpf_prog *prog) > { > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h > index 00a875720e84..fd069f285fbc 100644 > --- a/include/uapi/linux/bpf.h > +++ b/include/uapi/linux/bpf.h > @@ -1068,6 +1068,7 @@ enum bpf_link_type { > BPF_LINK_TYPE_NETFILTER = 10, > BPF_LINK_TYPE_TCX = 11, > BPF_LINK_TYPE_UPROBE_MULTI = 12, > + BPF_LINK_TYPE_META = 12, it's not just some completely universal "meta" device, it's specifically networking meta-device, is that right? so at least in UAPI I think we should stay away from using super-generic "meta" words, and do something like "net_meta" or "meta_net" or whatnot, but indicate that this is networking stuff. WDYT? > MAX_BPF_LINK_TYPE, > }; > > @@ -1653,6 +1654,13 @@ union bpf_attr { > __u32 flags; > __u32 pid; > } uprobe_multi; > + struct { > + union { > + __u32 relative_fd; > + __u32 relative_id; > + }; > + __u64 expected_revision; > + } meta; > }; > } link_create; > > @@ -6564,6 +6572,9 @@ struct bpf_link_info { > __u32 ifindex; > __u32 attach_type; > } tcx; > + struct { > + __u32 ifindex; > + } meta; > }; > } __attribute__((aligned(8))); > > diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c > index 51baf4355c39..b689da4de280 100644 > --- a/kernel/bpf/syscall.c > +++ b/kernel/bpf/syscall.c > @@ -4969,7 +4969,7 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr) > attr->link_create.attach_type == BPF_TCX_EGRESS) > ret = tcx_link_attach(attr, prog); > else > - ret = -EINVAL; > + ret = meta_link_attach(attr, prog); > break; > case BPF_PROG_TYPE_NETFILTER: > ret = bpf_nf_link_attach(attr, prog); > diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h > index 00a875720e84..fd069f285fbc 100644 > --- a/tools/include/uapi/linux/bpf.h > +++ b/tools/include/uapi/linux/bpf.h > @@ -1068,6 +1068,7 @@ enum bpf_link_type { > BPF_LINK_TYPE_NETFILTER = 10, > BPF_LINK_TYPE_TCX = 11, > BPF_LINK_TYPE_UPROBE_MULTI = 12, > + BPF_LINK_TYPE_META = 12, > MAX_BPF_LINK_TYPE, > }; > > @@ -1653,6 +1654,13 @@ union bpf_attr { > __u32 flags; > __u32 pid; > } uprobe_multi; > + struct { > + union { > + __u32 relative_fd; > + __u32 relative_id; > + }; > + __u64 expected_revision; > + } meta; > }; > } link_create; > > @@ -6564,6 +6572,9 @@ struct bpf_link_info { > __u32 ifindex; > __u32 attach_type; > } tcx; > + struct { > + __u32 ifindex; > + } meta; > }; > } __attribute__((aligned(8))); > > -- > 2.34.1 >