Skip to content

Commit

Permalink
ip_tunnel: restore binding to ifaces with a large mtu
Browse files Browse the repository at this point in the history
After commit f6cc9c0, the following conf is broken (note that the
default loopback mtu is 65536, ie IP_MAX_MTU + 1):

$ ip tunnel add gre1 mode gre local 10.125.0.1 remote 10.125.0.2 dev lo
add tunnel "gre0" failed: Invalid argument
$ ip l a type dummy
$ ip l s dummy1 up
$ ip l s dummy1 mtu 65535
$ ip tunnel add gre1 mode gre local 10.125.0.1 remote 10.125.0.2 dev dummy1
add tunnel "gre0" failed: Invalid argument

dev_set_mtu() doesn't allow to set a mtu which is too large.
First, let's cap the mtu returned by ip_tunnel_bind_dev(). Second, remove
the magic value 0xFFF8 and use IP_MAX_MTU instead.
0xFFF8 seems to be there for ages, I don't know why this value was used.

With a recent kernel, it's also possible to set a mtu > IP_MAX_MTU:
$ ip l s dummy1 mtu 66000
After that patch, it's also possible to bind an ip tunnel on that kind of
interface.

CC: Petr Machata <[email protected]>
CC: Ido Schimmel <[email protected]>
Link: https://git.kernel.org/pub/scm/linux/kernel/git/davem/netdev-vger-cvs.git/commit/?id=e5afd356a411a
Fixes: f6cc9c0 ("ip_tunnel: Emit events for post-register MTU changes")
Signed-off-by: Nicolas Dichtel <[email protected]>
Reviewed-by: Ido Schimmel <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
NicolasDichtel authored and davem330 committed Jun 1, 2018
1 parent ccfde6e commit 82612de
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions net/ipv4/ip_tunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ static int ip_tunnel_bind_dev(struct net_device *dev)

if (tdev) {
hlen = tdev->hard_header_len + tdev->needed_headroom;
mtu = tdev->mtu;
mtu = min(tdev->mtu, IP_MAX_MTU);
}

dev->needed_headroom = t_hlen + hlen;
Expand Down Expand Up @@ -362,7 +362,7 @@ static struct ip_tunnel *ip_tunnel_create(struct net *net,
nt = netdev_priv(dev);
t_hlen = nt->hlen + sizeof(struct iphdr);
dev->min_mtu = ETH_MIN_MTU;
dev->max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen;
dev->max_mtu = IP_MAX_MTU - dev->hard_header_len - t_hlen;
ip_tunnel_add(itn, nt);
return nt;

Expand Down Expand Up @@ -930,7 +930,7 @@ int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
int t_hlen = tunnel->hlen + sizeof(struct iphdr);
int max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen;
int max_mtu = IP_MAX_MTU - dev->hard_header_len - t_hlen;

if (new_mtu < ETH_MIN_MTU)
return -EINVAL;
Expand Down Expand Up @@ -1107,7 +1107,7 @@ int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],

mtu = ip_tunnel_bind_dev(dev);
if (tb[IFLA_MTU]) {
unsigned int max = 0xfff8 - dev->hard_header_len - nt->hlen;
unsigned int max = IP_MAX_MTU - dev->hard_header_len - nt->hlen;

mtu = clamp(dev->mtu, (unsigned int)ETH_MIN_MTU,
(unsigned int)(max - sizeof(struct iphdr)));
Expand Down

0 comments on commit 82612de

Please sign in to comment.