forked from torvalds/linux
-
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
netfilter: Add bpf_xdp_flow_lookup kfunc
Introduce bpf_xdp_flow_lookup kfunc in order to perform the lookup of a given flowtable entry based on a fib tuple of incoming traffic. bpf_xdp_flow_lookup can be used as building block to offload in xdp the processing of sw flowtable when hw flowtable is not available. Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org> Link: https://lore.kernel.org/bpf/55d38a4e5856f6d1509d823ff4e98aaa6d356097.1719698275.git.lorenzo@kernel.org
- Loading branch information
1 parent
89cc8f1
commit 391bb65
Showing
4 changed files
with
137 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* Unstable Flow Table Helpers for XDP hook | ||
* | ||
* These are called from the XDP programs. | ||
* Note that it is allowed to break compatibility for these functions since | ||
* the interface they are exposed through to BPF programs is explicitly | ||
* unstable. | ||
*/ | ||
|
||
#include <linux/kernel.h> | ||
#include <linux/init.h> | ||
#include <linux/module.h> | ||
#include <net/netfilter/nf_flow_table.h> | ||
#include <linux/bpf.h> | ||
#include <linux/btf.h> | ||
#include <net/xdp.h> | ||
|
||
/* bpf_flowtable_opts - options for bpf flowtable helpers | ||
* @error: out parameter, set for any encountered error | ||
*/ | ||
struct bpf_flowtable_opts { | ||
s32 error; | ||
}; | ||
|
||
enum { | ||
NF_BPF_FLOWTABLE_OPTS_SZ = 4, | ||
}; | ||
|
||
__diag_push(); | ||
__diag_ignore_all("-Wmissing-prototypes", | ||
"Global functions as their definitions will be in nf_flow_table BTF"); | ||
|
||
__bpf_kfunc_start_defs(); | ||
|
||
static struct flow_offload_tuple_rhash * | ||
bpf_xdp_flow_tuple_lookup(struct net_device *dev, | ||
struct flow_offload_tuple *tuple, __be16 proto) | ||
{ | ||
struct flow_offload_tuple_rhash *tuplehash; | ||
struct nf_flowtable *nf_flow_table; | ||
struct flow_offload *nf_flow; | ||
|
||
nf_flow_table = nf_flowtable_by_dev(dev); | ||
if (!nf_flow_table) | ||
return ERR_PTR(-ENOENT); | ||
|
||
tuplehash = flow_offload_lookup(nf_flow_table, tuple); | ||
if (!tuplehash) | ||
return ERR_PTR(-ENOENT); | ||
|
||
nf_flow = container_of(tuplehash, struct flow_offload, | ||
tuplehash[tuplehash->tuple.dir]); | ||
flow_offload_refresh(nf_flow_table, nf_flow, false); | ||
|
||
return tuplehash; | ||
} | ||
|
||
__bpf_kfunc struct flow_offload_tuple_rhash * | ||
bpf_xdp_flow_lookup(struct xdp_md *ctx, struct bpf_fib_lookup *fib_tuple, | ||
struct bpf_flowtable_opts *opts, u32 opts_len) | ||
{ | ||
struct xdp_buff *xdp = (struct xdp_buff *)ctx; | ||
struct flow_offload_tuple tuple = { | ||
.iifidx = fib_tuple->ifindex, | ||
.l3proto = fib_tuple->family, | ||
.l4proto = fib_tuple->l4_protocol, | ||
.src_port = fib_tuple->sport, | ||
.dst_port = fib_tuple->dport, | ||
}; | ||
struct flow_offload_tuple_rhash *tuplehash; | ||
__be16 proto; | ||
|
||
if (opts_len != NF_BPF_FLOWTABLE_OPTS_SZ) { | ||
opts->error = -EINVAL; | ||
return NULL; | ||
} | ||
|
||
switch (fib_tuple->family) { | ||
case AF_INET: | ||
tuple.src_v4.s_addr = fib_tuple->ipv4_src; | ||
tuple.dst_v4.s_addr = fib_tuple->ipv4_dst; | ||
proto = htons(ETH_P_IP); | ||
break; | ||
case AF_INET6: | ||
tuple.src_v6 = *(struct in6_addr *)&fib_tuple->ipv6_src; | ||
tuple.dst_v6 = *(struct in6_addr *)&fib_tuple->ipv6_dst; | ||
proto = htons(ETH_P_IPV6); | ||
break; | ||
default: | ||
opts->error = -EAFNOSUPPORT; | ||
return NULL; | ||
} | ||
|
||
tuplehash = bpf_xdp_flow_tuple_lookup(xdp->rxq->dev, &tuple, proto); | ||
if (IS_ERR(tuplehash)) { | ||
opts->error = PTR_ERR(tuplehash); | ||
return NULL; | ||
} | ||
|
||
return tuplehash; | ||
} | ||
|
||
__diag_pop() | ||
|
||
__bpf_kfunc_end_defs(); | ||
|
||
BTF_KFUNCS_START(nf_ft_kfunc_set) | ||
BTF_ID_FLAGS(func, bpf_xdp_flow_lookup, KF_TRUSTED_ARGS | KF_RET_NULL) | ||
BTF_KFUNCS_END(nf_ft_kfunc_set) | ||
|
||
static const struct btf_kfunc_id_set nf_flow_kfunc_set = { | ||
.owner = THIS_MODULE, | ||
.set = &nf_ft_kfunc_set, | ||
}; | ||
|
||
int nf_flow_register_bpf(void) | ||
{ | ||
return register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, | ||
&nf_flow_kfunc_set); | ||
} | ||
EXPORT_SYMBOL_GPL(nf_flow_register_bpf); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters