netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Cc: davem@davemloft.net, netdev@vger.kernel.org
Subject: [PATCH 49/50] netfilter: xt_bpf: support ebpf
Date: Wed,  7 Dec 2016 22:52:55 +0100	[thread overview]
Message-ID: <1481147576-5690-50-git-send-email-pablo@netfilter.org> (raw)
In-Reply-To: <1481147576-5690-1-git-send-email-pablo@netfilter.org>

From: Willem de Bruijn <willemb@google.com>

Add support for attaching an eBPF object by file descriptor.

The iptables binary can be called with a path to an elf object or a
pinned bpf object. Also pass the mode and path to the kernel to be
able to return it later for iptables dump and save.

Signed-off-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/uapi/linux/netfilter/xt_bpf.h | 21 ++++++++
 net/netfilter/xt_bpf.c                | 96 +++++++++++++++++++++++++++++------
 2 files changed, 101 insertions(+), 16 deletions(-)

diff --git a/include/uapi/linux/netfilter/xt_bpf.h b/include/uapi/linux/netfilter/xt_bpf.h
index 1fad2c27ac32..b97725af2ac0 100644
--- a/include/uapi/linux/netfilter/xt_bpf.h
+++ b/include/uapi/linux/netfilter/xt_bpf.h
@@ -2,9 +2,11 @@
 #define _XT_BPF_H
 
 #include <linux/filter.h>
+#include <linux/limits.h>
 #include <linux/types.h>
 
 #define XT_BPF_MAX_NUM_INSTR	64
+#define XT_BPF_PATH_MAX		(XT_BPF_MAX_NUM_INSTR * sizeof(struct sock_filter))
 
 struct bpf_prog;
 
@@ -16,4 +18,23 @@ struct xt_bpf_info {
 	struct bpf_prog *filter __attribute__((aligned(8)));
 };
 
+enum xt_bpf_modes {
+	XT_BPF_MODE_BYTECODE,
+	XT_BPF_MODE_FD_PINNED,
+	XT_BPF_MODE_FD_ELF,
+};
+
+struct xt_bpf_info_v1 {
+	__u16 mode;
+	__u16 bpf_program_num_elem;
+	__s32 fd;
+	union {
+		struct sock_filter bpf_program[XT_BPF_MAX_NUM_INSTR];
+		char path[XT_BPF_PATH_MAX];
+	};
+
+	/* only used in the kernel */
+	struct bpf_prog *filter __attribute__((aligned(8)));
+};
+
 #endif /*_XT_BPF_H */
diff --git a/net/netfilter/xt_bpf.c b/net/netfilter/xt_bpf.c
index dffee9d47ec4..2dedaa23ab0a 100644
--- a/net/netfilter/xt_bpf.c
+++ b/net/netfilter/xt_bpf.c
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/filter.h>
+#include <linux/bpf.h>
 
 #include <linux/netfilter/xt_bpf.h>
 #include <linux/netfilter/x_tables.h>
@@ -20,15 +21,15 @@ MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_bpf");
 MODULE_ALIAS("ip6t_bpf");
 
