netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH bpf-next] libbpf: making bpf_prog_load() ignore name if kernel doesn't support
@ 2022-08-12  2:40 Hangbin Liu
  2022-08-12  8:38 ` Quentin Monnet
  0 siblings, 1 reply; 3+ messages in thread
From: Hangbin Liu @ 2022-08-12  2:40 UTC (permalink / raw)
  To: netdev
  Cc: Quentin Monnet, Andrii Nakryiko, Alexei Starovoitov,
	Daniel Borkmann, Martin KaFai Lau, Song Liu, Yonghong Song,
	John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
	bpf, Hangbin Liu

Similar with commit 10b62d6a38f7 ("libbpf: Add names for auxiliary maps"),
let's make bpf_prog_load() also ignore name if kernel doesn't support
program name.

To achieve this, we need to call sys_bpf_prog_load() directly in
probe_kern_prog_name() to avoid circular dependency. sys_bpf_prog_load()
also need to be exported in the bpf.h file.

Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
---
 tools/lib/bpf/bpf.c    |  6 ++----
 tools/lib/bpf/bpf.h    |  3 +++
 tools/lib/bpf/libbpf.c | 11 +++++++++--
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 6a96e665dc5d..575867d69496 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -84,9 +84,7 @@ static inline int sys_bpf_fd(enum bpf_cmd cmd, union bpf_attr *attr,
 	return ensure_good_fd(fd);
 }
 
-#define PROG_LOAD_ATTEMPTS 5
-
-static inline int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int attempts)
+int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int attempts)
 {
 	int fd;
 
@@ -263,7 +261,7 @@ int bpf_prog_load(enum bpf_prog_type prog_type,
 	attr.prog_ifindex = OPTS_GET(opts, prog_ifindex, 0);
 	attr.kern_version = OPTS_GET(opts, kern_version, 0);
 
-	if (prog_name)
+	if (prog_name && kernel_supports(NULL, FEAT_PROG_NAME))
 		libbpf_strlcpy(attr.prog_name, prog_name, sizeof(attr.prog_name));
 	attr.license = ptr_to_u64(license);
 
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 9c50beabdd14..125c580e45f8 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -35,6 +35,9 @@
 extern "C" {
 #endif
 
+#define PROG_LOAD_ATTEMPTS 5
+int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int attempts);
+
 int libbpf_set_memlock_rlim(size_t memlock_bytes);
 
 struct bpf_map_create_opts {
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 3f01f5cd8a4c..1bcb2735d3f1 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -4419,10 +4419,17 @@ static int probe_kern_prog_name(void)
 		BPF_MOV64_IMM(BPF_REG_0, 0),
 		BPF_EXIT_INSN(),
 	};
-	int ret, insn_cnt = ARRAY_SIZE(insns);
+	union bpf_attr attr = {
+		.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
+		.prog_name = "test",
+		.license = ptr_to_u64("GPL"),
+		.insns = ptr_to_u64(insns),
+		.insn_cnt = (__u32)ARRAY_SIZE(insns),
+	};
+	int ret;
 
 	/* make sure loading with name works */
-	ret = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, "test", "GPL", insns, insn_cnt, NULL);
+	ret = sys_bpf_prog_load(&attr, sizeof(attr), PROG_LOAD_ATTEMPTS);
 	return probe_fd(ret);
 }
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH bpf-next] libbpf: making bpf_prog_load() ignore name if kernel doesn't support
  2022-08-12  2:40 [PATCH bpf-next] libbpf: making bpf_prog_load() ignore name if kernel doesn't support Hangbin Liu
@ 2022-08-12  8:38 ` Quentin Monnet
  2022-08-12 23:53   ` Hangbin Liu
  0 siblings, 1 reply; 3+ messages in thread
From: Quentin Monnet @ 2022-08-12  8:38 UTC (permalink / raw)
  To: Hangbin Liu, netdev
  Cc: Andrii Nakryiko, Alexei Starovoitov, Daniel Borkmann,
	Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, bpf

On 12/08/2022 03:40, Hangbin Liu wrote:
> Similar with commit 10b62d6a38f7 ("libbpf: Add names for auxiliary maps"),
> let's make bpf_prog_load() also ignore name if kernel doesn't support
> program name.
> 
> To achieve this, we need to call sys_bpf_prog_load() directly in
> probe_kern_prog_name() to avoid circular dependency. sys_bpf_prog_load()
> also need to be exported in the bpf.h file.
> 
> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
> ---
>  tools/lib/bpf/bpf.c    |  6 ++----
>  tools/lib/bpf/bpf.h    |  3 +++
>  tools/lib/bpf/libbpf.c | 11 +++++++++--
>  3 files changed, 14 insertions(+), 6 deletions(-)
> 
> diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
> index 6a96e665dc5d..575867d69496 100644
> --- a/tools/lib/bpf/bpf.c
> +++ b/tools/lib/bpf/bpf.c
> @@ -84,9 +84,7 @@ static inline int sys_bpf_fd(enum bpf_cmd cmd, union bpf_attr *attr,
>  	return ensure_good_fd(fd);
>  }
>  
> -#define PROG_LOAD_ATTEMPTS 5
> -
> -static inline int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int attempts)
> +int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int attempts)
>  {
>  	int fd;
>  
> @@ -263,7 +261,7 @@ int bpf_prog_load(enum bpf_prog_type prog_type,
>  	attr.prog_ifindex = OPTS_GET(opts, prog_ifindex, 0);
>  	attr.kern_version = OPTS_GET(opts, kern_version, 0);
>  
> -	if (prog_name)
> +	if (prog_name && kernel_supports(NULL, FEAT_PROG_NAME))
>  		libbpf_strlcpy(attr.prog_name, prog_name, sizeof(attr.prog_name));
>  	attr.license = ptr_to_u64(license);
>  
> diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
> index 9c50beabdd14..125c580e45f8 100644
> --- a/tools/lib/bpf/bpf.h
> +++ b/tools/lib/bpf/bpf.h
> @@ -35,6 +35,9 @@
>  extern "C" {
>  #endif
>  
> +#define PROG_LOAD_ATTEMPTS 5
> +int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int attempts);
> +

bpf.h is the user-facing header, should these go into libbpf_internal.h
instead?

By the way, I observe that libbpf_set_memlock_rlim() in bpf.h (below) is
not prefixed with LIBBPF_API, although it is exposed in the libbpf.map,
Andrii is this expected?

>  int libbpf_set_memlock_rlim(size_t memlock_bytes);
>  
>  struct bpf_map_create_opts {
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index 3f01f5cd8a4c..1bcb2735d3f1 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -4419,10 +4419,17 @@ static int probe_kern_prog_name(void)
>  		BPF_MOV64_IMM(BPF_REG_0, 0),
>  		BPF_EXIT_INSN(),
>  	};
> -	int ret, insn_cnt = ARRAY_SIZE(insns);
> +	union bpf_attr attr = {
> +		.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
> +		.prog_name = "test",
> +		.license = ptr_to_u64("GPL"),
> +		.insns = ptr_to_u64(insns),
> +		.insn_cnt = (__u32)ARRAY_SIZE(insns),
> +	};

I think you cannot initialise "attr" directly, you need a "memset(&attr,
0, sizeof(attr));" first, in case the struct contains padding between
the fields.

> +	int ret;
>  
>  	/* make sure loading with name works */
> -	ret = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, "test", "GPL", insns, insn_cnt, NULL);
> +	ret = sys_bpf_prog_load(&attr, sizeof(attr), PROG_LOAD_ATTEMPTS);
>  	return probe_fd(ret);
>  }
>  


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH bpf-next] libbpf: making bpf_prog_load() ignore name if kernel doesn't support
  2022-08-12  8:38 ` Quentin Monnet
