All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: bpf@vger.kernel.org
Cc: brouer@redhat.com, "Kumar Kartikeya Dwivedi" <memxor@gmail.com>,
	"Toke Høiland-Jørgensen" <toke@redhat.com>,
	"Alexei Starovoitov" <ast@kernel.org>,
	"Daniel Borkmann" <daniel@iogearbox.net>,
	"Andrii Nakryiko" <andrii@kernel.org>,
	"Martin KaFai Lau" <kafai@fb.com>,
	"Song Liu" <songliubraving@fb.com>, "Yonghong Song" <yhs@fb.com>,
	"John Fastabend" <john.fastabend@gmail.com>,
	"KP Singh" <kpsingh@kernel.org>, "Shuah Khan" <shuah@kernel.org>,
	"David S. Miller" <davem@davemloft.net>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Jesper Dangaard Brouer" <hawk@kernel.org>,
	"Peter Zijlstra" <peterz@infradead.org>,
	linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	linux-kselftest@vger.kernel.org
Subject: [PATCH bpf-next 4/5] libbpf: add high level TC-BPF API
Date: Thu, 25 Mar 2021 17:30:02 +0530	[thread overview]
Message-ID: <20210325120020.236504-5-memxor@gmail.com> (raw)
In-Reply-To: <20210325120020.236504-1-memxor@gmail.com>

A high level API is provided using the aforementioned routines internally,
and these return a bpf_link object to the user. These are limited to just
attach for now, and can be extended to change/replace if the use case
arises in the future. It is also possible to call bpf_link__disconnect
on the link and switch to managing the filter/action manually if the
need arises. In most cases, the higher level API should suffice.

Example:

	struct bpf_tc_cls_info info = {};
	struct bpf_object *obj;
	struct bpf_program *p;
	struct bpf_link *link;
	__u32 index;
	int fd, r;

	obj = bpf_object_open("foo.o");
	if (IS_ERR_OR_NULL(obj))
		return PTR_ERR(obj);

	p = bpf_object__find_program_by_title(obj, "classifier");
	if (IS_ERR_OR_NULL(p))
		return PTR_ERR(p);

	DECLARE_LIBBPF_OPTS(bpf_tc_cls_opts, opts, .handle = 1);
	link = bpf_program__attach_tc_cls_dev(p, if_nametoindex("lo"),
					      BPF_TC_CLSACT_INGRESS,
					      ETH_P_IP, &opts);
	if (IS_ERR_OR_NULL(link))
		return PTR_ERR(link);

	/* We want to take ownership of the filter, so we disconnect the
	 * link and detach it on our own
	 */
	bpf_link__disconnect(link);

	r = bpf_tc_cls_get_info_dev(bpf_program__fd(fd),
				    if_nametoindex("lo"),
				    BPF_TC_CLSACT_INGRESS,
				    ETH_P_IP, &opts, &info);
	if (r < 0)
		return r;

	/* We get the attach_id in the info struct, pass it to detach */
	bpf_tc_cls_detach_dev(&info.id);

	bpf_link__destroy(link);

