On Wed, Apr 21, 2021 at 12:28:01PM IST, Yonghong Song wrote: > > > On 4/20/21 12:37 PM, Kumar Kartikeya Dwivedi wrote: > > This adds functions that wrap the netlink API used for adding, > > manipulating, and removing traffic control filters. These functions > > operate directly on the loaded prog's fd, and return a handle to the > > filter using an out parameter named id. > > > > The basic featureset is covered to allow for attaching and removal of > > filters. Some additional features like TCA_BPF_POLICE and TCA_RATE for > > the API have been omitted. These can added on top later by extending the > > "later" => "layer"? > No, I meant that other options can be added on top of this series by someone later. I'll reword it. > > bpf_tc_opts struct. > > > > Support for binding actions directly to a classifier by passing them in > > during filter creation has also been omitted for now. These actions have > > an auto clean up property because their lifetime is bound to the filter > > they are attached to. This can be added later, but was omitted for now > > as direct action mode is a better alternative to it, which is enabled by > > default. > > > > An API summary: > > > > bpf_tc_attach may be used to attach, and replace SCHED_CLS bpf > > classifier. The protocol is always set as ETH_P_ALL. The replace option > > in bpf_tc_opts is used to control replacement behavior. Attachment > > fails if filter with existing attributes already exists. > > > > bpf_tc_detach may be used to detach existing SCHED_CLS filter. The > > bpf_tc_attach_id object filled in during attach must be passed in to the > > detach functions for them to remove the filter and its attached > > classififer correctly. > > > > bpf_tc_get_info is a helper that can be used to obtain attributes > > for the filter and classififer. > > > > Examples: > > > > struct bpf_tc_attach_id id = {}; > > struct bpf_object *obj; > > struct bpf_program *p; > > int fd, r; > > > > obj = bpf_object_open("foo.o"); > > if (IS_ERR_OR_NULL(obj)) > > return PTR_ERR(obj); > > > > p = bpf_object__find_program_by_title(obj, "classifier"); > > Please use bpf_object__find_program_by_name() API. > bpf_object__find_program_by_title() is not recommended as now > libbpf supports multiple programs within the same section. Thanks, will do. > > > if (IS_ERR_OR_NULL(p)) > > return PTR_ERR(p); > > > > if (bpf_object__load(obj) < 0) > > return -1; > > > > fd = bpf_program__fd(p); > > > > r = bpf_tc_attach(fd, if_nametoindex("lo"), > > BPF_TC_CLSACT_INGRESS, > > NULL, &id); > > if (r < 0) > > return r; > > > > ... which is roughly equivalent to: > > # tc qdisc add dev lo clsact > > # tc filter add dev lo ingress bpf obj foo.o sec classifier da > > > > ... as direct action mode is always enabled. > > > > To replace an existing filter: > > > > DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts, .handle = id.handle, > > .priority = id.priority, .replace = true); > > r = bpf_tc_attach(fd, if_nametoindex("lo"), > > BPF_TC_CLSACT_INGRESS, > > &opts, &id); > > if (r < 0) > > return r; > > > > To obtain info of a particular filter, the example above can be extended > > as follows: > > > > struct bpf_tc_info info = {}; > > > > r = bpf_tc_get_info(if_nametoindex("lo"), > > BPF_TC_CLSACT_INGRESS, > > &id, &info); > > if (r < 0) > > return r; > > > > ... where id corresponds to the bpf_tc_attach_id filled in during an > > attach operation. > > > > Reviewed-by: Toke Høiland-Jørgensen <toke@xxxxxxxxxx> > > Signed-off-by: Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx> > > --- > > tools/lib/bpf/libbpf.h | 44 ++++++ > > tools/lib/bpf/libbpf.map | 3 + > > tools/lib/bpf/netlink.c | 319 ++++++++++++++++++++++++++++++++++++++- > > 3 files changed, 360 insertions(+), 6 deletions(-) > > > > diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h > > index bec4e6a6e31d..b4ed6a41ea70 100644 > > --- a/tools/lib/bpf/libbpf.h > > +++ b/tools/lib/bpf/libbpf.h > > @@ -16,6 +16,8 @@ > > #include <stdbool.h> > > #include <sys/types.h> // for size_t > > #include <linux/bpf.h> > > +#include <linux/pkt_sched.h> > > +#include <linux/tc_act/tc_bpf.h> > > #include "libbpf_common.h" > > @@ -775,6 +777,48 @@ LIBBPF_API int bpf_linker__add_file(struct bpf_linker *linker, const char *filen > > LIBBPF_API int bpf_linker__finalize(struct bpf_linker *linker); > > LIBBPF_API void bpf_linker__free(struct bpf_linker *linker); > > +/* Convenience macros for the clsact attach hooks */ > > +#define BPF_TC_CLSACT_INGRESS TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_INGRESS) > > +#define BPF_TC_CLSACT_EGRESS TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_EGRESS) > > + > > +struct bpf_tc_opts { > > + size_t sz; > > + __u32 handle; > > + __u32 class_id; > > + __u16 priority; > > + bool replace; > > + size_t :0; > > Did you see any error without "size_t :0"? > Not really, I just added this considering this recent change: dde7b3f5f2f4 ("libbpf: Add explicit padding to bpf_xdp_set_link_opts") > > +}; > > + > > +#define bpf_tc_opts__last_field replace > > + > > +/* Acts as a handle for an attached filter */ > > +struct bpf_tc_attach_id { > > + __u32 handle; > > + __u16 priority; > > +}; > > + > [...] -- Kartikeya