-static int bpf_mt_check(const struct xt_mtchk_param *par)
+static int __bpf_mt_check_bytecode(struct sock_filter *insns, __u16 len,
+				   struct bpf_prog **ret)
 {
-	struct xt_bpf_info *info = par->matchinfo;
 	struct sock_fprog_kern program;
 
-	program.len = info->bpf_program_num_elem;
-	program.filter = info->bpf_program;
+	program.len = len;
+	program.filter = insns;
 
-	if (bpf_prog_create(&info->filter, &program)) {
+	if (bpf_prog_create(ret, &program)) {
 		pr_info("bpf: check failed: parse error\n");
 		return -EINVAL;
 	}
@@ -36,6 +37,42 @@ static int bpf_mt_check(const struct xt_mtchk_param *par)
 	return 0;
 }
 
+static int __bpf_mt_check_fd(int fd, struct bpf_prog **ret)
+{
+	struct bpf_prog *prog;
+
+	prog = bpf_prog_get_type(fd, BPF_PROG_TYPE_SOCKET_FILTER);
+	if (IS_ERR(prog))
+		return PTR_ERR(prog);
+
+	*ret = prog;
+	return 0;
+}
+
+static int bpf_mt_check(const struct xt_mtchk_param *par)
+{
+	struct xt_bpf_info *info = par->matchinfo;
+
+	return __bpf_mt_check_bytecode(info->bpf_program,
+				       info->bpf_program_num_elem,
+				       &info->filter);
+}
+
+static int bpf_mt_check_v1(const struct xt_mtchk_param *par)
+{
+	struct xt_bpf_info_v1 *info = par->matchinfo;
+
+	if (info->mode == XT_BPF_MODE_BYTECODE)
+		return __bpf_mt_check_bytecode(info->bpf_program,
+					       info->bpf_program_num_elem,
+					       &info->filter);
+	else if (info->mode == XT_BPF_MODE_FD_PINNED ||
+		 info->mode == XT_BPF_MODE_FD_ELF)
+		return __bpf_mt_check_fd(info->fd, &info->filter);
+	else
+		return -EINVAL;
+}
+
 static bool bpf_mt(const struct sk_buff *skb, struct xt_action_param *par)
 {
 	const struct xt_bpf_info *info = par->matchinfo;
@@ -43,31 +80,58 @@ static bool bpf_mt(const struct sk_buff *skb, struct xt_action_param *par)
 	return BPF_PROG_RUN(info->filter, skb);
 }
 
+static bool bpf_mt_v1(const struct sk_buff *skb, struct xt_action_param *par)
+{
+	const struct xt_bpf_info_v1 *info = par->matchinfo;
+
+	return !!bpf_prog_run_save_cb(info->filter, (struct sk_buff *) skb);
+}
+
 static void bpf_mt_destroy(const struct xt_mtdtor_param *par)
 {
 	const struct xt_bpf_info *info = par->matchinfo;
+
+	bpf_prog_destroy(info->filter);
+}
+
+static void bpf_mt_destroy_v1(const struct xt_mtdtor_param *par)
+{
+	const struct xt_bpf_info_v1 *info = par->matchinfo;
+
 	bpf_prog_destroy(info->filter);
 }
 
-static struct xt_match bpf_mt_reg __read_mostly = {
-	.name		= "bpf",
-	.revision	= 0,
-	.family		= NFPROTO_UNSPEC,
-	.checkentry	= bpf_mt_check,
-	.match		= bpf_mt,
-	.destroy	= bpf_mt_destroy,
-	.matchsize	= sizeof(struct xt_bpf_info),
-	.me		= THIS_MODULE,
+static struct xt_match bpf_mt_reg[] __read_mostly = {
+	{
+		.name		= "bpf",
+		.revision	= 0,
+		.family		= NFPROTO_UNSPEC,
+		.checkentry	= bpf_mt_check,
+		.match		= bpf_mt,
+		.destroy	= bpf_mt_destroy,
+		.matchsize	= sizeof(struct xt_bpf_info),
+		.me		= THIS_MODULE,
+	},
+	{
+		.name		= "bpf",
+		.revision	= 1,
+		.family		= NFPROTO_UNSPEC,
+		.checkentry	= bpf_mt_check_v1,
+		.match		= bpf_mt_v1,
+		.destroy	= bpf_mt_destroy_v1,
+		.matchsize	= sizeof(struct xt_bpf_info_v1),
+		.me		= THIS_MODULE,
+	},
 };
 
 static int __init bpf_mt_init(void)
 {
-	return xt_register_match(&bpf_mt_reg);
+	return xt_register_matches(bpf_mt_reg, ARRAY_SIZE(bpf_mt_reg));
 }
 
 static void __exit bpf_mt_exit(void)
 {
-	xt_unregister_match(&bpf_mt_reg);
+	xt_unregister_matches(bpf_mt_reg, ARRAY_SIZE(bpf_mt_reg));
 }
 
 module_init(bpf_mt_init);
-- 
2.1.4


  parent reply	other threads:[~2016-12-07 21:52 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-07 21:52 [PATCH 00/50] Netfilter/IPVS updates for net-next Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 01/50] ipvs: Use IS_ERR_OR_NULL(svc) instead of IS_ERR(svc) || svc == NULL Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 02/50] ipvs: Decrement ttl Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 03/50] netfilter: update Arturo Borrero Gonzalez email address Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 04/50] netfilter: built-in NAT support for DCCP Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 05/50] netfilter: built-in NAT support for SCTP Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 06/50] netfilter: built-in NAT support for UDPlite Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 07/50] netfilter: nf_log: do not assume ethernet header in netdev family Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 08/50] netfilter: nfnetlink_log: add "nf-logger-5-1" module alias name Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 09/50] netfilter: nf_conntrack_tuple_common.h: fix #include Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 10/50] netfilter: conntrack: built-in support for DCCP Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 11/50] netfilter: conntrack: built-in support for SCTP Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 12/50] netfilter: conntrack: built-in support for UDPlite Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 13/50] netfilter: conntrack: remove unused init_net hook Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 14/50] netfilter: add and use nf_ct_netns_get/put Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 15/50] netfilter: nat: add dependencies on conntrack module Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 16/50] netfilter: nf_tables: add conntrack dependencies for nat/masq/redir expressions Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 17/50] netfilter: conntrack: register hooks in netns when needed by ruleset Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 18/50] netfilter: conntrack: add nf_conntrack_default_on sysctl Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 19/50] netfilter: defrag: only register defrag functionality if needed Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 20/50] netfilter: introduce accessor functions for hook entries Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 21/50] netfilter: decouple nf_hook_entry and nf_hook_ops Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 22/50] netfilter: convert while loops to for loops Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 23/50] netfilter: x_tables: pass xt_counters struct instead of packet counter Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 24/50] netfilter: x_tables: pass xt_counters struct to counter allocator Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 25/50] netfilter: x_tables: pack percpu counter allocations Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 26/50] netfilter: nft_fib: convert htonl to ntohl properly Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 27/50] netfilter: nft_fib_ipv4: initialize *dest to zero Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 28/50] netfilter: nft_payload: layer 4 checksum adjustment for pseudoheader fields Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 29/50] netfilter: xt_multiport: Fix wrong unmatch result with multiple ports Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 30/50] netfilter: ingress: translate 0 nf_hook_slow retval to -1 Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 31/50] netfilter: add and use nf_fwd_netdev_egress Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 32/50] netfilter: nf_tables: add stateful objects Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 33/50] netfilter: nft_counter: add stateful object type Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 34/50] netfilter: nft_quota: " Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 35/50] netfilter: nf_tables: add stateful object reference expression Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 36/50] netfilter: nft_quota: dump consumed quota Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 37/50] netfilter: nf_tables: atomic dump and reset for stateful objects Pablo Neira Ayuso
