Commit 07e8b3ba authored by Akihiko Odaki's avatar Akihiko Odaki Committed by Jakub Kicinski
Browse files

tun: Keep hdr_len in tun_get_user()



hdr_len is repeatedly used so keep it in a local variable.

Signed-off-by: default avatarAkihiko Odaki <akihiko.odaki@daynix.com>
Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20250207-tun-v6-2-fb49cf8b103e@daynix.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 5a9c5e5d
Loading
Loading
Loading
Loading
+11 −13
Original line number Diff line number Diff line
@@ -1747,6 +1747,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
	struct virtio_net_hdr gso = { 0 };
	int good_linear;
	int copylen;
	int hdr_len = 0;
	bool zerocopy = false;
	int err;
	u32 rxhash = 0;
@@ -1773,19 +1774,21 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
		if (!copy_from_iter_full(&gso, sizeof(gso), from))
			return -EFAULT;

		if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
		    tun16_to_cpu(tun, gso.csum_start) + tun16_to_cpu(tun, gso.csum_offset) + 2 > tun16_to_cpu(tun, gso.hdr_len))
			gso.hdr_len = cpu_to_tun16(tun, tun16_to_cpu(tun, gso.csum_start) + tun16_to_cpu(tun, gso.csum_offset) + 2);
		hdr_len = tun16_to_cpu(tun, gso.hdr_len);

		if (tun16_to_cpu(tun, gso.hdr_len) > len)
		if (gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
			hdr_len = max(tun16_to_cpu(tun, gso.csum_start) + tun16_to_cpu(tun, gso.csum_offset) + 2, hdr_len);
			gso.hdr_len = cpu_to_tun16(tun, hdr_len);
		}

		if (hdr_len > len)
			return -EINVAL;
		iov_iter_advance(from, vnet_hdr_sz - sizeof(gso));
	}

	if ((tun->flags & TUN_TYPE_MASK) == IFF_TAP) {
		align += NET_IP_ALIGN;
		if (unlikely(len < ETH_HLEN ||
			     (gso.hdr_len && tun16_to_cpu(tun, gso.hdr_len) < ETH_HLEN)))
		if (unlikely(len < ETH_HLEN || (hdr_len && hdr_len < ETH_HLEN)))
			return -EINVAL;
	}

@@ -1798,9 +1801,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
		 * enough room for skb expand head in case it is used.
		 * The rest of the buffer is mapped from userspace.
		 */
		copylen = gso.hdr_len ? tun16_to_cpu(tun, gso.hdr_len) : GOODCOPY_LEN;
		if (copylen > good_linear)
			copylen = good_linear;
		copylen = min(hdr_len ? hdr_len : GOODCOPY_LEN, good_linear);
		linear = copylen;
		iov_iter_advance(&i, copylen);
		if (iov_iter_npages(&i, INT_MAX) <= MAX_SKB_FRAGS)
@@ -1821,10 +1822,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
	} else {
		if (!zerocopy) {
			copylen = len;
			if (tun16_to_cpu(tun, gso.hdr_len) > good_linear)
				linear = good_linear;
			else
				linear = tun16_to_cpu(tun, gso.hdr_len);
			linear = min(hdr_len, good_linear);
		}

		if (frags) {