linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] samples/bpf: Fix sockex3: missing BPF prog type
@ 2022-10-27 13:33 Rong Tao
  2022-10-27 13:38 ` [PATCH bpf-next] " Rong Tao
  0 siblings, 1 reply; 12+ messages in thread
From: Rong Tao @ 2022-10-27 13:33 UTC (permalink / raw)
  Cc: Rong Tao, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
	open list:BPF [GENERAL] (Safe Dynamic Programs and Tools),
	open list

From: Rong Tao <rongtao@cestc.cn>

since commit 450b167fb9be("libbpf: clean up SEC() handling"),
sec_def_matches() does not recognize "socket/xxx" as "socket", therefore,
the BPF program type is not recognized, we should add a custom program
type handler for "socket/xxx".

 $ cd samples/bpf
 $ sudo ./sockex3
 libbpf: prog 'bpf_func_PARSE_IP': missing BPF prog type, check ELF section name 'socket/3'
 libbpf: prog 'bpf_func_PARSE_IP': failed to load: -22
 libbpf: failed to load object './sockex3_kern.o'
 ERROR: loading BPF object file failed

Signed-off-by: Rong Tao <rongtao@cestc.cn>
---
 samples/bpf/sockex3_user.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/samples/bpf/sockex3_user.c b/samples/bpf/sockex3_user.c
index cd6fa79df900..d18d7a3600b0 100644
--- a/samples/bpf/sockex3_user.c
+++ b/samples/bpf/sockex3_user.c
@@ -22,6 +22,14 @@ struct pair {
 	__u64 bytes;
 };
 
+static int socket_prog_type_id;
+
+__attribute__((destructor))
+static void unregister_socket_sec_handlers(void)
+{
+	libbpf_unregister_prog_handler(socket_prog_type_id);
+}
+
 int main(int argc, char **argv)
 {
 	int i, sock, key, fd, main_prog_fd, jmp_table_fd, hash_map_fd;
@@ -31,6 +39,13 @@ int main(int argc, char **argv)
 	char filename[256];
 	FILE *f;
 
+	LIBBPF_OPTS(libbpf_prog_handler_opts, socket_opts,
+		.cookie = 1,
+	);
+
+	socket_prog_type_id = libbpf_register_prog_handler("socket/",
+			BPF_PROG_TYPE_SOCKET_FILTER, 0, &socket_opts);
+
 	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
 
 	obj = bpf_object__open_file(filename, NULL);
-- 
2.31.1


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

* [PATCH bpf-next] samples/bpf: Fix sockex3: missing BPF prog type
  2022-10-27 13:33 [PATCH] samples/bpf: Fix sockex3: missing BPF prog type Rong Tao
@ 2022-10-27 13:38 ` Rong Tao
  2022-10-27 20:15   ` Andrii Nakryiko
  0 siblings, 1 reply; 12+ messages in thread
From: Rong Tao @ 2022-10-27 13:38 UTC (permalink / raw)
  Cc: Rong Tao, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
	open list:BPF [GENERAL] (Safe Dynamic Programs and Tools),
	open list

From: Rong Tao <rongtao@cestc.cn>

since commit 450b167fb9be("libbpf: clean up SEC() handling"),
sec_def_matches() does not recognize "socket/xxx" as "socket", therefore,
the BPF program type is not recognized, we should add a custom program
type handler for "socket/xxx".

 $ cd samples/bpf
 $ sudo ./sockex3
 libbpf: prog 'bpf_func_PARSE_IP': missing BPF prog type, check ELF section name 'socket/3'
 libbpf: prog 'bpf_func_PARSE_IP': failed to load: -22
 libbpf: failed to load object './sockex3_kern.o'
 ERROR: loading BPF object file failed

Signed-off-by: Rong Tao <rongtao@cestc.cn>
---
 samples/bpf/sockex3_user.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/samples/bpf/sockex3_user.c b/samples/bpf/sockex3_user.c
index cd6fa79df900..d18d7a3600b0 100644
--- a/samples/bpf/sockex3_user.c
+++ b/samples/bpf/sockex3_user.c
@@ -22,6 +22,14 @@ struct pair {
 	__u64 bytes;
 };
 
+static int socket_prog_type_id;
+
+__attribute__((destructor))
+static void unregister_socket_sec_handlers(void)
+{
+	libbpf_unregister_prog_handler(socket_prog_type_id);
+}
+
 int main(int argc, char **argv)
 {
 	int i, sock, key, fd, main_prog_fd, jmp_table_fd, hash_map_fd;
@@ -31,6 +39,13 @@ int main(int argc, char **argv)
 	char filename[256];
 	FILE *f;
 
+	LIBBPF_OPTS(libbpf_prog_handler_opts, socket_opts,
+		.cookie = 1,
+	);
+
+	socket_prog_type_id = libbpf_register_prog_handler("socket/",
+			BPF_PROG_TYPE_SOCKET_FILTER, 0, &socket_opts);
+
 	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
 
 	obj = bpf_object__open_file(filename, NULL);
-- 
2.31.1


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

* Re: [PATCH bpf-next] samples/bpf: Fix sockex3: missing BPF prog type
  2022-10-27 13:38 ` [PATCH bpf-next] " Rong Tao