2016-12-09  0:40   ` Paul Gortmaker
2016-12-09 10:24     ` Pablo Neira Ayuso
2016-12-09 14:24       ` Eric Dumazet
2016-12-09 15:22         ` Eric Dumazet
2016-12-10 12:21           ` Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 38/50] netfilter: nf_tables: notify internal updates of " Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 39/50] netfilter: nft_quota: add depleted flag for objects Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 40/50] netfilter: nf_tables: add stateful object reference to set elements Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 41/50] netfilter: nft_objref: support for stateful object maps Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 42/50] netfilter: nf_tables: allow to filter stateful object dumps by type Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 43/50] netfilter: rpfilter: bypass ipv4 lbcast packets with zeronet source Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 44/50] netfilter: nat: skip checksum on offload SCTP packets Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 45/50] netfilter: nf_tables: constify struct nft_ctx * parameter in nft_trans_alloc() Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 46/50] netfilter: nft_set: introduce nft_{hash, rbtree}_deactivate_one() Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 47/50] netfilter: nf_tables: support for set flushing Pablo Neira Ayuso
2016-12-07 21:52 ` [PATCH 48/50] netfilter: x_tables: avoid warn and OOM killer on vmalloc call Pablo Neira Ayuso
2016-12-07 21:52 ` Pablo Neira Ayuso [this message]
2016-12-07 21:52 ` [PATCH 50/50] netfilter: nft_quota: allow to restore consumed quota Pablo Neira Ayuso
2016-12-08  0:29 ` [PATCH 00/50] Netfilter/IPVS updates for net-next David Miller

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=1481147576-5690-50-git-send-email-pablo@netfilter.org \
    --to=pablo@netfilter.org \
    --cc=davem@davemloft.net \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@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).