Message ID | 20230710201218.19460-6-daniel@iogearbox.net (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | BPF |
Headers | show |
Series | BPF link support for tc BPF programs | expand |
On Mon, Jul 10, 2023 at 1:12 PM Daniel Borkmann <daniel@iogearbox.net> wrote: > > Add a small and generic LIBBPF_OPTS_CLEAR() helper macros which clears > an opts structure and reinitializes its .sz member to place the structure > size. I found this very useful when developing selftests, but it is also > generic enough as a macro next to the existing LIBBPF_OPTS() which hides > the .sz initialization, too. > > Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> > --- > tools/lib/bpf/libbpf_common.h | 11 +++++++++++ > 1 file changed, 11 insertions(+) > > diff --git a/tools/lib/bpf/libbpf_common.h b/tools/lib/bpf/libbpf_common.h > index 9a7937f339df..eb180023aa97 100644 > --- a/tools/lib/bpf/libbpf_common.h > +++ b/tools/lib/bpf/libbpf_common.h > @@ -70,4 +70,15 @@ > }; \ > }) > > +/* Helper macro to clear a libbpf options struct > + * > + * Small helper macro to reset all fields and to reinitialize the common > + * structure size member. > + */ > +#define LIBBPF_OPTS_CLEAR(NAME) \ > + do { \ > + memset(&NAME, 0, sizeof(NAME)); \ > + NAME.sz = sizeof(NAME); \ > + } while (0) > + This is fine, but I think you can go a half-step further and have something even more universal and useful. Something like this: #define LIBBPF_OPTS_RESET(NAME, ...) do { memset(&NAME, 0, sizeof(NAME)); NAME = (typeof(NAME)) { .sz = sizeof(struct TYPE), __VA_ARGS__ }; while (0); I actually haven't tried if that typeof() trick works, but I hope it does :) Then your LIBBPF_OPTS_CLEAR() is just LIBBPF_OPTS_RESET(x). But you can also re-initialize: LIBBPF_OPTS_RESET(x, .flags = 123, .prog_fd = 456); It's more in line with LIBBPF_OPTS() itself in capabilities, except it works on existing variable. > #endif /* __LIBBPF_LIBBPF_COMMON_H */ > -- > 2.34.1 >
On 7/11/23 6:02 AM, Andrii Nakryiko wrote: > On Mon, Jul 10, 2023 at 1:12 PM Daniel Borkmann <daniel@iogearbox.net> wrote: >> >> Add a small and generic LIBBPF_OPTS_CLEAR() helper macros which clears >> an opts structure and reinitializes its .sz member to place the structure >> size. I found this very useful when developing selftests, but it is also >> generic enough as a macro next to the existing LIBBPF_OPTS() which hides >> the .sz initialization, too. >> >> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> >> --- >> tools/lib/bpf/libbpf_common.h | 11 +++++++++++ >> 1 file changed, 11 insertions(+) >> >> diff --git a/tools/lib/bpf/libbpf_common.h b/tools/lib/bpf/libbpf_common.h >> index 9a7937f339df..eb180023aa97 100644 >> --- a/tools/lib/bpf/libbpf_common.h >> +++ b/tools/lib/bpf/libbpf_common.h >> @@ -70,4 +70,15 @@ >> }; \ >> }) >> >> +/* Helper macro to clear a libbpf options struct >> + * >> + * Small helper macro to reset all fields and to reinitialize the common >> + * structure size member. >> + */ >> +#define LIBBPF_OPTS_CLEAR(NAME) \ >> + do { \ >> + memset(&NAME, 0, sizeof(NAME)); \ >> + NAME.sz = sizeof(NAME); \ >> + } while (0) >> + > > This is fine, but I think you can go a half-step further and have > something even more universal and useful. Something like this: > > > #define LIBBPF_OPTS_RESET(NAME, ...) > do { > memset(&NAME, 0, sizeof(NAME)); > NAME = (typeof(NAME)) { > .sz = sizeof(struct TYPE), > __VA_ARGS__ > }; > while (0); > > I actually haven't tried if that typeof() trick works, but I hope it does :) It does, I've used this in BPF code for Cilium, too. ;) > Then your LIBBPF_OPTS_CLEAR() is just LIBBPF_OPTS_RESET(x). But you > can also re-initialize: > > LIBBPF_OPTS_RESET(x, .flags = 123, .prog_fd = 456); > > It's more in line with LIBBPF_OPTS() itself in capabilities, except it > works on existing variable. Agree, changed into ... /* Helper macro to clear and optionally reinitialize libbpf options struct * * Small helper macro to reset all fields and to reinitialize the common * structure size member. Values provided by users in struct initializer- * syntax as varargs can be provided as well to reinitialize options struct * specific members. */ #define LIBBPF_OPTS_RESET(NAME, ...) \ do { \ memset(&NAME, 0, sizeof(NAME)); \ NAME = (typeof(NAME)) { \ .sz = sizeof(NAME), \ __VA_ARGS__ \ }; \ } while (0) ... and updated all the test cases. Thanks, Daniel
diff --git a/tools/lib/bpf/libbpf_common.h b/tools/lib/bpf/libbpf_common.h index 9a7937f339df..eb180023aa97 100644 --- a/tools/lib/bpf/libbpf_common.h +++ b/tools/lib/bpf/libbpf_common.h @@ -70,4 +70,15 @@ }; \ }) +/* Helper macro to clear a libbpf options struct + * + * Small helper macro to reset all fields and to reinitialize the common + * structure size member. + */ +#define LIBBPF_OPTS_CLEAR(NAME) \ + do { \ + memset(&NAME, 0, sizeof(NAME)); \ + NAME.sz = sizeof(NAME); \ + } while (0) + #endif /* __LIBBPF_LIBBPF_COMMON_H */
Add a small and generic LIBBPF_OPTS_CLEAR() helper macros which clears an opts structure and reinitializes its .sz member to place the structure size. I found this very useful when developing selftests, but it is also generic enough as a macro next to the existing LIBBPF_OPTS() which hides the .sz initialization, too. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> --- tools/lib/bpf/libbpf_common.h | 11 +++++++++++ 1 file changed, 11 insertions(+)