2018-10-06 07:40:00 +08:00
|
|
|
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
2018-07-11 05:43:04 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
|
|
|
|
* Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
|
|
|
|
* Copyright (C) 2015 Huawei Inc.
|
|
|
|
* Copyright (C) 2017 Nicira, Inc.
|
|
|
|
*/
|
|
|
|
|
2018-11-30 07:31:45 +08:00
|
|
|
#undef _GNU_SOURCE
|
2018-07-11 05:43:04 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "libbpf.h"
|
libbpf: Streamline error reporting for high-level APIs
Implement changes to error reporting for high-level libbpf APIs to make them
less surprising and less error-prone to users:
- in all the cases when error happens, errno is set to an appropriate error
value;
- in libbpf 1.0 mode, all pointer-returning APIs return NULL on error and
error code is communicated through errno; this applies both to APIs that
already returned NULL before (so now they communicate more detailed error
codes), as well as for many APIs that used ERR_PTR() macro and encoded
error numbers as fake pointers.
- in legacy (default) mode, those APIs that were returning ERR_PTR(err),
continue doing so, but still set errno.
With these changes, errno can be always used to extract actual error,
regardless of legacy or libbpf 1.0 modes. This is utilized internally in
libbpf in places where libbpf uses it's own high-level APIs.
libbpf_get_error() is adapted to handle both cases completely transparently to
end-users (and is used by libbpf consistently as well).
More context, justification, and discussion can be found in "Libbpf: the road
to v1.0" document ([0]).
[0] https://docs.google.com/document/d/1UyjTZuPFWiPFyKk1tV5an11_iaRuec6U-ZESZ54nNTY
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>
Link: https://lore.kernel.org/bpf/20210525035935.1461796-5-andrii@kernel.org
2021-05-25 11:59:34 +08:00
|
|
|
#include "libbpf_internal.h"
|
2018-07-11 05:43:04 +08:00
|
|
|
|
libbpf: Poison kernel-only integer types
It's been a recurring issue with types like u32 slipping into libbpf source
code accidentally. This is not detected during builds inside kernel source
tree, but becomes a compilation error in libbpf's Github repo. Libbpf is
supposed to use only __{s,u}{8,16,32,64} typedefs, so poison {s,u}{8,16,32,64}
explicitly in every .c file. Doing that in a bit more centralized way, e.g.,
inside libbpf_internal.h breaks selftests, which are both using kernel u32 and
libbpf_internal.h.
This patch also fixes a new u32 occurence in libbpf.c, added recently.
Fixes: 590a00888250 ("bpf: libbpf: Add STRUCT_OPS support")
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Link: https://lore.kernel.org/bpf/20200110181916.271446-1-andriin@fb.com
2020-01-11 02:19:16 +08:00
|
|
|
/* make sure libbpf doesn't use kernel-only integer typedefs */
|
|
|
|
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
|
|
|
|
2018-07-11 05:43:04 +08:00
|
|
|
#define ERRNO_OFFSET(e) ((e) - __LIBBPF_ERRNO__START)
|
|
|
|
#define ERRCODE_OFFSET(c) ERRNO_OFFSET(LIBBPF_ERRNO__##c)
|
|
|
|
#define NR_ERRNO (__LIBBPF_ERRNO__END - __LIBBPF_ERRNO__START)
|
|
|
|
|
|
|
|
static const char *libbpf_strerror_table[NR_ERRNO] = {
|
|
|
|
[ERRCODE_OFFSET(LIBELF)] = "Something wrong in libelf",
|
|
|
|
[ERRCODE_OFFSET(FORMAT)] = "BPF object format invalid",
|
|
|
|
[ERRCODE_OFFSET(KVERSION)] = "'version' section incorrect or lost",
|
|
|
|
[ERRCODE_OFFSET(ENDIAN)] = "Endian mismatch",
|
|
|
|
[ERRCODE_OFFSET(INTERNAL)] = "Internal error in libbpf",
|
|
|
|
[ERRCODE_OFFSET(RELOC)] = "Relocation failed",
|
|
|
|
[ERRCODE_OFFSET(VERIFY)] = "Kernel verifier blocks program loading",
|
|
|
|
[ERRCODE_OFFSET(PROG2BIG)] = "Program too big",
|
|
|
|
[ERRCODE_OFFSET(KVER)] = "Incorrect kernel version",
|
|
|
|
[ERRCODE_OFFSET(PROGTYPE)] = "Kernel doesn't support this program type",
|
|
|
|
[ERRCODE_OFFSET(WRNGPID)] = "Wrong pid in netlink message",
|
|
|
|
[ERRCODE_OFFSET(INVSEQ)] = "Invalid netlink sequence",
|
tools/bpf: add more netlink functionalities in lib/bpf
This patch added a few netlink attribute parsing functions
and the netlink API functions to query networking links, tc classes,
tc qdiscs and tc filters. For example, the following API is
to get networking links:
int nl_get_link(int sock, unsigned int nl_pid,
dump_nlmsg_t dump_link_nlmsg,
void *cookie);
Note that when the API is called, the user also provided a
callback function with the following signature:
int (*dump_nlmsg_t)(void *cookie, void *msg, struct nlattr **tb);
The "cookie" is the parameter the user passed to the API and will
be available for the callback function.
The "msg" is the information about the result, e.g., ifinfomsg or
tcmsg. The "tb" is the parsed netlink attributes.
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-09-06 07:58:05 +08:00
|
|
|
[ERRCODE_OFFSET(NLPARSE)] = "Incorrect netlink message parsing",
|
2018-07-11 05:43:04 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
int libbpf_strerror(int err, char *buf, size_t size)
|
|
|
|
{
|
2022-12-10 16:20:45 +08:00
|
|
|
int ret;
|
|
|
|
|
2018-07-11 05:43:04 +08:00
|
|
|
if (!buf || !size)
|
libbpf: Streamline error reporting for high-level APIs
Implement changes to error reporting for high-level libbpf APIs to make them
less surprising and less error-prone to users:
- in all the cases when error happens, errno is set to an appropriate error
value;
- in libbpf 1.0 mode, all pointer-returning APIs return NULL on error and
error code is communicated through errno; this applies both to APIs that
already returned NULL before (so now they communicate more detailed error
codes), as well as for many APIs that used ERR_PTR() macro and encoded
error numbers as fake pointers.
- in legacy (default) mode, those APIs that were returning ERR_PTR(err),
continue doing so, but still set errno.
With these changes, errno can be always used to extract actual error,
regardless of legacy or libbpf 1.0 modes. This is utilized internally in
libbpf in places where libbpf uses it's own high-level APIs.
libbpf_get_error() is adapted to handle both cases completely transparently to
end-users (and is used by libbpf consistently as well).
More context, justification, and discussion can be found in "Libbpf: the road
to v1.0" document ([0]).
[0] https://docs.google.com/document/d/1UyjTZuPFWiPFyKk1tV5an11_iaRuec6U-ZESZ54nNTY
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>
Link: https://lore.kernel.org/bpf/20210525035935.1461796-5-andrii@kernel.org
2021-05-25 11:59:34 +08:00
|
|
|
return libbpf_err(-EINVAL);
|
2018-07-11 05:43:04 +08:00
|
|
|
|
|
|
|
err = err > 0 ? err : -err;
|
|
|
|
|
|
|
|
if (err < __LIBBPF_ERRNO__START) {
|
|
|
|
ret = strerror_r(err, buf, size);
|
|
|
|
buf[size - 1] = '\0';
|
libbpf: Streamline error reporting for high-level APIs
Implement changes to error reporting for high-level libbpf APIs to make them
less surprising and less error-prone to users:
- in all the cases when error happens, errno is set to an appropriate error
value;
- in libbpf 1.0 mode, all pointer-returning APIs return NULL on error and
error code is communicated through errno; this applies both to APIs that
already returned NULL before (so now they communicate more detailed error
codes), as well as for many APIs that used ERR_PTR() macro and encoded
error numbers as fake pointers.
- in legacy (default) mode, those APIs that were returning ERR_PTR(err),
continue doing so, but still set errno.
With these changes, errno can be always used to extract actual error,
regardless of legacy or libbpf 1.0 modes. This is utilized internally in
libbpf in places where libbpf uses it's own high-level APIs.
libbpf_get_error() is adapted to handle both cases completely transparently to
end-users (and is used by libbpf consistently as well).
More context, justification, and discussion can be found in "Libbpf: the road
to v1.0" document ([0]).
[0] https://docs.google.com/document/d/1UyjTZuPFWiPFyKk1tV5an11_iaRuec6U-ZESZ54nNTY
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>
Link: https://lore.kernel.org/bpf/20210525035935.1461796-5-andrii@kernel.org
2021-05-25 11:59:34 +08:00
|
|
|
return libbpf_err_errno(ret);
|
2018-07-11 05:43:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (err < __LIBBPF_ERRNO__END) {
|
|
|
|
const char *msg;
|
|
|
|
|
|
|
|
msg = libbpf_strerror_table[ERRNO_OFFSET(err)];
|
2022-12-10 16:20:45 +08:00
|
|
|
ret = snprintf(buf, size, "%s", msg);
|
2018-07-11 05:43:04 +08:00
|
|
|
buf[size - 1] = '\0';
|
2022-12-10 16:20:45 +08:00
|
|
|
/* The length of the buf and msg is positive.
|
|
|
|
* A negative number may be returned only when the
|
|
|
|
* size exceeds INT_MAX. Not likely to appear.
|
|
|
|
*/
|
|
|
|
if (ret >= size)
|
|
|
|
return libbpf_err(-ERANGE);
|
2018-07-11 05:43:04 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-12-10 16:20:45 +08:00
|
|
|
ret = snprintf(buf, size, "Unknown libbpf error %d", err);
|
2018-07-11 05:43:04 +08:00
|
|
|
buf[size - 1] = '\0';
|
2022-12-10 16:20:45 +08:00
|
|
|
if (ret >= size)
|
|
|
|
return libbpf_err(-ERANGE);
|
libbpf: Streamline error reporting for high-level APIs
Implement changes to error reporting for high-level libbpf APIs to make them
less surprising and less error-prone to users:
- in all the cases when error happens, errno is set to an appropriate error
value;
- in libbpf 1.0 mode, all pointer-returning APIs return NULL on error and
error code is communicated through errno; this applies both to APIs that
already returned NULL before (so now they communicate more detailed error
codes), as well as for many APIs that used ERR_PTR() macro and encoded
error numbers as fake pointers.
- in legacy (default) mode, those APIs that were returning ERR_PTR(err),
continue doing so, but still set errno.
With these changes, errno can be always used to extract actual error,
regardless of legacy or libbpf 1.0 modes. This is utilized internally in
libbpf in places where libbpf uses it's own high-level APIs.
libbpf_get_error() is adapted to handle both cases completely transparently to
end-users (and is used by libbpf consistently as well).
More context, justification, and discussion can be found in "Libbpf: the road
to v1.0" document ([0]).
[0] https://docs.google.com/document/d/1UyjTZuPFWiPFyKk1tV5an11_iaRuec6U-ZESZ54nNTY
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>
Link: https://lore.kernel.org/bpf/20210525035935.1461796-5-andrii@kernel.org
2021-05-25 11:59:34 +08:00
|
|
|
return libbpf_err(-ENOENT);
|
2018-07-11 05:43:04 +08:00
|
|
|
}
|