bpf: BPF-helper for MTU checking add length input
The FIB lookup example[1] show how the IP-header field tot_len
(iph->tot_len) is used as input to perform the MTU check.
This patch extend the BPF-helper bpf_check_mtu() with the same ability
to provide the length as user parameter input, via mtu_len parameter.
This still needs to be done before the bpf_check_mtu() helper API
becomes frozen.
  [1] samples/bpf/xdp_fwd_kern.c
Fixes: 34b2021cc6 ("bpf: Add BPF-helper for MTU checking")
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/161521555850.3515614.6533850861569774444.stgit@firesoul
			
			
This commit is contained in:
		
							parent
							
								
									e7fb6465d4
								
							
						
					
					
						commit
						e5e35e754c
					
				| @ -3850,7 +3850,7 @@ union bpf_attr { | ||||
|  * | ||||
|  * long bpf_check_mtu(void *ctx, u32 ifindex, u32 *mtu_len, s32 len_diff, u64 flags) | ||||
|  *	Description | ||||
|  *		Check ctx packet size against exceeding MTU of net device (based | ||||
|  *		Check packet size against exceeding MTU of net device (based | ||||
|  *		on *ifindex*).  This helper will likely be used in combination | ||||
|  *		with helpers that adjust/change the packet size. | ||||
|  * | ||||
| @ -3867,6 +3867,14 @@ union bpf_attr { | ||||
|  *		against the current net device.  This is practical if this isn't | ||||
|  *		used prior to redirect. | ||||
|  * | ||||
|  *		On input *mtu_len* must be a valid pointer, else verifier will | ||||
|  *		reject BPF program.  If the value *mtu_len* is initialized to | ||||
|  *		zero then the ctx packet size is use.  When value *mtu_len* is | ||||
|  *		provided as input this specify the L3 length that the MTU check | ||||
|  *		is done against. Remember XDP and TC length operate at L2, but | ||||
|  *		this value is L3 as this correlate to MTU and IP-header tot_len | ||||
|  *		values which are L3 (similar behavior as bpf_fib_lookup). | ||||
|  * | ||||
|  *		The Linux kernel route table can configure MTUs on a more | ||||
|  *		specific per route level, which is not provided by this helper. | ||||
|  *		For route level MTU checks use the **bpf_fib_lookup**\ () | ||||
| @ -3891,11 +3899,9 @@ union bpf_attr { | ||||
|  * | ||||
|  *		On return *mtu_len* pointer contains the MTU value of the net | ||||
|  *		device.  Remember the net device configured MTU is the L3 size, | ||||
|  *		which is returned here and XDP and TX length operate at L2. | ||||
|  *		which is returned here and XDP and TC length operate at L2. | ||||
|  *		Helper take this into account for you, but remember when using | ||||
|  *		MTU value in your BPF-code.  On input *mtu_len* must be a valid | ||||
|  *		pointer and be initialized (to zero), else verifier will reject | ||||
|  *		BPF program. | ||||
|  *		MTU value in your BPF-code. | ||||
|  * | ||||
|  *	Return | ||||
|  *		* 0 on success, and populate MTU value in *mtu_len* pointer. | ||||
|  | ||||
| @ -5658,7 +5658,7 @@ BPF_CALL_5(bpf_skb_check_mtu, struct sk_buff *, skb, | ||||
| 	if (unlikely(flags & ~(BPF_MTU_CHK_SEGS))) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	if (unlikely(flags & BPF_MTU_CHK_SEGS && len_diff)) | ||||
| 	if (unlikely(flags & BPF_MTU_CHK_SEGS && (len_diff || *mtu_len))) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	dev = __dev_via_ifindex(dev, ifindex); | ||||
| @ -5668,7 +5668,11 @@ BPF_CALL_5(bpf_skb_check_mtu, struct sk_buff *, skb, | ||||
| 	mtu = READ_ONCE(dev->mtu); | ||||
| 
 | ||||
| 	dev_len = mtu + dev->hard_header_len; | ||||
| 	skb_len = skb->len + len_diff; /* minus result pass check */ | ||||
| 
 | ||||
| 	/* If set use *mtu_len as input, L3 as iph->tot_len (like fib_lookup) */ | ||||
| 	skb_len = *mtu_len ? *mtu_len + dev->hard_header_len : skb->len; | ||||
| 
 | ||||
| 	skb_len += len_diff; /* minus result pass check */ | ||||
| 	if (skb_len <= dev_len) { | ||||
| 		ret = BPF_MTU_CHK_RET_SUCCESS; | ||||
| 		goto out; | ||||
| @ -5713,6 +5717,10 @@ BPF_CALL_5(bpf_xdp_check_mtu, struct xdp_buff *, xdp, | ||||
| 	/* Add L2-header as dev MTU is L3 size */ | ||||
| 	dev_len = mtu + dev->hard_header_len; | ||||
| 
 | ||||
| 	/* Use *mtu_len as input, L3 as iph->tot_len (like fib_lookup) */ | ||||
| 	if (*mtu_len) | ||||
| 		xdp_len = *mtu_len + dev->hard_header_len; | ||||
| 
 | ||||
| 	xdp_len += len_diff; /* minus result pass check */ | ||||
| 	if (xdp_len > dev_len) | ||||
| 		ret = BPF_MTU_CHK_RET_FRAG_NEEDED; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user