net: netfilter: Make ct zone opts configurable for bpf ct helpers
Add ct zone id and direction to bpf_ct_opts so that arbitrary ct zones can be used for xdp/tc bpf ct helper functions bpf_{xdp,skb}_ct_alloc and bpf_{xdp,skb}_ct_lookup. Signed-off-by: Brad Cowie <brad@faucet.nz> Link: https://lore.kernel.org/r/20240522050712.732558-1-brad@faucet.nz Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
This commit is contained in:
parent
6c8d7598df
commit
ece4b29690
@ -32,7 +32,9 @@
|
|||||||
* -EINVAL - Passed NULL for bpf_tuple pointer
|
* -EINVAL - Passed NULL for bpf_tuple pointer
|
||||||
* -EINVAL - opts->reserved is not 0
|
* -EINVAL - opts->reserved is not 0
|
||||||
* -EINVAL - netns_id is less than -1
|
* -EINVAL - netns_id is less than -1
|
||||||
* -EINVAL - opts__sz isn't NF_BPF_CT_OPTS_SZ (12)
|
* -EINVAL - opts__sz isn't NF_BPF_CT_OPTS_SZ (16) or 12
|
||||||
|
* -EINVAL - opts->ct_zone_id set when
|
||||||
|
opts__sz isn't NF_BPF_CT_OPTS_SZ (16)
|
||||||
* -EPROTO - l4proto isn't one of IPPROTO_TCP or IPPROTO_UDP
|
* -EPROTO - l4proto isn't one of IPPROTO_TCP or IPPROTO_UDP
|
||||||
* -ENONET - No network namespace found for netns_id
|
* -ENONET - No network namespace found for netns_id
|
||||||
* -ENOENT - Conntrack lookup could not find entry for tuple
|
* -ENOENT - Conntrack lookup could not find entry for tuple
|
||||||
@ -42,6 +44,8 @@
|
|||||||
* Values:
|
* Values:
|
||||||
* IPPROTO_TCP, IPPROTO_UDP
|
* IPPROTO_TCP, IPPROTO_UDP
|
||||||
* @dir: - connection tracking tuple direction.
|
* @dir: - connection tracking tuple direction.
|
||||||
|
* @ct_zone_id - connection tracking zone id.
|
||||||
|
* @ct_zone_dir - connection tracking zone direction.
|
||||||
* @reserved - Reserved member, will be reused for more options in future
|
* @reserved - Reserved member, will be reused for more options in future
|
||||||
* Values:
|
* Values:
|
||||||
* 0
|
* 0
|
||||||
@ -51,11 +55,13 @@ struct bpf_ct_opts {
|
|||||||
s32 error;
|
s32 error;
|
||||||
u8 l4proto;
|
u8 l4proto;
|
||||||
u8 dir;
|
u8 dir;
|
||||||
u8 reserved[2];
|
u16 ct_zone_id;
|
||||||
|
u8 ct_zone_dir;
|
||||||
|
u8 reserved[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NF_BPF_CT_OPTS_SZ = 12,
|
NF_BPF_CT_OPTS_SZ = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int bpf_nf_ct_tuple_parse(struct bpf_sock_tuple *bpf_tuple,
|
static int bpf_nf_ct_tuple_parse(struct bpf_sock_tuple *bpf_tuple,
|
||||||
@ -104,12 +110,21 @@ __bpf_nf_ct_alloc_entry(struct net *net, struct bpf_sock_tuple *bpf_tuple,
|
|||||||
u32 timeout)
|
u32 timeout)
|
||||||
{
|
{
|
||||||
struct nf_conntrack_tuple otuple, rtuple;
|
struct nf_conntrack_tuple otuple, rtuple;
|
||||||
|
struct nf_conntrack_zone ct_zone;
|
||||||
struct nf_conn *ct;
|
struct nf_conn *ct;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!opts || !bpf_tuple || opts->reserved[0] || opts->reserved[1] ||
|
if (!opts || !bpf_tuple)
|
||||||
opts_len != NF_BPF_CT_OPTS_SZ)
|
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
if (!(opts_len == NF_BPF_CT_OPTS_SZ || opts_len == 12))
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
if (opts_len == NF_BPF_CT_OPTS_SZ) {
|
||||||
|
if (opts->reserved[0] || opts->reserved[1] || opts->reserved[2])
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
} else {
|
||||||
|
if (opts->ct_zone_id)
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely(opts->netns_id < BPF_F_CURRENT_NETNS))
|
if (unlikely(opts->netns_id < BPF_F_CURRENT_NETNS))
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
@ -130,7 +145,16 @@ __bpf_nf_ct_alloc_entry(struct net *net, struct bpf_sock_tuple *bpf_tuple,
|
|||||||
return ERR_PTR(-ENONET);
|
return ERR_PTR(-ENONET);
|
||||||
}
|
}
|
||||||
|
|
||||||
ct = nf_conntrack_alloc(net, &nf_ct_zone_dflt, &otuple, &rtuple,
|
if (opts_len == NF_BPF_CT_OPTS_SZ) {
|
||||||
|
if (opts->ct_zone_dir == 0)
|
||||||
|
opts->ct_zone_dir = NF_CT_DEFAULT_ZONE_DIR;
|
||||||
|
nf_ct_zone_init(&ct_zone,
|
||||||
|
opts->ct_zone_id, opts->ct_zone_dir, 0);
|
||||||
|
} else {
|
||||||
|
ct_zone = nf_ct_zone_dflt;
|
||||||
|
}
|
||||||
|
|
||||||
|
ct = nf_conntrack_alloc(net, &ct_zone, &otuple, &rtuple,
|
||||||
GFP_ATOMIC);
|
GFP_ATOMIC);
|
||||||
if (IS_ERR(ct))
|
if (IS_ERR(ct))
|
||||||
goto out;
|
goto out;
|
||||||
@ -152,12 +176,21 @@ static struct nf_conn *__bpf_nf_ct_lookup(struct net *net,
|
|||||||
{
|
{
|
||||||
struct nf_conntrack_tuple_hash *hash;
|
struct nf_conntrack_tuple_hash *hash;
|
||||||
struct nf_conntrack_tuple tuple;
|
struct nf_conntrack_tuple tuple;
|
||||||
|
struct nf_conntrack_zone ct_zone;
|
||||||
struct nf_conn *ct;
|
struct nf_conn *ct;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!opts || !bpf_tuple || opts->reserved[0] || opts->reserved[1] ||
|
if (!opts || !bpf_tuple)
|
||||||
opts_len != NF_BPF_CT_OPTS_SZ)
|
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
if (!(opts_len == NF_BPF_CT_OPTS_SZ || opts_len == 12))
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
if (opts_len == NF_BPF_CT_OPTS_SZ) {
|
||||||
|
if (opts->reserved[0] || opts->reserved[1] || opts->reserved[2])
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
} else {
|
||||||
|
if (opts->ct_zone_id)
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
if (unlikely(opts->l4proto != IPPROTO_TCP && opts->l4proto != IPPROTO_UDP))
|
if (unlikely(opts->l4proto != IPPROTO_TCP && opts->l4proto != IPPROTO_UDP))
|
||||||
return ERR_PTR(-EPROTO);
|
return ERR_PTR(-EPROTO);
|
||||||
if (unlikely(opts->netns_id < BPF_F_CURRENT_NETNS))
|
if (unlikely(opts->netns_id < BPF_F_CURRENT_NETNS))
|
||||||
@ -174,7 +207,16 @@ static struct nf_conn *__bpf_nf_ct_lookup(struct net *net,
|
|||||||
return ERR_PTR(-ENONET);
|
return ERR_PTR(-ENONET);
|
||||||
}
|
}
|
||||||
|
|
||||||
hash = nf_conntrack_find_get(net, &nf_ct_zone_dflt, &tuple);
|
if (opts_len == NF_BPF_CT_OPTS_SZ) {
|
||||||
|
if (opts->ct_zone_dir == 0)
|
||||||
|
opts->ct_zone_dir = NF_CT_DEFAULT_ZONE_DIR;
|
||||||
|
nf_ct_zone_init(&ct_zone,
|
||||||
|
opts->ct_zone_id, opts->ct_zone_dir, 0);
|
||||||
|
} else {
|
||||||
|
ct_zone = nf_ct_zone_dflt;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash = nf_conntrack_find_get(net, &ct_zone, &tuple);
|
||||||
if (opts->netns_id >= 0)
|
if (opts->netns_id >= 0)
|
||||||
put_net(net);
|
put_net(net);
|
||||||
if (!hash)
|
if (!hash)
|
||||||
@ -245,7 +287,7 @@ __bpf_kfunc_start_defs();
|
|||||||
* @opts - Additional options for allocation (documented above)
|
* @opts - Additional options for allocation (documented above)
|
||||||
* Cannot be NULL
|
* Cannot be NULL
|
||||||
* @opts__sz - Length of the bpf_ct_opts structure
|
* @opts__sz - Length of the bpf_ct_opts structure
|
||||||
* Must be NF_BPF_CT_OPTS_SZ (12)
|
* Must be NF_BPF_CT_OPTS_SZ (16) or 12
|
||||||
*/
|
*/
|
||||||
__bpf_kfunc struct nf_conn___init *
|
__bpf_kfunc struct nf_conn___init *
|
||||||
bpf_xdp_ct_alloc(struct xdp_md *xdp_ctx, struct bpf_sock_tuple *bpf_tuple,
|
bpf_xdp_ct_alloc(struct xdp_md *xdp_ctx, struct bpf_sock_tuple *bpf_tuple,
|
||||||
@ -279,7 +321,7 @@ bpf_xdp_ct_alloc(struct xdp_md *xdp_ctx, struct bpf_sock_tuple *bpf_tuple,
|
|||||||
* @opts - Additional options for lookup (documented above)
|
* @opts - Additional options for lookup (documented above)
|
||||||
* Cannot be NULL
|
* Cannot be NULL
|
||||||
* @opts__sz - Length of the bpf_ct_opts structure
|
* @opts__sz - Length of the bpf_ct_opts structure
|
||||||
* Must be NF_BPF_CT_OPTS_SZ (12)
|
* Must be NF_BPF_CT_OPTS_SZ (16) or 12
|
||||||
*/
|
*/
|
||||||
__bpf_kfunc struct nf_conn *
|
__bpf_kfunc struct nf_conn *
|
||||||
bpf_xdp_ct_lookup(struct xdp_md *xdp_ctx, struct bpf_sock_tuple *bpf_tuple,
|
bpf_xdp_ct_lookup(struct xdp_md *xdp_ctx, struct bpf_sock_tuple *bpf_tuple,
|
||||||
@ -312,7 +354,7 @@ bpf_xdp_ct_lookup(struct xdp_md *xdp_ctx, struct bpf_sock_tuple *bpf_tuple,
|
|||||||
* @opts - Additional options for allocation (documented above)
|
* @opts - Additional options for allocation (documented above)
|
||||||
* Cannot be NULL
|
* Cannot be NULL
|
||||||
* @opts__sz - Length of the bpf_ct_opts structure
|
* @opts__sz - Length of the bpf_ct_opts structure
|
||||||
* Must be NF_BPF_CT_OPTS_SZ (12)
|
* Must be NF_BPF_CT_OPTS_SZ (16) or 12
|
||||||
*/
|
*/
|
||||||
__bpf_kfunc struct nf_conn___init *
|
__bpf_kfunc struct nf_conn___init *
|
||||||
bpf_skb_ct_alloc(struct __sk_buff *skb_ctx, struct bpf_sock_tuple *bpf_tuple,
|
bpf_skb_ct_alloc(struct __sk_buff *skb_ctx, struct bpf_sock_tuple *bpf_tuple,
|
||||||
@ -347,7 +389,7 @@ bpf_skb_ct_alloc(struct __sk_buff *skb_ctx, struct bpf_sock_tuple *bpf_tuple,
|
|||||||
* @opts - Additional options for lookup (documented above)
|
* @opts - Additional options for lookup (documented above)
|
||||||
* Cannot be NULL
|
* Cannot be NULL
|
||||||
* @opts__sz - Length of the bpf_ct_opts structure
|
* @opts__sz - Length of the bpf_ct_opts structure
|
||||||
* Must be NF_BPF_CT_OPTS_SZ (12)
|
* Must be NF_BPF_CT_OPTS_SZ (16) or 12
|
||||||
*/
|
*/
|
||||||
__bpf_kfunc struct nf_conn *
|
__bpf_kfunc struct nf_conn *
|
||||||
bpf_skb_ct_lookup(struct __sk_buff *skb_ctx, struct bpf_sock_tuple *bpf_tuple,
|
bpf_skb_ct_lookup(struct __sk_buff *skb_ctx, struct bpf_sock_tuple *bpf_tuple,
|
||||||
|
Loading…
Reference in New Issue
Block a user