@ 2022-10-27 20:15   ` Andrii Nakryiko
  2022-10-28  1:01     ` [PATCH] " Rong Tao
  0 siblings, 1 reply; 12+ messages in thread
From: Andrii Nakryiko @ 2022-10-27 20:15 UTC (permalink / raw)
  To: Rong Tao
  Cc: Rong Tao, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
	open list:BPF [GENERAL] (Safe Dynamic Programs and Tools),
	open list

On Thu, Oct 27, 2022 at 6:38 AM Rong Tao <rtoax@foxmail.com> wrote:
>
> From: Rong Tao <rongtao@cestc.cn>
>
> since commit 450b167fb9be("libbpf: clean up SEC() handling"),
> sec_def_matches() does not recognize "socket/xxx" as "socket", therefore,
> the BPF program type is not recognized, we should add a custom program
> type handler for "socket/xxx".

I don't think we should, we should just switch to SEC("socket") or
whatever the right annotation has to be. Let's fix the BPF-side code.

>
>  $ cd samples/bpf
>  $ sudo ./sockex3
>  libbpf: prog 'bpf_func_PARSE_IP': missing BPF prog type, check ELF section name 'socket/3'
>  libbpf: prog 'bpf_func_PARSE_IP': failed to load: -22
>  libbpf: failed to load object './sockex3_kern.o'
>  ERROR: loading BPF object file failed
>
> Signed-off-by: Rong Tao <rongtao@cestc.cn>
> ---
>  samples/bpf/sockex3_user.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
>
> diff --git a/samples/bpf/sockex3_user.c b/samples/bpf/sockex3_user.c
> index cd6fa79df900..d18d7a3600b0 100644
> --- a/samples/bpf/sockex3_user.c
> +++ b/samples/bpf/sockex3_user.c
> @@ -22,6 +22,14 @@ struct pair {
>         __u64 bytes;
>  };
>
> +static int socket_prog_type_id;
> +
> +__attribute__((destructor))
> +static void unregister_socket_sec_handlers(void)
> +{
> +       libbpf_unregister_prog_handler(socket_prog_type_id);
> +}
> +
>  int main(int argc, char **argv)
>  {
>         int i, sock, key, fd, main_prog_fd, jmp_table_fd, hash_map_fd;
> @@ -31,6 +39,13 @@ int main(int argc, char **argv)
>         char filename[256];
>         FILE *f;
>
> +       LIBBPF_OPTS(libbpf_prog_handler_opts, socket_opts,
> +               .cookie = 1,
> +       );
> +
> +       socket_prog_type_id = libbpf_register_prog_handler("socket/",
> +                       BPF_PROG_TYPE_SOCKET_FILTER, 0, &socket_opts);
> +
>         snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
>
>         obj = bpf_object__open_file(filename, NULL);
> --
> 2.31.1
>

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

* Re: [PATCH] samples/bpf: Fix sockex3: missing BPF prog type
  2022-10-27 20:15   ` Andrii Nakryiko
@ 2022-10-28  1:01     ` Rong Tao
  2022-10-28 17:09       ` Andrii Nakryiko
  0 siblings, 1 reply; 12+ messages in thread
From: Rong Tao @ 2022-10-28  1:01 UTC (permalink / raw)
  To: andrii.nakryiko
  Cc: andrii, ast, bpf, daniel, haoluo, john.fastabend, jolsa, kpsingh,
	linux-kernel, martin.lau, rongtao, rtoax, sdf, song, yhs

Thanks for your reply, actually, i tried another method, which can solved
this error, recognize "socket/xxx" as "socket". However, it maybe influence
other BPF prog or not? What do you think the following patch?

--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -8659,7 +8659,7 @@ static bool sec_def_matches(const struct bpf_sec_def *sec_def, const char *sec_n
                return false;
        }

-       return strcmp(sec_name, sec_def->sec) == 0;
+       return strncmp(sec_name, sec_def->sec, len) == 0;
 }

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

* Re: [PATCH] samples/bpf: Fix sockex3: missing BPF prog type
  2022-10-28  1:01     ` [PATCH] " Rong Tao
@ 2022-10-28 17:09       ` Andrii Nakryiko
  2022-10-29  7:53         ` [PATCH bpf-next] " Rong Tao
  0 siblings, 1 reply; 12+ messages in thread
From: Andrii Nakryiko @ 2022-10-28 17:09 UTC (permalink / raw)
  To: Rong Tao
  Cc: andrii, ast, bpf, daniel, haoluo, john.fastabend, jolsa, kpsingh,
	linux-kernel, martin.lau, rongtao, sdf, song, yhs

On Thu, Oct 27, 2022 at 6:01 PM Rong Tao <rtoax@foxmail.com> wrote:
>
> Thanks for your reply, actually, i tried another method, which can solved
> this error, recognize "socket/xxx" as "socket". However, it maybe influence
> other BPF prog or not? What do you think the following patch?

Don't fix libbpf, it's not broken. Fix the sample.

>
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -8659,7 +8659,7 @@ static bool sec_def_matches(const struct bpf_sec_def *sec_def, const char *sec_n
>                 return false;
>         }
>
> -       return strcmp(sec_name, sec_def->sec) == 0;
> +       return strncmp(sec_name, sec_def->sec, len) == 0;
>  }

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

