Skip to content

Commit fb91db0

Browse files
author
Alexei Starovoitov
committed
Merge branch 'Add skb_adjust_room() for SK_SKB'
John Fastabend says: ==================== This implements the helper skb_adjust_room() for BPF_SKS_SK_STREAM_VERDICT programs so we can push/pop headers from the data on recieve. One use case is to pop TLS headers off kTLS packets. The first patch implements the helper and the second updates test_sockmap to use it removing some case handling we had to do earlier to account for the TLS headers in the kTLS tests. v1->v2: Fix error path for TLS case (Daniel) check mode input is 0 because we don't use it now (Daniel) Remove incorrect/misleading comment (Lorenz) Thanks, John Acked-by: Martin KaFai Lau <[email protected]> --- ==================== Signed-off-by: Alexei Starovoitov <[email protected]>
2 parents 60a128b + 91274ca commit fb91db0

File tree

3 files changed

+77
-30
lines changed

3 files changed

+77
-30
lines changed

net/core/filter.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
#include <net/bpf_sk_storage.h>
7777
#include <net/transp_v6.h>
7878
#include <linux/btf_ids.h>
79+
#include <net/tls.h>
7980

8081
static const struct bpf_func_proto *
8182
bpf_sk_base_func_proto(enum bpf_func_id func_id);
@@ -3479,6 +3480,48 @@ static u32 __bpf_skb_max_len(const struct sk_buff *skb)
34793480
SKB_MAX_ALLOC;
34803481
}
34813482

3483+
BPF_CALL_4(sk_skb_adjust_room, struct sk_buff *, skb, s32, len_diff,
3484+
u32, mode, u64, flags)
3485+
{
3486+
u32 len_diff_abs = abs(len_diff);
3487+
bool shrink = len_diff < 0;
3488+
int ret = 0;
3489+
3490+
if (unlikely(flags || mode))
3491+
return -EINVAL;
3492+
if (unlikely(len_diff_abs > 0xfffU))
3493+
return -EFAULT;
3494+
3495+
if (!shrink) {
3496+
ret = skb_cow(skb, len_diff);
3497+
if (unlikely(ret < 0))
3498+
return ret;
3499+
__skb_push(skb, len_diff_abs);
3500+
memset(skb->data, 0, len_diff_abs);
3501+
} else {
3502+
if (unlikely(!pskb_may_pull(skb, len_diff_abs)))
3503+
return -ENOMEM;
3504+
__skb_pull(skb, len_diff_abs);
3505+
}
3506+
bpf_compute_data_end_sk_skb(skb);
3507+
if (tls_sw_has_ctx_rx(skb->sk)) {
3508+
struct strp_msg *rxm = strp_msg(skb);
3509+
3510+
rxm->full_len += len_diff;
3511+
}
3512+
return ret;
3513+
}
3514+
3515+
static const struct bpf_func_proto sk_skb_adjust_room_proto = {
3516+
.func = sk_skb_adjust_room,
3517+
.gpl_only = false,
3518+
.ret_type = RET_INTEGER,
3519+
.arg1_type = ARG_PTR_TO_CTX,
3520+
.arg2_type = ARG_ANYTHING,
3521+
.arg3_type = ARG_ANYTHING,
3522+
.arg4_type = ARG_ANYTHING,
3523+
};
3524+
34823525
BPF_CALL_4(bpf_skb_adjust_room, struct sk_buff *, skb, s32, len_diff,
34833526
u32, mode, u64, flags)
34843527
{
@@ -6745,6 +6788,7 @@ bool bpf_helper_changes_pkt_data(void *func)
67456788
func == bpf_skb_change_tail ||
67466789
func == sk_skb_change_tail ||
67476790
func == bpf_skb_adjust_room ||
6791+
func == sk_skb_adjust_room ||
67486792
func == bpf_skb_pull_data ||
67496793
func == sk_skb_pull_data ||
67506794
func == bpf_clone_redirect ||
@@ -7218,6 +7262,8 @@ sk_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
72187262
return &sk_skb_change_tail_proto;
72197263
case BPF_FUNC_skb_change_head:
72207264
return &sk_skb_change_head_proto;
7265+
case BPF_FUNC_skb_adjust_room:
7266+
return &sk_skb_adjust_room_proto;
72217267
case BPF_FUNC_get_socket_cookie:
72227268
return &bpf_get_socket_cookie_proto;
72237269
case BPF_FUNC_get_socket_uid:

tools/testing/selftests/bpf/progs/test_sockmap_kern.h

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,39 +131,55 @@ int bpf_prog2(struct __sk_buff *skb)
131131

132132
}
133133

