[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180131135356.19134-6-bjorn.topel@gmail.com>
Date: Wed, 31 Jan 2018 14:53:37 +0100
From: Björn Töpel <bjorn.topel@...il.com>
To: bjorn.topel@...il.com, magnus.karlsson@...el.com,
alexander.h.duyck@...el.com, alexander.duyck@...il.com,
john.fastabend@...il.com, ast@...com, brouer@...hat.com,
willemdebruijn.kernel@...il.com, daniel@...earbox.net,
netdev@...r.kernel.org
Cc: Björn Töpel <bjorn.topel@...el.com>,
michael.lundkvist@...csson.com, jesse.brandeburg@...el.com,
anjali.singhai@...el.com, jeffrey.b.shaw@...el.com,
ferruh.yigit@...el.com, qi.z.zhang@...el.com
Subject: [RFC PATCH 05/24] bpf: added bpf_xdpsk_redirect
From: Björn Töpel <bjorn.topel@...el.com>
The bpf_xdpsk_redirect call redirects the XDP context to the XDP
socket bound to the receiving queue (if any).
Signed-off-by: Björn Töpel <bjorn.topel@...el.com>
---
include/uapi/linux/bpf.h | 6 +++++-
net/core/filter.c | 24 ++++++++++++++++++++++++
tools/testing/selftests/bpf/bpf_helpers.h | 2 ++
3 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index db6bdc375126..18f9ee7cb529 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -696,6 +696,9 @@ union bpf_attr {
* int bpf_override_return(pt_regs, rc)
* @pt_regs: pointer to struct pt_regs
* @rc: the return value to set
+ *
+ * int bpf_xdpsk_redirect()
+ * Return: XDP_REDIRECT
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -757,7 +760,8 @@ union bpf_attr {
FN(perf_prog_read_value), \
FN(getsockopt), \
FN(override_return), \
- FN(sock_ops_cb_flags_set),
+ FN(sock_ops_cb_flags_set), \
+ FN(xdpsk_redirect),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call
diff --git a/net/core/filter.c b/net/core/filter.c
index 08ab4c65a998..aedf57489cb5 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -1809,6 +1809,8 @@ struct redirect_info {
struct bpf_map *map;
struct bpf_map *map_to_flush;
unsigned long map_owner;
+ bool to_xsk;
+ /* XXX cache xsk socket here, to avoid lookup? */
};
static DEFINE_PER_CPU(struct redirect_info, redirect_info);
@@ -2707,6 +2709,7 @@ static int xdp_do_generic_redirect_map(struct net_device *dev,
ri->ifindex = 0;
ri->map = NULL;
ri->map_owner = 0;
+ ri->to_xsk = false;
if (unlikely(xdp_map_invalid(xdp_prog, map_owner))) {
err = -EFAULT;
@@ -2817,6 +2820,25 @@ static const struct bpf_func_proto bpf_xdp_redirect_map_proto = {
.arg3_type = ARG_ANYTHING,
};
+BPF_CALL_0(bpf_xdpsk_redirect)
+{
+ struct redirect_info *ri = this_cpu_ptr(&redirect_info);
+
+ /* XXX Would it be better to check for socket existence here,
+ * and XDP_ABORTED on failure? Also, then we can populate xsk
+ * in ri, and don't have to do the lookup multiple times.
+ */
+ ri->to_xsk = true;
+
+ return XDP_REDIRECT;
+}
+
+static const struct bpf_func_proto bpf_xdpsk_redirect_proto = {
+ .func = bpf_xdpsk_redirect,
+ .gpl_only = false,
+ .ret_type = RET_INTEGER,
+};
+
bool bpf_helper_changes_pkt_data(void *func)
{
if (func == bpf_skb_vlan_push ||
@@ -3544,6 +3566,8 @@ xdp_func_proto(enum bpf_func_id func_id)
return &bpf_xdp_redirect_proto;
case BPF_FUNC_redirect_map:
return &bpf_xdp_redirect_map_proto;
+ case BPF_FUNC_xdpsk_redirect:
+ return &bpf_xdpsk_redirect_proto;
default:
return bpf_base_func_proto(func_id);
}
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index dde2c11d7771..5898ad7a8e40 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -86,6 +86,8 @@ static int (*bpf_perf_prog_read_value)(void *ctx, void *buf,
(void *) BPF_FUNC_perf_prog_read_value;
static int (*bpf_override_return)(void *ctx, unsigned long rc) =
(void *) BPF_FUNC_override_return;
+static int (*bpf_xdpsk_redirect)(void) =
+ (void *) BPF_FUNC_xdpsk_redirect;
/* llvm builtin functions that eBPF C program may use to
* emit BPF_LD_ABS and BPF_LD_IND instructions
--
2.14.1
Powered by blists - more mailing lists