* [PATCH bpf-next] samples/bpf: Fix sockex3: missing BPF prog type
  2022-10-28 17:09       ` Andrii Nakryiko
@ 2022-10-29  7:53         ` Rong Tao
  2022-11-03 18:38           ` Andrii Nakryiko
  0 siblings, 1 reply; 12+ messages in thread
From: Rong Tao @ 2022-10-29  7:53 UTC (permalink / raw)
  To: andrii.nakryiko
  Cc: andrii, ast, bpf, daniel, haoluo, john.fastabend, jolsa, kpsingh,
	linux-kernel, martin.lau, rongtao, rtoax, sdf, song, yhs

From: Rong Tao <rongtao@cestc.cn>

since commit 450b167fb9be("libbpf: clean up SEC() handling"),
sec_def_matches() does not recognize "socket/xxx" as "socket", therefore,
the BPF program type is not recognized, set "socket/xxx" to SOCKET_FILTER
solves this error.

 $ cd samples/bpf
 $ sudo ./sockex3
 libbpf: prog 'bpf_func_PARSE_IP': missing BPF prog type, check ELF section name 'socket/3'
 libbpf: prog 'bpf_func_PARSE_IP': failed to load: -22
 libbpf: failed to load object './sockex3_kern.o'
 ERROR: loading BPF object file failed

Signed-off-by: Rong Tao <rongtao@cestc.cn>
---
 samples/bpf/sockex3_user.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/samples/bpf/sockex3_user.c b/samples/bpf/sockex3_user.c
index cd6fa79df900..dc79c17ad195 100644
--- a/samples/bpf/sockex3_user.c
+++ b/samples/bpf/sockex3_user.c
@@ -39,6 +39,9 @@ int main(int argc, char **argv)
 		return 0;
 	}
 
+	bpf_object__for_each_program(prog, obj)
+		bpf_program__set_type(prog, BPF_PROG_TYPE_SOCKET_FILTER);
+
 	/* load BPF program */
 	if (bpf_object__load(obj)) {
 		fprintf(stderr, "ERROR: loading BPF object file failed\n");
-- 
2.31.1


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

* Re: [PATCH bpf-next] samples/bpf: Fix sockex3: missing BPF prog type
  2022-10-29  7:53         ` [PATCH bpf-next] " Rong Tao
@ 2022-11-03 18:38           ` Andrii Nakryiko
  2022-11-04  3:17             ` Rong Tao
  0 siblings, 1 reply; 12+ messages in thread
From: Andrii Nakryiko @ 2022-11-03 18:38 UTC (permalink / raw)
  To: Rong Tao
  Cc: andrii, ast, bpf, daniel, haoluo, john.fastabend, jolsa, kpsingh,
	linux-kernel, martin.lau, rongtao, sdf, song, yhs

On Sat, Oct 29, 2022 at 12:53 AM Rong Tao <rtoax@foxmail.com> wrote:
>
> From: Rong Tao <rongtao@cestc.cn>
>
> since commit 450b167fb9be("libbpf: clean up SEC() handling"),
> sec_def_matches() does not recognize "socket/xxx" as "socket", therefore,
> the BPF program type is not recognized, set "socket/xxx" to SOCKET_FILTER
> solves this error.
>
>  $ cd samples/bpf
>  $ sudo ./sockex3
>  libbpf: prog 'bpf_func_PARSE_IP': missing BPF prog type, check ELF section name 'socket/3'
>  libbpf: prog 'bpf_func_PARSE_IP': failed to load: -22
>  libbpf: failed to load object './sockex3_kern.o'
>  ERROR: loading BPF object file failed
>
> Signed-off-by: Rong Tao <rongtao@cestc.cn>
> ---

You need to do changes like this:

diff --git a/samples/bpf/sockex3_kern.c b/samples/bpf/sockex3_kern.c
index b363503357e5..db6a93e7ec53 100644
--- a/samples/bpf/sockex3_kern.c
+++ b/samples/bpf/sockex3_kern.c
@@ -17,7 +17,7 @@
 #define IP_MF          0x2000
 #define IP_OFFSET      0x1FFF

-#define PROG(F) SEC("socket/"__stringify(F)) int bpf_func_##F
+#define PROG(F) SEC("socket_filter") int bpf_func_##F

 struct {
        __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
@@ -279,7 +279,7 @@ PROG(PARSE_MPLS)(struct __sk_buff *skb)
        return 0;
 }