134-
SEC("sk_skb3")
135-
int bpf_prog3(struct __sk_buff *skb)
134+
static inline void bpf_write_pass(struct __sk_buff *skb, int offset)
136135
{
137-
const int one = 1;
138-
int err, *f, ret = SK_PASS;
136+
int err = bpf_skb_pull_data(skb, 6 + offset);
139137
void *data_end;
140138
char *c;
141139

142-
err = bpf_skb_pull_data(skb, 19);
143140
if (err)
144-
goto tls_out;
141+
return;
145142

146143
c = (char *)(long)skb->data;
147144
data_end = (void *)(long)skb->data_end;
148145

149-
if (c + 18 < data_end)
150-
memcpy(&c[13], "PASS", 4);
146+
if (c + 5 + offset < data_end)
147+
memcpy(c + offset, "PASS", 4);
148+
}
149+
150+
SEC("sk_skb3")
151+
int bpf_prog3(struct __sk_buff *skb)
152+
{
153+
int err, *f, ret = SK_PASS;
154+
const int one = 1;
155+
151156
f = bpf_map_lookup_elem(&sock_skb_opts, &one);
152157
if (f && *f) {
153158
__u64 flags = 0;
154159

155160
ret = 0;
156161
flags = *f;
162+
163+
err = bpf_skb_adjust_room(skb, -13, 0, 0);
164+
if (err)
165+
return SK_DROP;
166+
err = bpf_skb_adjust_room(skb, 4, 0, 0);
167+
if (err)
168+
return SK_DROP;
169+
bpf_write_pass(skb, 0);
157170
#ifdef SOCKMAP
158171
return bpf_sk_redirect_map(skb, &tls_sock_map, ret, flags);
159172
#else
160173
return bpf_sk_redirect_hash(skb, &tls_sock_map, &ret, flags);
161174
#endif
162175
}
163-
164176
f = bpf_map_lookup_elem(&sock_skb_opts, &one);
165177
if (f && *f)
166178
ret = SK_DROP;
179+
err = bpf_skb_adjust_room(skb, 4, 0, 0);
180+
if (err)
181+
return SK_DROP;
182+
bpf_write_pass(skb, 13);
167183
tls_out:
168184
return ret;
169185
}

tools/testing/selftests/bpf/test_sockmap.c

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -518,28 +518,13 @@ static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz)
518518
if (i == 0 && txmsg_ktls_skb) {
519519
if (msg->msg_iov[i].iov_len < 4)
520520
return -EIO;
521-
if (txmsg_ktls_skb_redir) {
522-
if (memcmp(&d[13], "PASS", 4) != 0) {
523-
fprintf(stderr,
524-
"detected redirect ktls_skb data error with skb ingress update @iov[%i]:%i \"%02x %02x %02x %02x\" != \"PASS\"\n", i, 0, d[13], d[14], d[15], d[16]);
525-
return -EIO;
526-
}
527-
d[13] = 0;
528-
d[14] = 1;
529-
d[15] = 2;
530-
d[16] = 3;
531-
j = 13;
532-
} else if (txmsg_ktls_skb) {
533-
if (memcmp(d, "PASS", 4) != 0) {
534-
fprintf(stderr,
535-
"detected ktls_skb data error with skb ingress update @iov[%i]:%i \"%02x %02x %02x %02x\" != \"PASS\"\n", i, 0, d[0], d[1], d[2], d[3]);
536-
return -EIO;
537-
}
538-
d[0] = 0;
539-
d[1] = 1;
540-
d[2] = 2;
541-
d[3] = 3;
521+
if (memcmp(d, "PASS", 4) != 0) {
522+
fprintf(stderr,
523+
"detected skb data error with skb ingress update @iov[%i]:%i \"%02x %02x %02x %02x\" != \"PASS\"\n",
524+
i, 0, d[0], d[1], d[2], d[3]);
525+
return -EIO;
542526
}
527+
j = 4; /* advance index past PASS header */
543528
}
544529

545530
for (; j < msg->msg_iov[i].iov_len && size; j++) {

0 commit comments

Comments
 (0)