Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 38502af7 authored by Jason Wang's avatar Jason Wang Committed by David S. Miller
Browse files

tuntap: set transport header before passing it to kernel



Currently, for the packets receives from tuntap, before doing header check,
kernel just reset the transport header in netif_receive_skb() which pretends no
l4 header. This is suboptimal for precise packet length estimation (introduced
in 1def9238) which needs correct l4 header for gso packets.

So this patch set the transport header to csum_start for partial checksum
packets, otherwise it first try skb_flow_dissect(), if it fails, just reset the
transport header.

Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: default avatarJason Wang <jasowang@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9b4d669b
Loading
Loading
Loading
Loading
+10 −0
Original line number Original line Diff line number Diff line
@@ -70,6 +70,7 @@
#include <net/sock.h>
#include <net/sock.h>


#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <net/flow_keys.h>


/* Uncomment to enable debugging */
/* Uncomment to enable debugging */
/* #define TUN_DEBUG 1 */
/* #define TUN_DEBUG 1 */
@@ -1049,6 +1050,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
	bool zerocopy = false;
	bool zerocopy = false;
	int err;
	int err;
	u32 rxhash;
	u32 rxhash;
	struct flow_keys keys;


	if (!(tun->flags & TUN_NO_PI)) {
	if (!(tun->flags & TUN_NO_PI)) {
		if ((len -= sizeof(pi)) > total_len)
		if ((len -= sizeof(pi)) > total_len)
@@ -1203,6 +1205,14 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
	}
	}


	skb_reset_network_header(skb);
	skb_reset_network_header(skb);

	if (skb->ip_summed == CHECKSUM_PARTIAL)
		skb_set_transport_header(skb, skb_checksum_start_offset(skb));
	else if (skb_flow_dissect(skb, &keys))
		skb_set_transport_header(skb, keys.thoff);
	else
		skb_reset_transport_header(skb);

	rxhash = skb_get_rxhash(skb);
	rxhash = skb_get_rxhash(skb);
	netif_rx_ni(skb);
	netif_rx_ni(skb);