All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Leblond <eric@regit.org>
To: daniel@iogearbox.net,
	Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>,
	Philippe Ombredanne <pombredanne@nexb.com>
Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	Eric Leblond <eric@regit.org>
Subject: [PATCH bpf-next v4 1/3] libbpf: add function to setup XDP
Date: Sat, 30 Dec 2017 21:41:14 +0100	[thread overview]
Message-ID: <20171230204116.30871-2-eric@regit.org> (raw)
In-Reply-To: <20171230204116.30871-1-eric@regit.org>

Most of the code is taken from set_link_xdp_fd() in bpf_load.c and
slightly modified to be library compliant.

Signed-off-by: Eric Leblond <eric@regit.org>
Acked-by: Alexei Starovoitov <ast@kernel.org>
---
 tools/lib/bpf/bpf.c    | 126 ++++++++++++++++++++++++++++++++++++++++++++++++-
 tools/lib/bpf/libbpf.c |   2 +
 tools/lib/bpf/libbpf.h |   4 ++
 3 files changed, 130 insertions(+), 2 deletions(-)

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 5128677e4117..f00fba2edeae 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -25,6 +25,16 @@
 #include <asm/unistd.h>
 #include <linux/bpf.h>
 #include "bpf.h"
+#include "libbpf.h"
+#include <linux/rtnetlink.h>
+#include <sys/socket.h>
+#include <errno.h>
+
+#ifndef IFLA_XDP_MAX
+#define IFLA_XDP	43
+#define IFLA_XDP_FD	1
+#define IFLA_XDP_FLAGS	3
+#endif
 
 /*
  * When building perf, unistd.h is overridden. __NR_bpf is
@@ -46,8 +56,6 @@
 # endif
 #endif
 
-#define min(x, y) ((x) < (y) ? (x) : (y))
-
 static inline __u64 ptr_to_u64(const void *ptr)
 {
 	return (__u64) (unsigned long) ptr;
@@ -413,3 +421,117 @@ int bpf_obj_get_info_by_fd(int prog_fd, void *info, __u32 *info_len)
 
 	return err;
 }
+
+int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags)
+{
+	struct sockaddr_nl sa;
+	int sock, seq = 0, len, ret = -1;
+	char buf[4096];
+	struct nlattr *nla, *nla_xdp;
+	struct {
+		struct nlmsghdr  nh;
+		struct ifinfomsg ifinfo;
+		char             attrbuf[64];
+	} req;
+	struct nlmsghdr *nh;
+	struct nlmsgerr *err;
+	socklen_t addrlen;
+
+	memset(&sa, 0, sizeof(sa));
+	sa.nl_family = AF_NETLINK;
+
+	sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+	if (sock < 0) {
+		return -errno;
+	}
+
+	if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
+		ret = -errno;
+		goto cleanup;
+	}
+
+	addrlen = sizeof(sa);
+	if (getsockname(sock, (struct sockaddr *)&sa, &addrlen) < 0) {
+		ret = -errno;
+		goto cleanup;
+	}
+
+	if (addrlen != sizeof(sa)) {
+		ret = -LIBBPF_ERRNO__INTERNAL;
+		goto cleanup;
+	}
+
+	memset(&req, 0, sizeof(req));
+	req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+	req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+	req.nh.nlmsg_type = RTM_SETLINK;
+	req.nh.nlmsg_pid = 0;
+	req.nh.nlmsg_seq = ++seq;
+	req.ifinfo.ifi_family = AF_UNSPEC;
+	req.ifinfo.ifi_index = ifindex;
+
+	/* started nested attribute for XDP */
+	nla = (struct nlattr *)(((char *)&req)
+				+ NLMSG_ALIGN(req.nh.nlmsg_len));
+	nla->nla_type = NLA_F_NESTED | IFLA_XDP;
+	nla->nla_len = NLA_HDRLEN;
+
+	/* add XDP fd */
+	nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
+	nla_xdp->nla_type = IFLA_XDP_FD;
+	nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
+	memcpy((char *)nla_xdp + NLA_HDRLEN, &fd, sizeof(fd));
+	nla->nla_len += nla_xdp->nla_len;
+
+	/* if user passed in any flags, add those too */
+	if (flags) {
+		nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
+		nla_xdp->nla_type = IFLA_XDP_FLAGS;
+		nla_xdp->nla_len = NLA_HDRLEN + sizeof(flags);
+		memcpy((char *)nla_xdp + NLA_HDRLEN, &flags, sizeof(flags));
+		nla->nla_len += nla_xdp->nla_len;
+	}
+
+	req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
+
+	if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {
+		ret = -errno;
+		goto cleanup;
+	}
+
+	len = recv(sock, buf, sizeof(buf), 0);
+	if (len < 0) {
+		ret = -errno;
+		goto cleanup;
+	}
+
+	for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
+	     nh = NLMSG_NEXT(nh, len)) {
+		if (nh->nlmsg_pid != sa.nl_pid) {
+			ret = -LIBBPF_ERRNO__WRNGPID;
+			goto cleanup;
+		}
+		if (nh->nlmsg_seq != seq) {
+			ret = -LIBBPF_ERRNO__INVSEQ;
+			goto cleanup;
+		}
+		switch (nh->nlmsg_type) {
+		case NLMSG_ERROR:
+			err = (struct nlmsgerr *)NLMSG_DATA(nh);
+			if (!err->error)
+				continue;
+			ret = err->error;
+			goto cleanup;
+		case NLMSG_DONE:
+			break;
+		default:
+			break;
+		}
+	}
+
+	ret = 0;
+
+cleanup:
+	close(sock);
+	return ret;
+}
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index e9c4b7cabcf2..5fe8aaa2123e 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -106,6 +106,8 @@ static const char *libbpf_strerror_table[NR_ERRNO] = {
 	[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",
 };
 
 int libbpf_strerror(int err, char *buf, size_t size)
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 6e20003109e0..e42f96900318 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -42,6 +42,8 @@ enum libbpf_errno {
 	LIBBPF_ERRNO__PROG2BIG,	/* Program too big */
 	LIBBPF_ERRNO__KVER,	/* Incorrect kernel version */
 	LIBBPF_ERRNO__PROGTYPE,	/* Kernel doesn't support this program type */
+	LIBBPF_ERRNO__WRNGPID,	/* Wrong pid in netlink message */
+	LIBBPF_ERRNO__INVSEQ,	/* Invalid netlink sequence */
 	__LIBBPF_ERRNO__END,
 };
 
@@ -246,4 +248,6 @@ long libbpf_get_error(const void *ptr);
 
 int bpf_prog_load(const char *file, enum bpf_prog_type type,
 		  struct bpf_object **pobj, int *prog_fd);
+
+int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags);
 #endif
