Skip to content

Commit 4b3e33f

Browse files
Thomas BogendoerferPaolo Abeni
authored andcommitted
ip6_tunnel: Fix broken GRO
GRO code checks for matching layer 2 headers to see, if packet belongs to the same flow and because ip6 tunnel set dev->hard_header_len this check fails in cases, where it shouldn't. To fix this don't set hard_header_len, but use needed_headroom like ipv4/ip_tunnel.c does. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Thomas Bogendoerfer <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
1 parent 807067b commit 4b3e33f

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

net/ipv6/ip6_tunnel.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,7 +1507,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
15071507
tdev = __dev_get_by_index(t->net, p->link);
15081508

15091509
if (tdev) {
1510-
dev->hard_header_len = tdev->hard_header_len + t_hlen;
1510+
dev->needed_headroom = tdev->hard_header_len +
1511+
tdev->needed_headroom + t_hlen;
15111512
mtu = min_t(unsigned int, tdev->mtu, IP6_MAX_MTU);
15121513

15131514
mtu = mtu - t_hlen;
@@ -1731,7 +1732,9 @@ ip6_tnl_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
17311732
int ip6_tnl_change_mtu(struct net_device *dev, int new_mtu)
17321733
{
17331734
struct ip6_tnl *tnl = netdev_priv(dev);
1735+
int t_hlen;
17341736

1737+
t_hlen = tnl->hlen + sizeof(struct ipv6hdr);
17351738
if (tnl->parms.proto == IPPROTO_IPV6) {
17361739
if (new_mtu < IPV6_MIN_MTU)
17371740
return -EINVAL;
@@ -1740,10 +1743,10 @@ int ip6_tnl_change_mtu(struct net_device *dev, int new_mtu)
17401743
return -EINVAL;
17411744
}
17421745
if (tnl->parms.proto == IPPROTO_IPV6 || tnl->parms.proto == 0) {
1743-
if (new_mtu > IP6_MAX_MTU - dev->hard_header_len)
1746+
if (new_mtu > IP6_MAX_MTU - dev->hard_header_len - t_hlen)
17441747
return -EINVAL;
17451748
} else {
1746-
if (new_mtu > IP_MAX_MTU - dev->hard_header_len)
1749+
if (new_mtu > IP_MAX_MTU - dev->hard_header_len - t_hlen)
17471750
return -EINVAL;
17481751
}
17491752
WRITE_ONCE(dev->mtu, new_mtu);
@@ -1887,12 +1890,11 @@ ip6_tnl_dev_init_gen(struct net_device *dev)
18871890
t_hlen = t->hlen + sizeof(struct ipv6hdr);
18881891

18891892
dev->type = ARPHRD_TUNNEL6;
1890-
dev->hard_header_len = LL_MAX_HEADER + t_hlen;
18911893
dev->mtu = ETH_DATA_LEN - t_hlen;
18921894
if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
18931895
dev->mtu -= 8;
18941896
dev->min_mtu = ETH_MIN_MTU;
1895-
dev->max_mtu = IP6_MAX_MTU - dev->hard_header_len;
1897+
dev->max_mtu = IP6_MAX_MTU - dev->hard_header_len - t_hlen;
18961898

18971899
netdev_hold(dev, &t->dev_tracker, GFP_KERNEL);
18981900
netdev_lockdep_set_classes(dev);

0 commit comments

Comments
 (0)