Commit 151516fa authored by David S. Miller's avatar David S. Miller

Merge branch 'sockmap-fixes'

John Fastabend says:

====================
net: sockmap fixes

Last two fixes (as far as I know) for sockmap code this round.

First, we are using the qdisc cb structure when making the data end
calculation. This is really just wrong so, store it with the other
metadata in the correct tcp_skb_cb sturct to avoid breaking things.

Next, with recent work to attach multiple programs to a cgroup a
specific enumeration of return codes was agreed upon. However,
I wrote the sk_skb program types before seeing this work and used
a different convention. Patch 2 in the series aligns the return
codes to avoid breaking with this infrastructure and also aligns
with other programming conventions to avoid being the odd duck out
forcing programs to remember SK_SKB programs are different. Pusing
to net because its a user visible change. With this SK_SKB program
return codes are the same as other cgroup program types.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents dea6e19f bfa64075
...@@ -844,6 +844,7 @@ struct tcp_skb_cb { ...@@ -844,6 +844,7 @@ struct tcp_skb_cb {
__u32 key; __u32 key;
__u32 flags; __u32 flags;
struct bpf_map *map; struct bpf_map *map;
void *data_end;
} bpf; } bpf;
}; };
}; };
......
...@@ -575,7 +575,7 @@ union bpf_attr { ...@@ -575,7 +575,7 @@ union bpf_attr {
* @map: pointer to sockmap * @map: pointer to sockmap
* @key: key to lookup sock in map * @key: key to lookup sock in map
* @flags: reserved for future use * @flags: reserved for future use
* Return: SK_REDIRECT * Return: SK_PASS
* *
* int bpf_sock_map_update(skops, map, key, flags) * int bpf_sock_map_update(skops, map, key, flags)
* @skops: pointer to bpf_sock_ops * @skops: pointer to bpf_sock_ops
...@@ -786,8 +786,8 @@ struct xdp_md { ...@@ -786,8 +786,8 @@ struct xdp_md {
}; };
enum sk_action { enum sk_action {
SK_ABORTED = 0, SK_DROP = 0,
SK_DROP, SK_PASS,
SK_REDIRECT, SK_REDIRECT,
}; };
......
...@@ -93,6 +93,14 @@ static inline struct smap_psock *smap_psock_sk(const struct sock *sk) ...@@ -93,6 +93,14 @@ static inline struct smap_psock *smap_psock_sk(const struct sock *sk)
return rcu_dereference_sk_user_data(sk); return rcu_dereference_sk_user_data(sk);
} }
/* compute the linear packet data range [data, data_end) for skb when
* sk_skb type programs are in use.
*/
static inline void bpf_compute_data_end_sk_skb(struct sk_buff *skb)
{
TCP_SKB_CB(skb)->bpf.data_end = skb->data + skb_headlen(skb);
}
static int smap_verdict_func(struct smap_psock *psock, struct sk_buff *skb) static int smap_verdict_func(struct smap_psock *psock, struct sk_buff *skb)
{ {
struct bpf_prog *prog = READ_ONCE(psock->bpf_verdict); struct bpf_prog *prog = READ_ONCE(psock->bpf_verdict);
...@@ -108,13 +116,14 @@ static int smap_verdict_func(struct smap_psock *psock, struct sk_buff *skb) ...@@ -108,13 +116,14 @@ static int smap_verdict_func(struct smap_psock *psock, struct sk_buff *skb)
*/ */
TCP_SKB_CB(skb)->bpf.map = NULL; TCP_SKB_CB(skb)->bpf.map = NULL;
skb->sk = psock->sock; skb->sk = psock->sock;
bpf_compute_data_end(skb); bpf_compute_data_end_sk_skb(skb);
preempt_disable(); preempt_disable();
rc = (*prog->bpf_func)(skb, prog->insnsi); rc = (*prog->bpf_func)(skb, prog->insnsi);
preempt_enable(); preempt_enable();
skb->sk = NULL; skb->sk = NULL;
return rc; return rc == SK_PASS ?
(TCP_SKB_CB(skb)->bpf.map ? SK_REDIRECT : SK_PASS) : SK_DROP;
} }
static void smap_do_verdict(struct smap_psock *psock, struct sk_buff *skb) static void smap_do_verdict(struct smap_psock *psock, struct sk_buff *skb)
...@@ -368,7 +377,7 @@ static int smap_parse_func_strparser(struct strparser *strp, ...@@ -368,7 +377,7 @@ static int smap_parse_func_strparser(struct strparser *strp,
* any socket yet. * any socket yet.
*/ */
skb->sk = psock->sock; skb->sk = psock->sock;
bpf_compute_data_end(skb); bpf_compute_data_end_sk_skb(skb);
rc = (*prog->bpf_func)(skb, prog->insnsi); rc = (*prog->bpf_func)(skb, prog->insnsi);
skb->sk = NULL; skb->sk = NULL;
rcu_read_unlock(); rcu_read_unlock();
......
...@@ -1844,14 +1844,15 @@ BPF_CALL_4(bpf_sk_redirect_map, struct sk_buff *, skb, ...@@ -1844,14 +1844,15 @@ BPF_CALL_4(bpf_sk_redirect_map, struct sk_buff *, skb,
{ {
struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); struct tcp_skb_cb *tcb = TCP_SKB_CB(skb);
/* If user passes invalid input drop the packet. */
if (unlikely(flags)) if (unlikely(flags))
return SK_ABORTED; return SK_DROP;
tcb->bpf.key = key; tcb->bpf.key = key;
tcb->bpf.flags = flags; tcb->bpf.flags = flags;
tcb->bpf.map = map; tcb->bpf.map = map;
return SK_REDIRECT; return SK_PASS;
} }
struct sock *do_sk_redirect_map(struct sk_buff *skb) struct sock *do_sk_redirect_map(struct sk_buff *skb)
...@@ -4243,6 +4244,31 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type, ...@@ -4243,6 +4244,31 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
return insn - insn_buf; return insn - insn_buf;
} }
static u32 sk_skb_convert_ctx_access(enum bpf_access_type type,
const struct bpf_insn *si,
struct bpf_insn *insn_buf,
struct bpf_prog *prog, u32 *target_size)
{
struct bpf_insn *insn = insn_buf;
int off;
switch (si->off) {
case offsetof(struct __sk_buff, data_end):
off = si->off;
off -= offsetof(struct __sk_buff, data_end);
off += offsetof(struct sk_buff, cb);
off += offsetof(struct tcp_skb_cb, bpf.data_end);
*insn++ = BPF_LDX_MEM(BPF_SIZEOF(void *), si->dst_reg,
si->src_reg, off);
break;
default:
return bpf_convert_ctx_access(type, si, insn_buf, prog,
target_size);
}
return insn - insn_buf;
}
const struct bpf_verifier_ops sk_filter_prog_ops = { const struct bpf_verifier_ops sk_filter_prog_ops = {
.get_func_proto = sk_filter_func_proto, .get_func_proto = sk_filter_func_proto,
.is_valid_access = sk_filter_is_valid_access, .is_valid_access = sk_filter_is_valid_access,
...@@ -4301,7 +4327,7 @@ const struct bpf_verifier_ops sock_ops_prog_ops = { ...@@ -4301,7 +4327,7 @@ const struct bpf_verifier_ops sock_ops_prog_ops = {
const struct bpf_verifier_ops sk_skb_prog_ops = { const struct bpf_verifier_ops sk_skb_prog_ops = {
.get_func_proto = sk_skb_func_proto, .get_func_proto = sk_skb_func_proto,
.is_valid_access = sk_skb_is_valid_access, .is_valid_access = sk_skb_is_valid_access,
.convert_ctx_access = bpf_convert_ctx_access, .convert_ctx_access = sk_skb_convert_ctx_access,
.gen_prologue = sk_skb_prologue, .gen_prologue = sk_skb_prologue,
}; };
......
...@@ -787,8 +787,8 @@ struct xdp_md { ...@@ -787,8 +787,8 @@ struct xdp_md {
}; };
enum sk_action { enum sk_action {
SK_ABORTED = 0, SK_DROP = 0,
SK_DROP, SK_PASS,
SK_REDIRECT, SK_REDIRECT,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment