linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Eric Leblond <eric@regit.org>
To: daniel@iogearbox.net
Cc: alexei.starovoitov@gmail.com, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, Eric Leblond <eric@regit.org>
Subject: [PATCH bpf-next v7 2/5] libbpf: add function to setup XDP
Date: Thu, 25 Jan 2018 01:05:45 +0100	[thread overview]
Message-ID: <20180125000548.12320-3-eric@regit.org> (raw)
In-Reply-To: <20180125000548.12320-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    | 127 +++++++++++++++++++++++++++++++++++++++++++++++++
 tools/lib/bpf/libbpf.c |   2 +
 tools/lib/bpf/libbpf.h |   4 ++
 3 files changed, 133 insertions(+)

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 5128677e4117..749a447ec9ed 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -25,6 +25,17 @@
 #include <asm/unistd.h>
 #include <linux/bpf.h>
 #include "bpf.h"
+#include "libbpf.h"
+#include "nlattr.h"
+#include <uapi/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,7 +57,9 @@
 # endif
 #endif
 
+#ifndef min
 #define min(x, y) ((x) < (y) ? (x) : (y))
+#endif
 
 static inline __u64 ptr_to_u64(const void *ptr)
 {
@@ -413,3 +426,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 30c776375118..c60122d3ea85 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

  parent reply	other threads:[~2018-01-25  0:06 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                       ` [PATCH bpf-next v4 1/3] " Eric Leblond
2018-01-03 23:59                         ` 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                                             ` Eric Leblond [this message]
2018-01-27  1:23                                               ` [PATCH bpf-next v7 2/5] libbpf: add function to setup XDP 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=20180125000548.12320-3-eric@regit.org \
    --to=eric@regit.org \
    --cc=alexei.starovoitov@gmail.com \
    --cc=daniel@iogearbox.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    /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 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).