|
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); |
@@ -3218,6 +3219,53 @@ static u32 __bpf_skb_max_len(const struct sk_buff *skb) |
3218 | 3219 | SKB_MAX_ALLOC; |
3219 | 3220 | } |
3220 | 3221 |
|
| 3222 | +BPF_CALL_4(sk_skb_adjust_room, struct sk_buff *, skb, s32, len_diff, |
| 3223 | + u32, mode, u64, flags) |
| 3224 | +{ |
| 3225 | + unsigned int len_diff_abs = abs(len_diff); |
| 3226 | + bool shrink = len_diff < 0; |
| 3227 | + int ret = 0; |
| 3228 | + |
| 3229 | + if (unlikely(flags)) |
| 3230 | + return -EINVAL; |
| 3231 | + if (unlikely(len_diff_abs > 0xfffU)) |
| 3232 | + return -EFAULT; |
| 3233 | + |
| 3234 | + if (!shrink) { |
| 3235 | + unsigned int grow = len_diff; |
| 3236 | + |
| 3237 | + ret = skb_cow(skb, grow); |
| 3238 | + if (likely(!ret)) { |
| 3239 | + __skb_push(skb, len_diff_abs); |
| 3240 | + memset(skb->data, 0, len_diff_abs); |
| 3241 | + } |
| 3242 | + } else { |
| 3243 | + /* skb_ensure_writable() is not needed here, as we're |
| 3244 | + * already working on an uncloned skb. |
| 3245 | + */ |
| 3246 | + if (unlikely(!pskb_may_pull(skb, len_diff_abs))) |
| 3247 | + return -ENOMEM; |
| 3248 | + __skb_pull(skb, len_diff_abs); |
| 3249 | + } |
| 3250 | + bpf_compute_data_end_sk_skb(skb); |
| 3251 | + if (tls_sw_has_ctx_rx(skb->sk)) { |
| 3252 | + struct strp_msg *rxm = strp_msg(skb); |
| 3253 | + |
| 3254 | + rxm->full_len += len_diff; |
| 3255 | + } |
| 3256 | + return ret; |
| 3257 | +} |
| 3258 | + |
| 3259 | +static const struct bpf_func_proto sk_skb_adjust_room_proto = { |
| 3260 | + .func = sk_skb_adjust_room, |
| 3261 | + .gpl_only = false, |
| 3262 | + .ret_type = RET_INTEGER, |
| 3263 | + .arg1_type = ARG_PTR_TO_CTX, |
| 3264 | + .arg2_type = ARG_ANYTHING, |
| 3265 | + .arg3_type = ARG_ANYTHING, |
| 3266 | + .arg4_type = ARG_ANYTHING, |
| 3267 | +}; |
| 3268 | + |
3221 | 3269 | BPF_CALL_4(bpf_skb_adjust_room, struct sk_buff *, skb, s32, len_diff, |
3222 | 3270 | u32, mode, u64, flags) |
3223 | 3271 | { |
@@ -6484,6 +6532,7 @@ bool bpf_helper_changes_pkt_data(void *func) |
6484 | 6532 | func == bpf_skb_change_tail || |
6485 | 6533 | func == sk_skb_change_tail || |
6486 | 6534 | func == bpf_skb_adjust_room || |
| 6535 | + func == sk_skb_adjust_room || |
6487 | 6536 | func == bpf_skb_pull_data || |
6488 | 6537 | func == sk_skb_pull_data || |
6489 | 6538 | func == bpf_clone_redirect || |
@@ -6951,6 +7000,8 @@ sk_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) |
6951 | 7000 | return &sk_skb_change_tail_proto; |
6952 | 7001 | case BPF_FUNC_skb_change_head: |
6953 | 7002 | return &sk_skb_change_head_proto; |
| 7003 | + case BPF_FUNC_skb_adjust_room: |
| 7004 | + return &sk_skb_adjust_room_proto; |
6954 | 7005 | case BPF_FUNC_get_socket_cookie: |
6955 | 7006 | return &bpf_get_socket_cookie_proto; |
6956 | 7007 | case BPF_FUNC_get_socket_uid: |
|
0 commit comments