Example:

	struct bpf_object *obj;
	struct bpf_program *p;
	struct bpf_link *link;
	__u32 index;
	int fd, r;

	obj = bpf_object_open("foo.o");
	if (IS_ERR_OR_NULL(obj))
		return PTR_ERR(obj);

	p = bpf_object__find_program_by_title(obj, "action");
	if (IS_ERR_OR_NULL(p))
		return PTR_ERR(p);

	/* A simple example that attaches a SCHED_ACT prog */
	link = bpf_program__attach_tc_act(p, NULL);
	if (IS_ERR_OR_NULL(link))
		return PTR_ERR(link);

	bpf_link__destroy(link);

Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
 tools/lib/bpf/libbpf.c   | 110 ++++++++++++++++++++++++++++++++++++++-
 tools/lib/bpf/libbpf.h   |  15 ++++++
 tools/lib/bpf/libbpf.map |   3 ++
 3 files changed, 127 insertions(+), 1 deletion(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 058b643cbcb1..cc5c200a661d 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -33,6 +33,7 @@
 #include <linux/filter.h>
 #include <linux/list.h>
 #include <linux/limits.h>
+#include <linux/rtnetlink.h>
 #include <linux/perf_event.h>
 #include <linux/ring_buffer.h>
 #include <linux/version.h>
@@ -6847,7 +6848,7 @@ static int bpf_object__collect_relos(struct bpf_object *obj)
 
 	for (i = 0; i < obj->nr_programs; i++) {
 		struct bpf_program *p = &obj->programs[i];
-		
+
 		if (!p->nr_reloc)
 			continue;
 
@@ -9443,6 +9444,10 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,
 struct bpf_link {
 	int (*detach)(struct bpf_link *link);
 	int (*destroy)(struct bpf_link *link);
+	union {
+		struct bpf_tc_cls_attach_id *tc_cls_id;
+		__u32 tc_act_index;
+	};
 	char *pin_path;		/* NULL, if not pinned */
 	int fd;			/* hook FD, -1 if not applicable */
 	bool disconnected;
@@ -10199,6 +10204,109 @@ struct bpf_link *bpf_map__attach_struct_ops(struct bpf_map *map)
 	return link;
 }
 
+static int bpf_link__detach_tc_cls(struct bpf_link *link)
+{
+	return bpf_tc_cls_detach_dev(link->tc_cls_id);
+}
+
+static int bpf_link__destroy_tc_cls(struct bpf_link *link)
+{
+	zfree(&link->tc_cls_id);
+	return 0;
+}
+
+struct bpf_link *bpf_program__attach_tc_cls_dev(struct bpf_program *prog,
+						__u32 ifindex, __u32 parent_id,
+						__u32 protocol,
+						const struct bpf_tc_cls_opts *opts)
+{
+	struct bpf_tc_cls_attach_id *id = NULL;
+	struct bpf_link *link = NULL;
+	char errmsg[STRERR_BUFSIZE];
+	int prog_fd, err;
+
+	prog_fd = bpf_program__fd(prog);
+	if (prog_fd < 0) {
+		pr_warn("prog '%s': can't attach before loaded\n", prog->name);
+		return ERR_PTR(-EINVAL);
+	}
+
+	link = calloc(1, sizeof(*link));
+	if (!link)
+		return ERR_PTR(-ENOMEM);
+	link->detach = &bpf_link__detach_tc_cls;
+	link->destroy = &bpf_link__destroy_tc_cls;
+	link->fd = -1;
+
+	id = calloc(1, sizeof(*id));
+	if (!id) {
+		err = -ENOMEM;
+		goto end;
+	}
+
+	err = bpf_tc_cls_attach_dev(prog_fd, ifindex, parent_id, protocol, opts, id);
+	if (err < 0) {
+		pr_warn("prog '%s': failed to attach classifier: %s\n",
+			prog->name,
+			libbpf_strerror_r(err, errmsg, sizeof(errmsg)));
+		goto end;
+	}
+
+	link->tc_cls_id = id;
+	return link;
+
+end:
+	free(id);
+	free(link);
+	return ERR_PTR(err);
+}
+
+struct bpf_link *bpf_program__attach_tc_cls_block(struct bpf_program *prog,
+						  __u32 block_index, __u32 protocol,
+						  const struct bpf_tc_cls_opts *opts)
+{
+	return bpf_program__attach_tc_cls_dev(prog, TCM_IFINDEX_MAGIC_BLOCK, block_index,
+					      protocol, opts);
+}
+
+static int bpf_link__detach_tc_act(struct bpf_link *link)
+{
+	return bpf_tc_act_detach(link->tc_act_index);
+}
+
+struct bpf_link *bpf_program__attach_tc_act(struct bpf_program *prog,
+					    const struct bpf_tc_act_opts *opts)
+{
+	struct bpf_link *link = NULL;
+	char errmsg[STRERR_BUFSIZE];
+	int prog_fd, err;
+
+	prog_fd = bpf_program__fd(prog);
+	if (prog_fd < 0) {
+		pr_warn("prog '%s': can't attach before loading\n", prog->name);
+		return ERR_PTR(-EINVAL);
+	}
+
+	link = calloc(1, sizeof(*link));
+	if (!link)
+		return ERR_PTR(-ENOMEM);
+	link->detach = &bpf_link__detach_tc_act;
+	link->fd = -1;
+
+	err = bpf_tc_act_attach(prog_fd, opts, &link->tc_act_index);
+	if (err < 0) {
+		pr_warn("prog '%s': failed to attach action: %s\n", prog->name,
+			libbpf_strerror_r(err, errmsg, sizeof(errmsg)));
+		goto end;
+	}
+
+	return link;
+
+end:
+	free(link);
+	return ERR_PTR(err);
+}
+
 enum bpf_perf_event_ret
 bpf_perf_event_read_simple(void *mmap_mem, size_t mmap_size, size_t page_size,
 			   void **copy_mem, size_t *copy_size,
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 63baef6045b1..e33720d0b672 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -268,6 +268,21 @@ LIBBPF_API struct bpf_link *
 bpf_program__attach_freplace(struct bpf_program *prog,
 			     int target_fd, const char *attach_func_name);
 
+struct bpf_tc_cls_opts;
+struct bpf_tc_act_opts;
+
+LIBBPF_API struct bpf_link *
+bpf_program__attach_tc_cls_dev(struct bpf_program *prog, __u32 ifindex,
+			       __u32 parent_id, __u32 protocol,
+			       const struct bpf_tc_cls_opts *opts);
+LIBBPF_API struct bpf_link *
+bpf_program__attach_tc_cls_block(struct bpf_program *prog, __u32 block_index,
+				 __u32 protocol,
+				 const struct bpf_tc_cls_opts *opts);
+LIBBPF_API struct bpf_link *
+bpf_program__attach_tc_act(struct bpf_program *prog,
+			   const struct bpf_tc_act_opts *opts);
+
 struct bpf_map;
 
 LIBBPF_API struct bpf_link *bpf_map__attach_struct_ops(struct bpf_map *map);
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index 72022b45a8b9..2e1390e4ebf0 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -373,4 +373,7 @@ LIBBPF_0.4.0 {
 		bpf_tc_cls_replace_dev;
 		bpf_tc_cls_get_info_dev;
 		bpf_tc_cls_get_info_block;
+		bpf_program__attach_tc_cls_dev;
+		bpf_program__attach_tc_cls_block;
+		bpf_program__attach_tc_act;
 } LIBBPF_0.3.0;
-- 
2.30.2


  parent reply	other threads:[~2021-03-25 12:03 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-25 11:59 [PATCH bpf-next 0/5] libbpf: Add TC-BPF API Kumar Kartikeya Dwivedi
2021-03-25 11:59 ` [PATCH bpf-next 1/5] tools pkt_cls.h: sync with kernel sources Kumar Kartikeya Dwivedi
2021-03-26 23:25   ` Andrii Nakryiko
2021-03-27  3:54     ` Kumar Kartikeya Dwivedi
2021-03-27  3:58       ` Andrii Nakryiko
2021-03-25 12:00 ` [PATCH bpf-next 2/5] libbpf: add helpers for preparing netlink attributes Kumar Kartikeya Dwivedi
2021-03-26 23:52   ` Andrii Nakryiko
2021-03-25 12:00 ` [PATCH bpf-next 3/5] libbpf: add low level TC-BPF API Kumar Kartikeya Dwivedi
2021-03-28  4:42   ` Andrii Nakryiko
2021-03-28  8:11     ` Kumar Kartikeya Dwivedi
2021-03-30 20:39       ` Andrii Nakryiko
2021-03-30 21:11         ` Toke Høiland-Jørgensen
2021-03-31  9:32           ` Kumar Kartikeya Dwivedi
2021-03-30 21:25         ` Daniel Borkmann
2021-03-30 23:30           ` Alexei Starovoitov
2021-03-31  9:44           ` Kumar Kartikeya Dwivedi
2021-04-02  0:19             ` Daniel Borkmann
2021-04-02 15:27               ` Kumar Kartikeya Dwivedi
2021-04-02 18:32                 ` Alexei Starovoitov
2021-04-02 19:08                   ` Kumar Kartikeya Dwivedi
2021-04-03 17:47                     ` Alexei Starovoitov
2021-04-05 17:27                       ` Andrii Nakryiko
2021-04-06 10:06                         ` Toke Høiland-Jørgensen
2021-04-14  0:47                           ` Andrii Nakryiko
2021-04-14 10:58                             ` Toke Høiland-Jørgensen
2021-04-14 22:22                               ` Andrii Nakryiko
2021-04-14 22:51                                 ` Toke Høiland-Jørgensen
2021-04-14 23:19                                   ` Andrii Nakryiko
2021-04-14 23:32                                     ` Daniel Borkmann
2021-04-14 23:58                                       ` Andrii Nakryiko
2021-04-15 22:10                                         ` Daniel Borkmann
2021-04-15 22:22                                           ` Andrii Nakryiko
2021-04-15 23:10                                             ` Daniel Borkmann
2021-04-16  9:01                                               ` Toke Høiland-Jørgensen
2021-04-15 15:57                                     ` Toke Høiland-Jørgensen
2021-04-15 21:09                                       ` Andrii Nakryiko
2021-04-05 17:21                 ` Andrii Nakryiko
2021-04-06 19:05                   ` Kumar Kartikeya Dwivedi
2021-03-31  9:51           ` Toke Høiland-Jørgensen
2021-03-29 11:46   ` Vlad Buslov
2021-03-29 12:32     ` Toke Høiland-Jørgensen
2021-03-29 12:49       ` Vlad Buslov
2021-03-25 12:00 ` Kumar Kartikeya Dwivedi [this message]
2021-03-25 12:00 ` [PATCH bpf-next 5/5] libbpf: add selftests for " Kumar Kartikeya Dwivedi
2021-03-27  2:15   ` Alexei Starovoitov
2021-03-27 15:17     ` Toke Høiland-Jørgensen
2021-03-29  1:26       ` Alexei Starovoitov
2021-03-29  1:45         ` Kumar Kartikeya Dwivedi
2021-03-28  4:32     ` Andrii Nakryiko
2021-03-29  1:40       ` Alexei Starovoitov
2021-03-29  2:38         ` Andrii Nakryiko
2021-03-30  3:28           ` Alexei Starovoitov
2021-03-30 20:28             ` Andrii Nakryiko
2021-03-30 23:27               ` Alexei Starovoitov
2021-03-29  9:56         ` Toke Høiland-Jørgensen

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=20210325120020.236504-5-memxor@gmail.com \
    --to=memxor@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=brouer@redhat.com \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=hawk@kernel.org \
    --cc=john.fastabend@gmail.com \
    --cc=kafai@fb.com \
    --cc=kpsingh@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=peterz@infradead.org \
    --cc=shuah@kernel.org \
    --cc=songliubraving@fb.com \
    --cc=toke@redhat.com \
    --cc=yhs@fb.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.