diff options
author | Stanislav Fomichev <sdf@google.com> | 2019-12-13 14:30:27 -0800 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2019-12-13 15:26:53 -0800 |
commit | 850a88cc4096fe1df407452ba2e4d28cf5b3eee9 (patch) | |
tree | 45fde0333440ad15a1f6e682009cda3fe8892ebe /net | |
parent | 02620d9e629d217330a1e2a55f9c1e15a1af1519 (diff) | |
download | linux-850a88cc4096fe1df407452ba2e4d28cf5b3eee9.tar.gz linux-850a88cc4096fe1df407452ba2e4d28cf5b3eee9.tar.bz2 linux-850a88cc4096fe1df407452ba2e4d28cf5b3eee9.zip |
bpf: Expose __sk_buff wire_len/gso_segs to BPF_PROG_TEST_RUN
wire_len should not be less than real len and is capped by GSO_MAX_SIZE.
gso_segs is capped by GSO_MAX_SEGS.
v2:
* set wire_len to skb->len when passed wire_len is 0 (Alexei Starovoitov)
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Cc: Martin KaFai Lau <kafai@fb.com>
Link: https://lore.kernel.org/bpf/20191213223028.161282-1-sdf@google.com
Diffstat (limited to 'net')
-rw-r--r-- | net/bpf/test_run.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 5016c538d3ce..93a9c87787e0 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -267,8 +267,10 @@ static int convert___skb_to_skb(struct sk_buff *skb, struct __sk_buff *__skb) return -EINVAL; /* tstamp is allowed */ + /* wire_len is allowed */ + /* gso_segs is allowed */ - if (!range_is_zero(__skb, offsetofend(struct __sk_buff, tstamp), + if (!range_is_zero(__skb, offsetofend(struct __sk_buff, gso_segs), sizeof(struct __sk_buff))) return -EINVAL; @@ -276,6 +278,19 @@ static int convert___skb_to_skb(struct sk_buff *skb, struct __sk_buff *__skb) skb->tstamp = __skb->tstamp; memcpy(&cb->data, __skb->cb, QDISC_CB_PRIV_LEN); + if (__skb->wire_len == 0) { + cb->pkt_len = skb->len; + } else { + if (__skb->wire_len < skb->len || + __skb->wire_len > GSO_MAX_SIZE) + return -EINVAL; + cb->pkt_len = __skb->wire_len; + } + + if (__skb->gso_segs > GSO_MAX_SEGS) + return -EINVAL; + skb_shinfo(skb)->gso_segs = __skb->gso_segs; + return 0; } @@ -289,6 +304,8 @@ static void convert_skb_to___skb(struct sk_buff *skb, struct __sk_buff *__skb) __skb->priority = skb->priority; __skb->tstamp = skb->tstamp; memcpy(__skb->cb, &cb->data, QDISC_CB_PRIV_LEN); + __skb->wire_len = cb->pkt_len; + __skb->gso_segs = skb_shinfo(skb)->gso_segs; } int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr, |