|
76 | 76 | #include <net/bpf_sk_storage.h>
|
77 | 77 | #include <net/transp_v6.h>
|
78 | 78 | #include <linux/btf_ids.h>
|
| 79 | +#include <net/tls.h> |
79 | 80 |
|
80 | 81 | static const struct bpf_func_proto *
|
81 | 82 | 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)
|
3479 | 3480 | SKB_MAX_ALLOC;
|
3480 | 3481 | }
|
3481 | 3482 |
|
| 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 | + |
3482 | 3525 | BPF_CALL_4(bpf_skb_adjust_room, struct sk_buff *, skb, s32, len_diff,
|
3483 | 3526 | u32, mode, u64, flags)
|
3484 | 3527 | {
|
@@ -6745,6 +6788,7 @@ bool bpf_helper_changes_pkt_data(void *func)
|
6745 | 6788 | func == bpf_skb_change_tail ||
|
6746 | 6789 | func == sk_skb_change_tail ||
|
6747 | 6790 | func == bpf_skb_adjust_room ||
|
| 6791 | + func == sk_skb_adjust_room || |
6748 | 6792 | func == bpf_skb_pull_data ||
|
6749 | 6793 | func == sk_skb_pull_data ||
|
6750 | 6794 | func == bpf_clone_redirect ||
|
@@ -7218,6 +7262,8 @@ sk_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
|
7218 | 7262 | return &sk_skb_change_tail_proto;
|
7219 | 7263 | case BPF_FUNC_skb_change_head:
|
7220 | 7264 | return &sk_skb_change_head_proto;
|
| 7265 | + case BPF_FUNC_skb_adjust_room: |
| 7266 | + return &sk_skb_adjust_room_proto; |
7221 | 7267 | case BPF_FUNC_get_socket_cookie:
|
7222 | 7268 | return &bpf_get_socket_cookie_proto;
|
7223 | 7269 | case BPF_FUNC_get_socket_uid:
|
|
0 commit comments