-SEC("socket/0")
+SEC("socket_filter")
 int main_prog(struct __sk_buff *skb)
 {
        __u32 nhoff = ETH_HLEN;


Why fixing up after the fact at runtime, if you can just make those
BPF programs conform to libbpf rules?



>  samples/bpf/sockex3_user.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/samples/bpf/sockex3_user.c b/samples/bpf/sockex3_user.c
> index cd6fa79df900..dc79c17ad195 100644
> --- a/samples/bpf/sockex3_user.c
> +++ b/samples/bpf/sockex3_user.c
> @@ -39,6 +39,9 @@ int main(int argc, char **argv)
>                 return 0;
>         }
>
> +       bpf_object__for_each_program(prog, obj)
> +               bpf_program__set_type(prog, BPF_PROG_TYPE_SOCKET_FILTER);
> +
>         /* load BPF program */
>         if (bpf_object__load(obj)) {
>                 fprintf(stderr, "ERROR: loading BPF object file failed\n");
> --
> 2.31.1
>

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

* Re: Re: [PATCH bpf-next] samples/bpf: Fix sockex3: missing BPF prog type
  2022-11-03 18:38           ` Andrii Nakryiko
@ 2022-11-04  3:17             ` Rong Tao
  2022-11-04 22:53               ` Andrii Nakryiko
  0 siblings, 1 reply; 12+ messages in thread
From: Rong Tao @ 2022-11-04  3:17 UTC (permalink / raw)
  To: andrii.nakryiko
  Cc: andrii, ast, bpf, daniel, haoluo, john.fastabend, jolsa, kpsingh,
	linux-kernel, martin.lau, rongtao, rtoax, sdf, song, yhs

We can not just remove the number of program like:

-#define PROG(F) SEC("socket/"__stringify(F)) int bpf_func_##F
+#define PROG(F) SEC("socket_filter") int bpf_func_##F

because "sockex3" use the _NUMBER_ as index(see map "jmp_table"), if we
apply the following patch, it's still not recognize "socket_filter/xxx"
as "socket_filter", still have "missing BPF prog type" error:

diff --git a/samples/bpf/sockex3_kern.c b/samples/bpf/sockex3_kern.c
index b363503357e5..ab5a7bde66d0 100644
--- a/samples/bpf/sockex3_kern.c
+++ b/samples/bpf/sockex3_kern.c
@@ -17,7 +17,7 @@
 #define IP_MF          0x2000
 #define IP_OFFSET      0x1FFF

-#define PROG(F) SEC("socket/"__stringify(F)) int bpf_func_##F
+#define PROG(F) SEC("socket_filter/"__stringify(F)) int bpf_func_##F

 struct {
        __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
@@ -279,7 +279,7 @@ PROG(PARSE_MPLS)(struct __sk_buff *skb)
        return 0;
 }

-SEC("socket/0")
+SEC("socket_filter/0")
 int main_prog(struct __sk_buff *skb)
 {
        __u32 nhoff = ETH_HLEN;
diff --git a/samples/bpf/sockex3_user.c b/samples/bpf/sockex3_user.c
index cd6fa79df900..63fc9a8077b1 100644
--- a/samples/bpf/sockex3_user.c
+++ b/samples/bpf/sockex3_user.c
@@ -56,7 +56,7 @@ int main(int argc, char **argv)
                fd = bpf_program__fd(prog);

                section = bpf_program__section_name(prog);
-               if (sscanf(section, "socket/%d", &key) != 1) {
+               if (sscanf(section, "socket_filter/%d", &key) != 1) {
                        fprintf(stderr, "ERROR: finding prog failed\n");
                        goto cleanup;
                }

For a reason, in sockex3_kern.c only have five PROGs, list all five:

#define PROG(F) SEC("socket/"__stringify(F)) int bpf_func_##F
PROG(PARSE_IP)(struct __sk_buff *skb)
PROG(PARSE_IPV6)(struct __sk_buff *skb)
PROG(PARSE_VLAN)(struct __sk_buff *skb)
PROG(PARSE_MPLS)(struct __sk_buff *skb)
SEC("socket/0") int main_prog(struct __sk_buff *skb)

As you can see, all those PROGs are BPF_PROG_TYPE_SOCKET_FILTER, so we can
use the follow patch specify bpf program type as SOCKET_FILTER:

https://lore.kernel.org/lkml/tencent_7DD02046A8398BE3324F85E0F56ED41EB105@qq.com/

diff --git a/samples/bpf/sockex3_user.c b/samples/bpf/sockex3_user.c
index cd6fa79df900..dc79c17ad195 100644
--- a/samples/bpf/sockex3_user.c
+++ b/samples/bpf/sockex3_user.c
@@ -39,6 +39,9 @@ int main(int argc, char **argv)
                return 0;
        }

+       bpf_object__for_each_program(prog, obj)
+               bpf_program__set_type(prog, BPF_PROG_TYPE_SOCKET_FILTER);
+
        /* load BPF program */
        if (bpf_object__load(obj)) {
                fprintf(stderr, "ERROR: loading BPF object file failed\n");

This patch above totally solved the compile error.


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

* Re: Re: [PATCH bpf-next] samples/bpf: Fix sockex3: missing BPF prog type
  2022-11-04  3:17             ` Rong Tao
@ 2022-11-04 22:53               ` Andrii Nakryiko
  2022-11-05  6:48                 ` [PATCH bpf-next] samples/bpf: Fix sockex3 error: " Rong Tao
  0 siblings, 1 reply; 12+ messages in thread
From: Andrii Nakryiko @ 2022-11-04 22:53 UTC (permalink / raw)
  To: Rong Tao
  Cc: andrii, ast, bpf, daniel, haoluo, john.fastabend, jolsa, kpsingh,
	linux-kernel, martin.lau, rongtao, sdf, song, yhs

On Thu, Nov 3, 2022 at 8:17 PM Rong Tao <rtoax@foxmail.com> wrote:
>
> We can not just remove the number of program like:
>
> -#define PROG(F) SEC("socket/"__stringify(F)) int bpf_func_##F
> +#define PROG(F) SEC("socket_filter") int bpf_func_##F
>
> because "sockex3" use the _NUMBER_ as index(see map "jmp_table"), if we
> apply the following patch, it's still not recognize "socket_filter/xxx"
> as "socket_filter", still have "missing BPF prog type" error:

Ok, let's keep unwinding this. This is an old and manual way to set up
tail call map. Libbpf supports declarative way to do, so
sockex3_user.c won't have to do anything at all.

See progs/test_prog_array_init.c for an example. Let's convert samples
to use this as well.

This programmatic setting of program type works, there is no doubt
about this. But it's a signal that something is not exactly how it
should be. So let's use this as an opportunity to modernize samples,
instead of adding workarounds.

I hope you sympathize with this goal.

>
> diff --git a/samples/bpf/sockex3_kern.c b/samples/bpf/sockex3_kern.c
> index b363503357e5..ab5a7bde66d0 100644
> --- a/samples/bpf/sockex3_kern.c
> +++ b/samples/bpf/sockex3_kern.c
> @@ -17,7 +17,7 @@
>  #define IP_MF          0x2000
>  #define IP_OFFSET      0x1FFF
>

[...]

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

* [PATCH bpf-next] samples/bpf: Fix sockex3 error: missing BPF prog type
  2022-11-04 22:53               ` Andrii Nakryiko
@ 2022-11-05  6:48                 ` Rong Tao
  2022-11-08  1:14                   ` Andrii Nakryiko
  2022-11-08  1:20                   ` patchwork-bot+netdevbpf
  0 siblings, 2 replies; 12+ messages in thread
From: Rong Tao @ 2022-11-05  6:48 UTC (permalink / raw)
  To: andrii.nakryiko
  Cc: andrii, ast, bpf, daniel, haoluo, john.fastabend, jolsa, kpsingh,
	linux-kernel, martin.lau, rongtao, rtoax, sdf, song, yhs

From: Rong Tao <rongtao@cestc.cn>

since commit 450b167fb9be("libbpf: clean up SEC() handling"),
sec_def_matches() does not recognize "socket/xxx" as "socket", therefore,
the BPF program type is not recognized.

Instead of sockex3_user.c parsing section names to get the BPF program fd.
We use the program array map to assign a static index to each BPF program
(get inspired by selftests/bpf progs/test_prog_array_init.c).
Therefore, use SEC("socket") as section name instead of SEC("socket/xxx"),
so that the BPF program is parsed to SOCKET_FILTER type. The "missing BPF
prog type" problem is solved.

How to reproduce this error:
$ cd samples/bpf
$ sudo ./sockex3
libbpf: prog 'bpf_func_PARSE_IP': missing BPF prog type, check ELF section name 'socket/3'
libbpf: prog 'bpf_func_PARSE_IP': failed to load: -22
libbpf: failed to load object './sockex3_kern.o'
ERROR: loading BPF object file failed

Signed-off-by: Rong Tao <rongtao@cestc.cn>
---
 samples/bpf/sockex3_kern.c | 95 ++++++++++++++++++++++----------------
 samples/bpf/sockex3_user.c | 23 ++++-----
 2 files changed, 64 insertions(+), 54 deletions(-)

diff --git a/samples/bpf/sockex3_kern.c b/samples/bpf/sockex3_kern.c
index b363503357e5..26d916834865 100644
--- a/samples/bpf/sockex3_kern.c
+++ b/samples/bpf/sockex3_kern.c
@@ -17,47 +17,12 @@
 #define IP_MF		0x2000
 #define IP_OFFSET	0x1FFF
 
-#define PROG(F) SEC("socket/"__stringify(F)) int bpf_func_##F
-
-struct {
-	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
-	__uint(key_size, sizeof(u32));
-	__uint(value_size, sizeof(u32));
-	__uint(max_entries, 8);
-} jmp_table SEC(".maps");
-
 #define PARSE_VLAN 1
 #define PARSE_MPLS 2
 #define PARSE_IP 3
 #define PARSE_IPV6 4
 
-/* Protocol dispatch routine. It tail-calls next BPF program depending
- * on eth proto. Note, we could have used ...
- *
- *   bpf_tail_call(skb, &jmp_table, proto);
- *
- * ... but it would need large prog_array and cannot be optimised given
- * the map key is not static.
- */
-static inline void parse_eth_proto(struct __sk_buff *skb, u32 proto)
-{
-	switch (proto) {
-	case ETH_P_8021Q:
-	case ETH_P_8021AD:
-		bpf_tail_call(skb, &jmp_table, PARSE_VLAN);
-		break;
-	case ETH_P_MPLS_UC:
-	case ETH_P_MPLS_MC:
-		bpf_tail_call(skb, &jmp_table, PARSE_MPLS);
-		break;
-	case ETH_P_IP:
-		bpf_tail_call(skb, &jmp_table, PARSE_IP);
-		break;
-	case ETH_P_IPV6:
-		bpf_tail_call(skb, &jmp_table, PARSE_IPV6);
-		break;
-	}
-}
+#define PROG_SOCKET_FILTER	SEC("socket")
 
 struct vlan_hdr {
 	__be16 h_vlan_TCI;
@@ -74,6 +39,8 @@ struct flow_key_record {
 	__u32 ip_proto;
 };
 
+static inline void parse_eth_proto(struct __sk_buff *skb, u32 proto);
+
 static inline int ip_is_fragment(struct __sk_buff *ctx, __u64 nhoff)
 {
 	return load_half(ctx, nhoff + offsetof(struct iphdr, frag_off))
@@ -189,7 +156,8 @@ static __always_inline void parse_ip_proto(struct __sk_buff *skb,
 	}
 }
 
-PROG(PARSE_IP)(struct __sk_buff *skb)
+PROG_SOCKET_FILTER
+int bpf_func_ip(struct __sk_buff *skb)
 {
 	struct globals *g = this_cpu_globals();
 	__u32 nhoff, verlen, ip_proto;
@@ -217,7 +185,8 @@ PROG(PARSE_IP)(struct __sk_buff *skb)
 	return 0;
 }
 
-PROG(PARSE_IPV6)(struct __sk_buff *skb)
+PROG_SOCKET_FILTER
+int bpf_func_ipv6(struct __sk_buff *skb)
 {
 	struct globals *g = this_cpu_globals();
 	__u32 nhoff, ip_proto;
@@ -240,7 +209,8 @@ PROG(PARSE_IPV6)(struct __sk_buff *skb)
 	return 0;
 }
 
-PROG(PARSE_VLAN)(struct __sk_buff *skb)
+PROG_SOCKET_FILTER
+int bpf_func_vlan(struct __sk_buff *skb)
 {
 	__u32 nhoff, proto;
 
@@ -256,7 +226,8 @@ PROG(PARSE_VLAN)(struct __sk_buff *skb)
 	return 0;
 }
 
-PROG(PARSE_MPLS)(struct __sk_buff *skb)
+PROG_SOCKET_FILTER
+int bpf_func_mpls(struct __sk_buff *skb)
 {
 	__u32 nhoff, label;
 
@@ -279,7 +250,49 @@ PROG(PARSE_MPLS)(struct __sk_buff *skb)
 	return 0;
 }
 
-SEC("socket/0")
+struct {
+	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
+	__uint(key_size, sizeof(u32));
+	__uint(max_entries, 8);
+	__array(values, u32 (void *));
+} prog_array_init SEC(".maps") = {
+	.values = {
+		[PARSE_VLAN] = (void *)&bpf_func_vlan,
+		[PARSE_IP]   = (void *)&bpf_func_ip,
+		[PARSE_IPV6] = (void *)&bpf_func_ipv6,
+		[PARSE_MPLS] = (void *)&bpf_func_mpls,
+	},
+};
+
+/* Protocol dispatch routine. It tail-calls next BPF program depending
+ * on eth proto. Note, we could have used ...
+ *
+ *   bpf_tail_call(skb, &prog_array_init, proto);
+ *
+ * ... but it would need large prog_array and cannot be optimised given
+ * the map key is not static.
+ */
+static inline void parse_eth_proto(struct __sk_buff *skb, u32 proto)
+{
+	switch (proto) {
+	case ETH_P_8021Q:
+	case ETH_P_8021AD:
+		bpf_tail_call(skb, &prog_array_init, PARSE_VLAN);
+		break;
+	case ETH_P_MPLS_UC:
+	case ETH_P_MPLS_MC:
+		bpf_tail_call(skb, &prog_array_init, PARSE_MPLS);
+		break;
+	case ETH_P_IP:
+		bpf_tail_call(skb, &prog_array_init, PARSE_IP);
+		break;
+	case ETH_P_IPV6:
+		bpf_tail_call(skb, &prog_array_init, PARSE_IPV6);
+		break;
+	}
+}
+
+PROG_SOCKET_FILTER
 int main_prog(struct __sk_buff *skb)
 {
 	__u32 nhoff = ETH_HLEN;
diff --git a/samples/bpf/sockex3_user.c b/samples/bpf/sockex3_user.c
index cd6fa79df900..56044acbd25d 100644
--- a/samples/bpf/sockex3_user.c
+++ b/samples/bpf/sockex3_user.c
@@ -24,10 +24,9 @@ struct pair {
 
 int main(int argc, char **argv)
 {
-	int i, sock, key, fd, main_prog_fd, jmp_table_fd, hash_map_fd;
+	int i, sock, fd, main_prog_fd, hash_map_fd;
 	struct bpf_program *prog;
 	struct bpf_object *obj;
-	const char *section;
 	char filename[256];
 	FILE *f;
 
@@ -45,26 +44,24 @@ int main(int argc, char **argv)
 		goto cleanup;
 	}
 
-	jmp_table_fd = bpf_object__find_map_fd_by_name(obj, "jmp_table");
 	hash_map_fd = bpf_object__find_map_fd_by_name(obj, "hash_map");
-	if (jmp_table_fd < 0 || hash_map_fd < 0) {
+	if (hash_map_fd < 0) {
 		fprintf(stderr, "ERROR: finding a map in obj file failed\n");
 		goto cleanup;
 	}
 
+	/* find BPF main program */
+	main_prog_fd = 0;
 	bpf_object__for_each_program(prog, obj) {
 		fd = bpf_program__fd(prog);
 
-		section = bpf_program__section_name(prog);
-		if (sscanf(section, "socket/%d", &key) != 1) {
-			fprintf(stderr, "ERROR: finding prog failed\n");
-			goto cleanup;
-		}
-
-		if (key == 0)
+		if (!strcmp(bpf_program__name(prog), "main_prog"))
 			main_prog_fd = fd;
-		else
-			bpf_map_update_elem(jmp_table_fd, &key, &fd, BPF_ANY);
+	}
+
+	if (main_prog_fd == 0) {
+		fprintf(stderr, "ERROR: can't find main_prog\n");
+		goto cleanup;
 	}
 
 	sock = open_raw_sock("lo");
-- 
2.31.1


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

* Re: [PATCH bpf-next] samples/bpf: Fix sockex3 error: missing BPF prog type
  2022-11-05  6:48                 ` [PATCH bpf-next] samples/bpf: Fix sockex3 error: " Rong Tao
@ 2022-11-08  1:14                   ` Andrii Nakryiko
  2022-11-08  1:20                   ` patchwork-bot+netdevbpf
  1 sibling, 0 replies; 12+ messages in thread
From: Andrii Nakryiko @ 2022-11-08  1:14 UTC (permalink / raw)
  To: Rong Tao
  Cc: andrii, ast, bpf, daniel, haoluo, john.fastabend, jolsa, kpsingh,
	linux-kernel, martin.lau, rongtao, sdf, song, yhs

On Fri, Nov 4, 2022 at 11:48 PM Rong Tao <rtoax@foxmail.com> wrote:
>
> From: Rong Tao <rongtao@cestc.cn>
>
> since commit 450b167fb9be("libbpf: clean up SEC() handling"),
> sec_def_matches() does not recognize "socket/xxx" as "socket", therefore,
> the BPF program type is not recognized.
>
> Instead of sockex3_user.c parsing section names to get the BPF program fd.
> We use the program array map to assign a static index to each BPF program
> (get inspired by selftests/bpf progs/test_prog_array_init.c).
> Therefore, use SEC("socket") as section name instead of SEC("socket/xxx"),
> so that the BPF program is parsed to SOCKET_FILTER type. The "missing BPF
> prog type" problem is solved.
>
> How to reproduce this error:
> $ cd samples/bpf
> $ sudo ./sockex3
> libbpf: prog 'bpf_func_PARSE_IP': missing BPF prog type, check ELF section name 'socket/3'
> libbpf: prog 'bpf_func_PARSE_IP': failed to load: -22
> libbpf: failed to load object './sockex3_kern.o'
> ERROR: loading BPF object file failed
>
> Signed-off-by: Rong Tao <rongtao@cestc.cn>
> ---
>  samples/bpf/sockex3_kern.c | 95 ++++++++++++++++++++++----------------
>  samples/bpf/sockex3_user.c | 23 ++++-----
>  2 files changed, 64 insertions(+), 54 deletions(-)
>
> diff --git a/samples/bpf/sockex3_kern.c b/samples/bpf/sockex3_kern.c
> index b363503357e5..26d916834865 100644
> --- a/samples/bpf/sockex3_kern.c
> +++ b/samples/bpf/sockex3_kern.c
> @@ -17,47 +17,12 @@
>  #define IP_MF          0x2000
>  #define IP_OFFSET      0x1FFF
>
> -#define PROG(F) SEC("socket/"__stringify(F)) int bpf_func_##F
> -
> -struct {
> -       __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
> -       __uint(key_size, sizeof(u32));
> -       __uint(value_size, sizeof(u32));
> -       __uint(max_entries, 8);
> -} jmp_table SEC(".maps");
> -
>  #define PARSE_VLAN 1
>  #define PARSE_MPLS 2
>  #define PARSE_IP 3
>  #define PARSE_IPV6 4
>
> -/* Protocol dispatch routine. It tail-calls next BPF program depending
> - * on eth proto. Note, we could have used ...
> - *
> - *   bpf_tail_call(skb, &jmp_table, proto);
> - *
> - * ... but it would need large prog_array and cannot be optimised given
> - * the map key is not static.
> - */
> -static inline void parse_eth_proto(struct __sk_buff *skb, u32 proto)
> -{
> -       switch (proto) {
> -       case ETH_P_8021Q:
> -       case ETH_P_8021AD:
> -               bpf_tail_call(skb, &jmp_table, PARSE_VLAN);
> -               break;
> -       case ETH_P_MPLS_UC:
> -       case ETH_P_MPLS_MC:
> -               bpf_tail_call(skb, &jmp_table, PARSE_MPLS);
> -               break;
> -       case ETH_P_IP:
> -               bpf_tail_call(skb, &jmp_table, PARSE_IP);
> -               break;
> -       case ETH_P_IPV6:
> -               bpf_tail_call(skb, &jmp_table, PARSE_IPV6);
> -               break;
> -       }
> -}
> +#define PROG_SOCKET_FILTER     SEC("socket")

I dropped this and made SEC("socket") annotations explicit everywhere.
Applied to bpf-next, thank.

>
>  struct vlan_hdr {
>         __be16 h_vlan_TCI;
> @@ -74,6 +39,8 @@ struct flow_key_record {
>         __u32 ip_proto;
>  };
>

[...]

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

* Re: [PATCH bpf-next] samples/bpf: Fix sockex3 error: missing BPF prog type
  2022-11-05  6:48                 ` [PATCH bpf-next] samples/bpf: Fix sockex3 error: " Rong Tao
  2022-11-08  1:14                   ` Andrii Nakryiko
@ 2022-11-08  1:20                   ` patchwork-bot+netdevbpf
  1 sibling, 0 replies; 12+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-11-08  1:20 UTC (permalink / raw)
  To: Rong Tao
  Cc: andrii.nakryiko, andrii, ast, bpf, daniel, haoluo,
	john.fastabend, jolsa, kpsingh, linux-kernel, martin.lau,
	rongtao, sdf, song, yhs

Hello:

This patch was applied to bpf/bpf-next.git (master)
by Andrii Nakryiko <andrii@kernel.org>:

On Sat,  5 Nov 2022 14:48:00 +0800 you wrote:
> From: Rong Tao <rongtao@cestc.cn>
> 
> since commit 450b167fb9be("libbpf: clean up SEC() handling"),
> sec_def_matches() does not recognize "socket/xxx" as "socket", therefore,
> the BPF program type is not recognized.
> 
> Instead of sockex3_user.c parsing section names to get the BPF program fd.
> We use the program array map to assign a static index to each BPF program
> (get inspired by selftests/bpf progs/test_prog_array_init.c).
> Therefore, use SEC("socket") as section name instead of SEC("socket/xxx"),
> so that the BPF program is parsed to SOCKET_FILTER type. The "missing BPF
> prog type" problem is solved.
> 
> [...]

Here is the summary with links:
  - [bpf-next] samples/bpf: Fix sockex3 error: missing BPF prog type
    https://git.kernel.org/bpf/bpf-next/c/e5659e4e19e4

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

end of thread, other threads:[~2022-11-08  1:20 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-27 13:33 [PATCH] samples/bpf: Fix sockex3: missing BPF prog type Rong Tao
2022-10-27 13:38 ` [PATCH bpf-next] " Rong Tao
2022-10-27 20:15   ` Andrii Nakryiko
2022-10-28  1:01     ` [PATCH] " Rong Tao
2022-10-28 17:09       ` Andrii Nakryiko
2022-10-29  7:53         ` [PATCH bpf-next] " Rong Tao
2022-11-03 18:38           ` Andrii Nakryiko
2022-11-04  3:17             ` Rong Tao
2022-11-04 22:53               ` Andrii Nakryiko
2022-11-05  6:48                 ` [PATCH bpf-next] samples/bpf: Fix sockex3 error: " Rong Tao
2022-11-08  1:14                   ` Andrii Nakryiko
2022-11-08  1:20                   ` patchwork-bot+netdevbpf

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).