Finally, after all drivers have a frame size, allow BPF-helper bpf_xdp_adjust_tail() to grow or extend packet size at frame tail. Remember that helper/macro xdp_data_hard_end have reserved some tailroom. Thus, this helper makes sure that the BPF-prog don't have access to this tailroom area. V2: Remove one chicken check and use WARN_ONCE for other
Unified · Split
| @@ -2015,8 +2015,8 @@ union bpf_attr { · 2014 unmodified lines | ||
| 2015 | 2015 | * int bpf_xdp_adjust_tail(struct xdp_buff *xdp_md, int delta) |
| 2016 | 2016 | * Description |
| 2017 | 2017 | * Adjust (move) *xdp_md*\ **->data_end** by *delta* bytes. It is |
| 2018 | − * only possible to shrink the packet as of this writing, | |
| 2019 | − * therefore *delta* must be a negative integer. | |
| 2018 | + * possible to both shrink and grow the packet tail. | |
| 2019 | + * Shrink done via *delta* being a negative integer. | |
| 2020 | 2020 | * |
| 2021 | 2021 | * A call to this helper is susceptible to change the underlying |
| 2022 | 2022 | * packet buffer. Therefore, at load time, all checks on pointers |
| @@ -3411,12 +3411,19 @@ static const struct bpf_func_proto bpf_xdp_adjust_head_proto = { · 3410 unmodified lines | ||
| 3411 | 3411 | |
| 3412 | 3412 | BPF_CALL_2(bpf_xdp_adjust_tail, struct xdp_buff *, xdp, int, offset) |
| 3413 | 3413 | { |
| 3414 | + void *data_hard_end = xdp_data_hard_end(xdp); /* use xdp->frame_sz */ | |
| 3414 | 3415 | void *data_end = xdp->data_end + offset; |
| 3415 | 3416 | |
| 3416 | − /* only shrinking is allowed for now. */ | |
| 3417 | − if (unlikely(offset >= 0)) | |
| 3417 | + /* Notice that xdp_data_hard_end have reserved some tailroom */ | |
| 3418 | + if (unlikely(data_end > data_hard_end)) | |
| 3418 | 3419 | return -EINVAL; |
| 3419 | 3420 | |
| 3421 | + /* ALL drivers MUST init xdp->frame_sz, chicken check below */ | |
| 3422 | + if (unlikely(xdp->frame_sz > PAGE_SIZE)) { | |
| 3423 | + WARN_ONCE(1, "Too BIG xdp->frame_sz = %d\n", xdp->frame_sz); | |
| 3424 | + return -EINVAL; | |
| 3425 | + } | |
| 3426 | + | |
| 3420 | 3427 | if (unlikely(data_end < xdp->data + ETH_HLEN)) |
| 3421 | 3428 | return -EINVAL; |
| 3422 | 3429 | |