Add a bpf_csum_level() helper which BPF programs can use in combination with bpf_skb_adjust_room() when they pass in BPF_F_ADJ_ROOM_NO_CSUM_RESET flag to the latter to avoid falling back to CHECKSUM_NONE. The bpf_csum_level() allows to adjust CHECKSUM_UNNECESSARY skb->csum_levels via BPF_CSUM_LEVEL_{INC,DEC} which calls __skb_{incr,decr}_checksum_unnecessary() on the skb. The helper also allows a BPF_CSUM_LEVEL_RESET which sets the skb's csum to CHECKSUM_NONE as well as a BPF_CSUM_LEVEL_QUERY to just return the current level. Without this helper, there is no way to otherwise adjust the skb->csum_level. I did not add an extra dummy flags as there is plenty of free bitspace in level argument itself iff ever needed in future.
Showing the changes to include/uapi/linux (1 of 3 files). Show all
Unified · Split
| @@ -3220,6 +3220,38 @@ union bpf_attr { · 3219 unmodified lines | ||
| 3220 | 3220 | * calculation. |
| 3221 | 3221 | * Return |
| 3222 | 3222 | * Requested value, or 0, if flags are not recognized. |
| 3223 | + * | |
| 3224 | + * int bpf_csum_level(struct sk_buff *skb, u64 level) | |
| 3225 | + * Description | |
| 3226 | + * Change the skbs checksum level by one layer up or down, or | |
| 3227 | + * reset it entirely to none in order to have the stack perform | |
| 3228 | + * checksum validation. The level is applicable to the following | |
| 3229 | + * protocols: TCP, UDP, GRE, SCTP, FCOE. For example, a decap of | |
| 3230 | + * | ETH | IP | UDP | GUE | IP | TCP | into | ETH | IP | TCP | | |
| 3231 | + * through **bpf_skb_adjust_room**\ () helper with passing in | |
| 3232 | + * **BPF_F_ADJ_ROOM_NO_CSUM_RESET** flag would require one call | |
| 3233 | + * to **bpf_csum_level**\ () with **BPF_CSUM_LEVEL_DEC** since | |
| 3234 | + * the UDP header is removed. Similarly, an encap of the latter | |
| 3235 | + * into the former could be accompanied by a helper call to | |
| 3236 | + * **bpf_csum_level**\ () with **BPF_CSUM_LEVEL_INC** if the | |
| 3237 | + * skb is still intended to be processed in higher layers of the | |
| 3238 | + * stack instead of just egressing at tc. | |
| 3239 | + * | |
| 3240 | + * There are three supported level settings at this time: | |
| 3241 | + * | |
| 3242 | + * * **BPF_CSUM_LEVEL_INC**: Increases skb->csum_level for skbs | |
| 3243 | + * with CHECKSUM_UNNECESSARY. | |
| 3244 | + * * **BPF_CSUM_LEVEL_DEC**: Decreases skb->csum_level for skbs | |
| 3245 | + * with CHECKSUM_UNNECESSARY. | |
| 3246 | + * * **BPF_CSUM_LEVEL_RESET**: Resets skb->csum_level to 0 and | |
| 3247 | + * sets CHECKSUM_NONE to force checksum validation by the stack. | |
| 3248 | + * * **BPF_CSUM_LEVEL_QUERY**: No-op, returns the current | |
| 3249 | + * skb->csum_level. | |
| 3250 | + * Return | |
| 3251 | + * 0 on success, or a negative error in case of failure. In the | |
| 3252 | + * case of **BPF_CSUM_LEVEL_QUERY**, the current skb->csum_level | |
| 3253 | + * is returned or the error code -EACCES in case the skb is not | |
| 3254 | + * subject to CHECKSUM_UNNECESSARY. | |
| 3223 | 3255 | */ |
| 3224 | 3256 | #define __BPF_FUNC_MAPPER(FN) \ |
| 3225 | 3257 | FN(unspec), \ |
| @@ -3356,7 +3388,8 @@ union bpf_attr { · 130 unmodified lines | ||
| 3356 | 3388 | FN(ringbuf_reserve), \ |
| 3357 | 3389 | FN(ringbuf_submit), \ |
| 3358 | 3390 | FN(ringbuf_discard), \ |
| 3359 | − FN(ringbuf_query), | |
| 3391 | + FN(ringbuf_query), \ | |
| 3392 | + FN(csum_level), | |
| 3360 | 3393 | |
| 3361 | 3394 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper |
| 3362 | 3395 | * function eBPF program intends to call |
| @@ -3433,6 +3466,14 @@ enum { · 70 unmodified lines | ||
| 3433 | 3466 | BPF_F_CURRENT_NETNS = (-1L), |
| 3434 | 3467 | }; |
| 3435 | 3468 | |
| 3469 | +/* BPF_FUNC_csum_level level values. */ | |
| 3470 | +enum { | |
| 3471 | + BPF_CSUM_LEVEL_QUERY, | |
| 3472 | + BPF_CSUM_LEVEL_INC, | |
| 3473 | + BPF_CSUM_LEVEL_DEC, | |
| 3474 | + BPF_CSUM_LEVEL_RESET, | |
| 3475 | +}; | |
| 3476 | + | |
| 3436 | 3477 | /* BPF_FUNC_skb_adjust_room flags. */ |
| 3437 | 3478 | enum { |
| 3438 | 3479 | BPF_F_ADJ_ROOM_FIXED_GSO = (1ULL << 0), |