Re: [PATCH bpf-next v5 2/4] libbpf: add error reporting in XDP
Hi, Sorry for the delay, missed the mail. On Sat, 2018-01-06 at 22:16 +0100, Daniel Borkmann wrote: > On 01/04/2018 09:21 AM, Eric Leblond wrote: > > Parse netlink ext attribute to get the error message returned by > > the card. Code is partially take from libnl. > > > > Signed-off-by: Eric Leblond> > Acked-by: Alexei Starovoitov > > --- > > samples/bpf/Makefile | 2 +- > > tools/lib/bpf/Build| 2 +- > > tools/lib/bpf/bpf.c| 10 ++- > > tools/lib/bpf/nlattr.c | 187 > > + > > tools/lib/bpf/nlattr.h | 70 ++ > > 5 files changed, 268 insertions(+), 3 deletions(-) > > create mode 100644 tools/lib/bpf/nlattr.c > > create mode 100644 tools/lib/bpf/nlattr.h > > > > diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile > > index 4fb944a7ecf8..c889ebcba9b3 100644 > > --- a/samples/bpf/Makefile > > +++ b/samples/bpf/Makefile > > @@ -44,7 +44,7 @@ hostprogs-y += xdp_monitor > > hostprogs-y += syscall_tp > > > > # Libbpf dependencies > > -LIBBPF := ../../tools/lib/bpf/bpf.o > > +LIBBPF := ../../tools/lib/bpf/bpf.o ../../tools/lib/bpf/nlattr.o > > CGROUP_HELPERS := > > ../../tools/testing/selftests/bpf/cgroup_helpers.o > > > > test_lru_dist-objs := test_lru_dist.o $(LIBBPF) > > diff --git a/tools/lib/bpf/Build b/tools/lib/bpf/Build > > index d8749756352d..64c679d67109 100644 > > --- a/tools/lib/bpf/Build > > +++ b/tools/lib/bpf/Build > > @@ -1 +1 @@ > > -libbpf-y := libbpf.o bpf.o > > +libbpf-y := libbpf.o bpf.o nlattr.o > > diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c > > index e6c61035b64c..10d71b9fdbd0 100644 > > --- a/tools/lib/bpf/bpf.c > > +++ b/tools/lib/bpf/bpf.c > > @@ -26,6 +26,7 @@ > > #include > > #include "bpf.h" > > #include "libbpf.h" > > +#include "nlattr.h" > > #include > > #include > > #include > > @@ -440,6 +441,7 @@ int bpf_set_link_xdp_fd(int ifindex, int fd, > > __u32 flags) > > struct nlmsghdr *nh; > > struct nlmsgerr *err; > > socklen_t addrlen; > > + int one; > > Hmm, it's not initialized here to 1 ... > > > memset(, 0, sizeof(sa)); > > sa.nl_family = AF_NETLINK; > > @@ -449,6 +451,11 @@ int bpf_set_link_xdp_fd(int ifindex, int fd, > > __u32 flags) > > return -errno; > > } > > > > + if (setsockopt(sock, SOL_NETLINK, NETLINK_EXT_ACK, > > + , sizeof(one)) < 0) { > > ... so we turn it on by chance here. Indeed, fixing that. > > + fprintf(stderr, "Netlink error reporting not > > supported\n"); > > + } > > + > > if (bind(sock, (struct sockaddr *), sizeof(sa)) < 0) { > > ret = -errno; > > goto cleanup; > > @@ -524,7 +531,8 @@ int bpf_set_link_xdp_fd(int ifindex, int fd, > > __u32 flags) > > err = (struct nlmsgerr *)NLMSG_DATA(nh); > > if (!err->error) > > continue; > > - ret = err->error; > > + ret = -err->error; > > This one looks strange. Your prior patch added the 'ret = err->error' > and this one negates it. Which variant is the correct version? From > digging into the kernel code, my take is that 'ret = err->error' was > the correct variant since it already holds the negative error code. > Could you double check? Yes all netlink_ack usage I have seen are using the negative value of the error. Fixing that too. BR, -- Eric Leblond Blog: https://home.regit.org/
Re: [PATCH bpf-next v5 2/4] libbpf: add error reporting in XDP
On 01/04/2018 09:21 AM, Eric Leblond wrote: > Parse netlink ext attribute to get the error message returned by > the card. Code is partially take from libnl. > > Signed-off-by: Eric Leblond> Acked-by: Alexei Starovoitov > --- > samples/bpf/Makefile | 2 +- > tools/lib/bpf/Build| 2 +- > tools/lib/bpf/bpf.c| 10 ++- > tools/lib/bpf/nlattr.c | 187 > + > tools/lib/bpf/nlattr.h | 70 ++ > 5 files changed, 268 insertions(+), 3 deletions(-) > create mode 100644 tools/lib/bpf/nlattr.c > create mode 100644 tools/lib/bpf/nlattr.h > > diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile > index 4fb944a7ecf8..c889ebcba9b3 100644 > --- a/samples/bpf/Makefile > +++ b/samples/bpf/Makefile > @@ -44,7 +44,7 @@ hostprogs-y += xdp_monitor > hostprogs-y += syscall_tp > > # Libbpf dependencies > -LIBBPF := ../../tools/lib/bpf/bpf.o > +LIBBPF := ../../tools/lib/bpf/bpf.o ../../tools/lib/bpf/nlattr.o > CGROUP_HELPERS := ../../tools/testing/selftests/bpf/cgroup_helpers.o > > test_lru_dist-objs := test_lru_dist.o $(LIBBPF) > diff --git a/tools/lib/bpf/Build b/tools/lib/bpf/Build > index d8749756352d..64c679d67109 100644 > --- a/tools/lib/bpf/Build > +++ b/tools/lib/bpf/Build > @@ -1 +1 @@ > -libbpf-y := libbpf.o bpf.o > +libbpf-y := libbpf.o bpf.o nlattr.o > diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c > index e6c61035b64c..10d71b9fdbd0 100644 > --- a/tools/lib/bpf/bpf.c > +++ b/tools/lib/bpf/bpf.c > @@ -26,6 +26,7 @@ > #include > #include "bpf.h" > #include "libbpf.h" > +#include "nlattr.h" > #include > #include > #include > @@ -440,6 +441,7 @@ int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags) > struct nlmsghdr *nh; > struct nlmsgerr *err; > socklen_t addrlen; > + int one; Hmm, it's not initialized here to 1 ... > memset(, 0, sizeof(sa)); > sa.nl_family = AF_NETLINK; > @@ -449,6 +451,11 @@ int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags) > return -errno; > } > > + if (setsockopt(sock, SOL_NETLINK, NETLINK_EXT_ACK, > +, sizeof(one)) < 0) { ... so we turn it on by chance here. > + fprintf(stderr, "Netlink error reporting not supported\n"); > + } > + > if (bind(sock, (struct sockaddr *), sizeof(sa)) < 0) { > ret = -errno; > goto cleanup; > @@ -524,7 +531,8 @@ int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags) > err = (struct nlmsgerr *)NLMSG_DATA(nh); > if (!err->error) > continue; > - ret = err->error; > + ret = -err->error; This one looks strange. Your prior patch added the 'ret = err->error' and this one negates it. Which variant is the correct version? From digging into the kernel code, my take is that 'ret = err->error' was the correct variant since it already holds the negative error code. Could you double check? > + nla_dump_errormsg(nh); > goto cleanup; > case NLMSG_DONE: > break; Thanks, Daniel
[PATCH bpf-next v5 2/4] libbpf: add error reporting in XDP
Parse netlink ext attribute to get the error message returned by the card. Code is partially take from libnl. Signed-off-by: Eric LeblondAcked-by: Alexei Starovoitov --- samples/bpf/Makefile | 2 +- tools/lib/bpf/Build| 2 +- tools/lib/bpf/bpf.c| 10 ++- tools/lib/bpf/nlattr.c | 187 + tools/lib/bpf/nlattr.h | 70 ++ 5 files changed, 268 insertions(+), 3 deletions(-) create mode 100644 tools/lib/bpf/nlattr.c create mode 100644 tools/lib/bpf/nlattr.h diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 4fb944a7ecf8..c889ebcba9b3 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -44,7 +44,7 @@ hostprogs-y += xdp_monitor hostprogs-y += syscall_tp # Libbpf dependencies -LIBBPF := ../../tools/lib/bpf/bpf.o +LIBBPF := ../../tools/lib/bpf/bpf.o ../../tools/lib/bpf/nlattr.o CGROUP_HELPERS := ../../tools/testing/selftests/bpf/cgroup_helpers.o test_lru_dist-objs := test_lru_dist.o $(LIBBPF) diff --git a/tools/lib/bpf/Build b/tools/lib/bpf/Build index d8749756352d..64c679d67109 100644 --- a/tools/lib/bpf/Build +++ b/tools/lib/bpf/Build @@ -1 +1 @@ -libbpf-y := libbpf.o bpf.o +libbpf-y := libbpf.o bpf.o nlattr.o diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index e6c61035b64c..10d71b9fdbd0 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -26,6 +26,7 @@ #include #include "bpf.h" #include "libbpf.h" +#include "nlattr.h" #include #include #include @@ -440,6 +441,7 @@ int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags) struct nlmsghdr *nh; struct nlmsgerr *err; socklen_t addrlen; + int one; memset(, 0, sizeof(sa)); sa.nl_family = AF_NETLINK; @@ -449,6 +451,11 @@ int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags) return -errno; } + if (setsockopt(sock, SOL_NETLINK, NETLINK_EXT_ACK, + , sizeof(one)) < 0) { + fprintf(stderr, "Netlink error reporting not supported\n"); + } + if (bind(sock, (struct sockaddr *), sizeof(sa)) < 0) { ret = -errno; goto cleanup; @@ -524,7 +531,8 @@ int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags) err = (struct nlmsgerr *)NLMSG_DATA(nh); if (!err->error) continue; - ret = err->error; + ret = -err->error; + nla_dump_errormsg(nh); goto cleanup; case NLMSG_DONE: break; diff --git a/tools/lib/bpf/nlattr.c b/tools/lib/bpf/nlattr.c new file mode 100644 index ..4719434278b2 --- /dev/null +++ b/tools/lib/bpf/nlattr.c @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: LGPL-2.1 + +/* + * NETLINK Netlink attributes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2013 Thomas Graf + */ + +#include +#include "nlattr.h" +#include +#include +#include + +static uint16_t nla_attr_minlen[NLA_TYPE_MAX+1] = { + [NLA_U8]= sizeof(uint8_t), + [NLA_U16] = sizeof(uint16_t), + [NLA_U32] = sizeof(uint32_t), + [NLA_U64] = sizeof(uint64_t), + [NLA_STRING]= 1, + [NLA_FLAG] = 0, +}; + +static int nla_len(const struct nlattr *nla) +{ + return nla->nla_len - NLA_HDRLEN; +} + +static struct nlattr *nla_next(const struct nlattr *nla, int *remaining) +{ + int totlen = NLA_ALIGN(nla->nla_len); + + *remaining -= totlen; + return (struct nlattr *) ((char *) nla + totlen); +} + +static int nla_ok(const struct nlattr *nla, int remaining) +{ + return remaining >= sizeof(*nla) && + nla->nla_len >= sizeof(*nla) && + nla->nla_len <= remaining; +} + +static void *nla_data(const struct nlattr *nla) +{ + return (char *) nla + NLA_HDRLEN; +} + +static int nla_type(const struct nlattr *nla) +{ + return nla->nla_type & NLA_TYPE_MASK; +} + +static int validate_nla(struct nlattr *nla, int maxtype, + struct nla_policy *policy) +{ + struct nla_policy *pt; + unsigned int minlen = 0; + int type = nla_type(nla); + + if (type < 0 || type > maxtype) + return 0; + + pt = [type]; + + if (pt->type > NLA_TYPE_MAX) + return 0; + + if (pt->minlen) + minlen = pt->minlen; + else if (pt->type != NLA_UNSPEC) + minlen = nla_attr_minlen[pt->type]; + + if (nla_len(nla) < minlen) + return -1; + + if (pt->maxlen && nla_len(nla) > pt->maxlen) + return -1; + +