@ 2022-08-12 23:53   ` Hangbin Liu
  0 siblings, 0 replies; 3+ messages in thread
From: Hangbin Liu @ 2022-08-12 23:53 UTC (permalink / raw)
  To: Quentin Monnet
  Cc: netdev, Andrii Nakryiko, Alexei Starovoitov, Daniel Borkmann,
	Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, bpf

On Fri, Aug 12, 2022 at 4:38 PM Quentin Monnet <quentin@isovalent.com> wrote:
> > diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
> > index 9c50beabdd14..125c580e45f8 100644
> > --- a/tools/lib/bpf/bpf.h
> > +++ b/tools/lib/bpf/bpf.h
> > @@ -35,6 +35,9 @@
> >  extern "C" {
> >  #endif
> >
> > +#define PROG_LOAD_ATTEMPTS 5
> > +int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int attempts);
> > +
>
> bpf.h is the user-facing header, should these go into libbpf_internal.h
> instead?

 libbpf_internal.h makes more sense, I wil move it.

> > +     union bpf_attr attr = {
> > +             .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
> > +             .prog_name = "test",
> > +             .license = ptr_to_u64("GPL"),
> > +             .insns = ptr_to_u64(insns),
> > +             .insn_cnt = (__u32)ARRAY_SIZE(insns),
> > +     };
>
> I think you cannot initialise "attr" directly, you need a "memset(&attr,
> 0, sizeof(attr));" first, in case the struct contains padding between
> the fields.

Thanks for the reminder. I forgot the padding issue.

I will post version 2.

Thanks
Hangbin

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-08-12 23:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-08-12  2:40 [PATCH bpf-next] libbpf: making bpf_prog_load() ignore name if kernel doesn't support Hangbin Liu
2022-08-12  8:38 ` Quentin Monnet
2022-08-12 23:53   ` Hangbin Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).