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 | * int bpf_xdp_adjust_tail(struct xdp_buff *xdp_md, int delta) | 2015 | * int bpf_xdp_adjust_tail(struct xdp_buff *xdp_md, int delta) |
| 2016 | * Description | 2016 | * Description |
| 2017 | * Adjust (move) *xdp_md*\ **->data_end** by *delta* bytes. It is | 2017 | * Adjust (move) *xdp_md*\ **->data_end** by *delta* bytes. It is |
| 2018 | * only possible to shrink the packet as of this writing, | 2018 | * possible to both shrink and grow the packet tail. |
| 2019 | * therefore *delta* must be a negative integer. | 2019 | * Shrink done via *delta* being a negative integer. |
| 2020 | * | 2020 | * |
| 2021 | * A call to this helper is susceptible to change the underlying | 2021 | * A call to this helper is susceptible to change the underlying |
| 2022 | * packet buffer. Therefore, at load time, all checks on pointers | 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 | BPF_CALL_2(bpf_xdp_adjust_tail, struct xdp_buff *, xdp, int, offset) | 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 | void *data_end = xdp->data_end + offset; | 3415 | void *data_end = xdp->data_end + offset; |
| 3415 | 3416 | ||
| 3416 | /* only shrinking is allowed for now. */ | 3417 | /* Notice that xdp_data_hard_end have reserved some tailroom */ |
| 3417 | if (unlikely(offset >= 0)) | 3418 | if (unlikely(data_end > data_hard_end)) |
| 3418 | return -EINVAL; | 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 | if (unlikely(data_end < xdp->data + ETH_HLEN)) | 3427 | if (unlikely(data_end < xdp->data + ETH_HLEN)) |
| 3421 | return -EINVAL; | 3428 | return -EINVAL; |
| 3422 | 3429 | ||