Skip to content

Commit

Permalink
Merge branch 'sockmap-fixes'
Browse files Browse the repository at this point in the history
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: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Oct 29, 2017
2 parents dea6e19 + bfa6407 commit 151516f
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 11 deletions.
1 change: 1 addition & 0 deletions include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,7 @@ struct tcp_skb_cb {
__u32 key;
__u32 flags;
struct bpf_map *map;
void *data_end;
} bpf;
};
};
Expand Down
6 changes: 3 additions & 3 deletions include/uapi/linux/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ union bpf_attr {
* @map: pointer to sockmap
* @key: key to lookup sock in map
* @flags: reserved for future use
* Return: SK_REDIRECT
* Return: SK_PASS
*
* int bpf_sock_map_update(skops, map, key, flags)
* @skops: pointer to bpf_sock_ops
Expand Down Expand Up @@ -786,8 +786,8 @@ struct xdp_md {
};

enum sk_action {
SK_ABORTED = 0,
SK_DROP,
SK_DROP = 0,
SK_PASS,
SK_REDIRECT,
};

Expand Down
15 changes: 12 additions & 3 deletions kernel/bpf/sockmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ static inline struct smap_psock *smap_psock_sk(const struct sock *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)
{
struct bpf_prog *prog = READ_ONCE(psock->bpf_verdict);
Expand All @@ -108,13 +116,14 @@ static int smap_verdict_func(struct smap_psock *psock, struct sk_buff *skb)
*/
TCP_SKB_CB(skb)->bpf.map = NULL;
skb->sk = psock->sock;
bpf_compute_data_end(skb);
bpf_compute_data_end_sk_skb(skb);
preempt_disable();
rc = (*prog->bpf_func)(skb, prog->insnsi);
preempt_enable();
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)
Expand Down Expand Up @@ -368,7 +377,7 @@ static int smap_parse_func_strparser(struct strparser *strp,
* any socket yet.
*/
skb->sk = psock->sock;
bpf_compute_data_end(skb);
bpf_compute_data_end_sk_skb(skb);
rc = (*prog->bpf_func)(skb, prog->insnsi);
skb->sk = NULL;
rcu_read_unlock();
Expand Down
32 changes: 29 additions & 3 deletions net/core/filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1844,14 +1844,15 @@ BPF_CALL_4(bpf_sk_redirect_map, struct sk_buff *, skb,
{
struct tcp_skb_cb *tcb = TCP_SKB_CB(skb);

/* If user passes invalid input drop the packet. */
if (unlikely(flags))
return SK_ABORTED;
return SK_DROP;

tcb->bpf.key = key;
tcb->bpf.flags = flags;
tcb->bpf.map = map;

return SK_REDIRECT;
return SK_PASS;
}

struct sock *do_sk_redirect_map(struct sk_buff *skb)
Expand Down Expand Up @@ -4243,6 +4244,31 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
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 = {
.get_func_proto = sk_filter_func_proto,
.is_valid_access = sk_filter_is_valid_access,
Expand Down Expand Up @@ -4301,7 +4327,7 @@ const struct bpf_verifier_ops sock_ops_prog_ops = {
const struct bpf_verifier_ops sk_skb_prog_ops = {
.get_func_proto = sk_skb_func_proto,
.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,
};

Expand Down
4 changes: 2 additions & 2 deletions tools/include/uapi/linux/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -787,8 +787,8 @@ struct xdp_md {
};

enum sk_action {
SK_ABORTED = 0,
SK_DROP,
SK_DROP = 0,
SK_PASS,
SK_REDIRECT,
};

Expand Down

0 comments on commit 151516f

Please sign in to comment.