2022-10-27 13:52:06

by Rong Tao

[permalink] [raw]
Subject: [PATCH bpf-next] samples/bpf: Fix sockex3: missing BPF prog type

From: Rong Tao <[email protected]>

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 <[email protected]>
---
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



2022-10-27 20:21:19

by Andrii Nakryiko

[permalink] [raw]
Subject: Re: [PATCH bpf-next] samples/bpf: Fix sockex3: missing BPF prog type

On Thu, Oct 27, 2022 at 6:38 AM Rong Tao <[email protected]> wrote:
>
> From: Rong Tao <[email protected]>
>
> 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 <[email protected]>
> ---
> 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
>

2022-10-28 01:07:19

by Rong Tao

[permalink] [raw]
Subject: Re: [PATCH] samples/bpf: Fix sockex3: missing BPF prog type

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;
}

2022-10-28 18:38:19

by Andrii Nakryiko

[permalink] [raw]
Subject: Re: [PATCH] samples/bpf: Fix sockex3: missing BPF prog type

On Thu, Oct 27, 2022 at 6:01 PM Rong Tao <[email protected]> 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;
> }

2022-10-29 08:52:31

by Rong Tao

[permalink] [raw]
Subject: [PATCH bpf-next] samples/bpf: Fix sockex3: missing BPF prog type

From: Rong Tao <[email protected]>

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 <[email protected]>
---
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


2022-11-03 19:30:46

by Andrii Nakryiko

[permalink] [raw]
Subject: Re: [PATCH bpf-next] samples/bpf: Fix sockex3: missing BPF prog type

On Sat, Oct 29, 2022 at 12:53 AM Rong Tao <[email protected]> wrote:
>
> From: Rong Tao <[email protected]>
>
> 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 <[email protected]>
> ---

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
>

2022-11-04 03:28:27

by Rong Tao

[permalink] [raw]
Subject: Re: Re: [PATCH bpf-next] samples/bpf: Fix sockex3: missing BPF prog type

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/[email protected]/

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.


2022-11-04 23:12:42

by Andrii Nakryiko

[permalink] [raw]
Subject: Re: Re: [PATCH bpf-next] samples/bpf: Fix sockex3: missing BPF prog type

On Thu, Nov 3, 2022 at 8:17 PM Rong Tao <[email protected]> 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
>

[...]

2022-11-05 07:12:24

by Rong Tao

[permalink] [raw]
Subject: [PATCH bpf-next] samples/bpf: Fix sockex3 error: missing BPF prog type

From: Rong Tao <[email protected]>

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 <[email protected]>
---
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


2022-11-08 01:56:51

by Andrii Nakryiko

[permalink] [raw]
Subject: Re: [PATCH bpf-next] samples/bpf: Fix sockex3 error: missing BPF prog type

On Fri, Nov 4, 2022 at 11:48 PM Rong Tao <[email protected]> wrote:
>
> From: Rong Tao <[email protected]>
>
> 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 <[email protected]>
> ---
> 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;
> };
>

[...]

2022-11-08 02:04:47

by patchwork-bot+netdevbpf

[permalink] [raw]
Subject: Re: [PATCH bpf-next] samples/bpf: Fix sockex3 error: missing BPF prog type

Hello:

This patch was applied to bpf/bpf-next.git (master)
by Andrii Nakryiko <[email protected]>:

On Sat, 5 Nov 2022 14:48:00 +0800 you wrote:
> From: Rong Tao <[email protected]>
>
> 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