diff options
author | David Wragg <david@weave.works> | 2016-02-18 17:43:29 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-02-18 13:57:15 -0500 |
commit | aeee0e66c6b46cee311be22cb82735763eceb7c3 (patch) | |
tree | 15c5724ed408fbc8fbd5e9d54af92eb48f49758b /drivers/net/geneve.c | |
parent | 7716682cc58e305e22207d5bb315f26af6b1e243 (diff) | |
download | blackbird-obmc-linux-aeee0e66c6b46cee311be22cb82735763eceb7c3.tar.gz blackbird-obmc-linux-aeee0e66c6b46cee311be22cb82735763eceb7c3.zip |
geneve: Refine MTU limit
Calculate the maximum MTU taking into account the size of headers
involved in GENEVE encapsulation, as for other tunnel types.
Changes in v3:
- Correct comment style
Changes in v2:
- Conform more closely to ip_tunnel_change_mtu
- Exclude GENEVE options from max MTU calculation
Signed-off-by: David Wragg <david@weave.works>
Acked-by: Jesse Gross <jesse@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/geneve.c')
-rw-r--r-- | drivers/net/geneve.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 028e3873c310..70975700f91d 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -1039,17 +1039,34 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev) return geneve_xmit_skb(skb, dev, info); } -static int geneve_change_mtu(struct net_device *dev, int new_mtu) +static int __geneve_change_mtu(struct net_device *dev, int new_mtu, bool strict) { - /* GENEVE overhead is not fixed, so we can't enforce a more - * precise max MTU. + /* The max_mtu calculation does not take account of GENEVE + * options, to avoid excluding potentially valid + * configurations. */ - if (new_mtu < 68 || new_mtu > IP_MAX_MTU) + int max_mtu = IP_MAX_MTU - GENEVE_BASE_HLEN - sizeof(struct iphdr) + - dev->hard_header_len; + + if (new_mtu < 68) return -EINVAL; + + if (new_mtu > max_mtu) { + if (strict) + return -EINVAL; + + new_mtu = max_mtu; + } + dev->mtu = new_mtu; return 0; } +static int geneve_change_mtu(struct net_device *dev, int new_mtu) +{ + return __geneve_change_mtu(dev, new_mtu, true); +} + static int geneve_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb) { struct ip_tunnel_info *info = skb_tunnel_info(skb); @@ -1459,7 +1476,7 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name, /* openvswitch users expect packet sizes to be unrestricted, * so set the largest MTU we can. */ - err = geneve_change_mtu(dev, IP_MAX_MTU); + err = __geneve_change_mtu(dev, IP_MAX_MTU, false); if (err) goto err; |