-- 
2.15.1

  reply	other threads:[~2017-12-30 20:41 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-25 22:13 [PATCH bpf-next 0/3] add XDP loading support to libbpf Eric Leblond
2017-12-25 22:13 ` [PATCH bpf-next 1/3] libbpf: add function to setup XDP Eric Leblond
2017-12-25 22:13 ` [PATCH bpf-next 2/3] libbpf: add error reporting in XDP Eric Leblond
2017-12-27  2:27   ` Alexei Starovoitov
2017-12-27 18:02     ` [PATCH bpf-next v2 0/4] libbpf: add function to setup XDP Eric Leblond
2017-12-27 18:02       ` [PATCH 1/4] " Eric Leblond
2017-12-27 18:57         ` Alexei Starovoitov
2017-12-28  0:59         ` Toshiaki Makita
2017-12-27 18:02       ` [PATCH 2/4] libbpf: add error reporting in XDP Eric Leblond
2017-12-27 18:57         ` Alexei Starovoitov
2017-12-27 18:02       ` [PATCH 3/4] libbpf: break loop earlier Eric Leblond
2017-12-27 19:00         ` Alexei Starovoitov
2017-12-27 20:30           ` Eric Leblond
2017-12-27 23:05             ` Daniel Borkmann
2017-12-28  8:04               ` [PATCH bpf-next v3 0/3] libbpf: add XDP setup support Eric Leblond
2017-12-28  8:04                 ` [PATCH bpf-next v3 1/3] libbpf: add function to setup XDP Eric Leblond
2017-12-28  8:18                   ` Toshiaki Makita
2017-12-30 20:41                     ` [PATCH bpf-next v4 0/3] " Eric Leblond
2017-12-30 20:41                       ` Eric Leblond [this message]
2018-01-03 23:59                         ` [PATCH bpf-next v4 1/3] " Eric Leblond
2018-01-04  8:21                           ` [PATCH bpf-next v5 1/4] " Eric Leblond
2018-01-04  8:21                             ` [PATCH bpf-next v5 2/4] libbpf: add error reporting in XDP Eric Leblond
2018-01-06 21:16                               ` Daniel Borkmann
2018-01-18 23:35                                 ` Eric Leblond
2018-01-18 23:43                                   ` [PATCH bpf-next 0/4] libbpf: add XDP binding support Eric Leblond
2018-01-18 23:43                                     ` [PATCH bpf-next v6 1/4] libbpf: add function to setup XDP Eric Leblond
2018-01-18 23:43                                     ` [PATCH bpf-next v6 2/4] libbpf: add error reporting in XDP Eric Leblond
2018-01-18 23:43                                     ` [PATCH bpf-next v6 3/4] libbpf: add missing SPDX-License-Identifier Eric Leblond
2018-01-18 23:43                                     ` [PATCH bpf-next v6 4/4] samples/bpf: use bpf_set_link_xdp_fd Eric Leblond
2018-01-20  2:00                                     ` [PATCH bpf-next 0/4] libbpf: add XDP binding support Daniel Borkmann
2018-01-20  2:27                                       ` Alexei Starovoitov
2018-01-20  8:21                                         ` Daniel Borkmann
2018-01-25  0:05                                           ` [PATCH bpf-next v7 0/5] libbpf: add XDP setup support Eric Leblond
2018-01-25  0:05                                             ` [PATCH bpf-next v7 1/5] tools: import netlink header in tools uapi Eric Leblond
2018-01-25  0:05                                             ` [PATCH bpf-next v7 2/5] libbpf: add function to setup XDP Eric Leblond
2018-01-27  1:23                                               ` Daniel Borkmann
2018-01-27 10:22                                                 ` Eric Leblond
2018-01-25  0:05                                             ` [PATCH bpf-next v7 3/5] libbpf: add error reporting in XDP Eric Leblond
2018-01-27  1:28                                               ` Daniel Borkmann
2018-01-27 10:32                                                 ` Eric Leblond
2018-01-30 10:58                                                   ` Daniel Borkmann
2018-01-30 20:50                                                     ` [PATCH bpf-next v8 0/5] libbpf: add XDP binding support Eric Leblond
2018-01-31 16:53                                                       ` Daniel Borkmann
2018-02-03  2:01                                                         ` Alexei Starovoitov
2018-01-30 20:55                                                     ` [PATCH bpf-next v8 1/5] tools: add netlink.h and if_link.h in tools uapi Eric Leblond
2018-01-30 20:55                                                       ` [PATCH bpf-next v8 2/5] libbpf: add function to setup XDP Eric Leblond
2018-01-30 20:55                                                       ` [PATCH bpf-next v8 3/5] libbpf: add error reporting in XDP Eric Leblond
2018-01-30 20:55                                                       ` [PATCH bpf-next v8 4/5] libbpf: add missing SPDX-License-Identifier Eric Leblond
2018-01-30 20:55                                                       ` [PATCH bpf-next v8 5/5] samples/bpf: use bpf_set_link_xdp_fd Eric Leblond
2018-01-25  0:05                                             ` [PATCH bpf-next v7 4/5] libbpf: add missing SPDX-License-Identifier Eric Leblond
2018-01-25  0:05                                             ` [PATCH bpf-next v7 5/5] samples/bpf: use bpf_set_link_xdp_fd Eric Leblond
2018-01-04  8:21                             ` [PATCH bpf-next v5 3/4] libbpf: add missing SPDX-License-Identifier Eric Leblond
2018-01-04  9:49                               ` Philippe Ombredanne
2018-01-04  8:21                             ` [PATCH bpf-next v5 4/4] samples/bpf: use bpf_set_link_xdp_fd Eric Leblond
2017-12-30 20:41                       ` [PATCH bpf-next v4 2/3] libbpf: add error reporting in XDP Eric Leblond
2017-12-31 11:20                         ` Philippe Ombredanne
2017-12-30 20:41                       ` [PATCH bpf-next v4 3/3] libbpf: add missing SPDX-License-Identifier Eric Leblond
2017-12-28  8:04                 ` [PATCH bpf-next v3 2/3] libbpf: add error reporting in XDP Eric Leblond
2017-12-28  8:04                 ` [PATCH bpf-next v3 3/3] libbpf: add missing SPDX-License-Identifier Eric Leblond
2017-12-29 12:35                   ` Philippe Ombredanne
2017-12-27 18:02       ` [PATCH 4/4] " Eric Leblond
2017-12-27 19:01         ` Alexei Starovoitov
2017-12-25 22:13 ` [PATCH bpf-next 3/3] libbpf: break loop earlier Eric Leblond

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171230204116.30871-2-eric@regit.org \
    --to=eric@regit.org \
    --cc=alexei.starovoitov@gmail.com \
    --cc=daniel@iogearbox.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=makita.toshiaki@lab.ntt.co.jp \
    --cc=netdev@vger.kernel.org \
    --cc=pombredanne@nexb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.