aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/geneve.c31
-rw-r--r--drivers/net/vxlan.c47
-rw-r--r--include/net/ip_tunnels.h1
-rw-r--r--net/ipv4/ip_gre.c8
-rw-r--r--net/ipv4/ip_tunnel.c20
-rw-r--r--net/openvswitch/vport-vxlan.c2
6 files changed, 87 insertions, 22 deletions
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 0b14ac3b8d11..028e3873c310 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -1039,6 +1039,17 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
1039 return geneve_xmit_skb(skb, dev, info); 1039 return geneve_xmit_skb(skb, dev, info);
1040} 1040}
1041 1041
1042static int geneve_change_mtu(struct net_device *dev, int new_mtu)
1043{
1044 /* GENEVE overhead is not fixed, so we can't enforce a more
1045 * precise max MTU.
1046 */
1047 if (new_mtu < 68 || new_mtu > IP_MAX_MTU)
1048 return -EINVAL;
1049 dev->mtu = new_mtu;
1050 return 0;
1051}
1052
1042static int geneve_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb) 1053static int geneve_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
1043{ 1054{
1044 struct ip_tunnel_info *info = skb_tunnel_info(skb); 1055 struct ip_tunnel_info *info = skb_tunnel_info(skb);
@@ -1083,7 +1094,7 @@ static const struct net_device_ops geneve_netdev_ops = {
1083 .ndo_stop = geneve_stop, 1094 .ndo_stop = geneve_stop,
1084 .ndo_start_xmit = geneve_xmit, 1095 .ndo_start_xmit = geneve_xmit,
1085 .ndo_get_stats64 = ip_tunnel_get_stats64, 1096 .ndo_get_stats64 = ip_tunnel_get_stats64,
1086 .ndo_change_mtu = eth_change_mtu, 1097 .ndo_change_mtu = geneve_change_mtu,
1087 .ndo_validate_addr = eth_validate_addr, 1098 .ndo_validate_addr = eth_validate_addr,
1088 .ndo_set_mac_address = eth_mac_addr, 1099 .ndo_set_mac_address = eth_mac_addr,
1089 .ndo_fill_metadata_dst = geneve_fill_metadata_dst, 1100 .ndo_fill_metadata_dst = geneve_fill_metadata_dst,
@@ -1442,11 +1453,21 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
1442 1453
1443 err = geneve_configure(net, dev, &geneve_remote_unspec, 1454 err = geneve_configure(net, dev, &geneve_remote_unspec,
1444 0, 0, 0, htons(dst_port), true, 0); 1455 0, 0, 0, htons(dst_port), true, 0);
1445 if (err) { 1456 if (err)
1446 free_netdev(dev); 1457 goto err;
1447 return ERR_PTR(err); 1458
1448 } 1459 /* openvswitch users expect packet sizes to be unrestricted,
1460 * so set the largest MTU we can.
1461 */
1462 err = geneve_change_mtu(dev, IP_MAX_MTU);
1463 if (err)
1464 goto err;
1465
1449 return dev; 1466 return dev;
1467
1468 err:
1469 free_netdev(dev);
1470 return ERR_PTR(err);
1450} 1471}
1451EXPORT_SYMBOL_GPL(geneve_dev_create_fb); 1472EXPORT_SYMBOL_GPL(geneve_dev_create_fb);
1452 1473
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 65439188c582..a31cd954b308 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2367,29 +2367,43 @@ static void vxlan_set_multicast_list(struct net_device *dev)
2367{ 2367{
2368} 2368}
2369 2369
2370static int vxlan_change_mtu(struct net_device *dev, int new_mtu) 2370static int __vxlan_change_mtu(struct net_device *dev,
2371 struct net_device *lowerdev,
2372 struct vxlan_rdst *dst, int new_mtu, bool strict)
2371{ 2373{
2372 struct vxlan_dev *vxlan = netdev_priv(dev); 2374 int max_mtu = IP_MAX_MTU;
2373 struct vxlan_rdst *dst = &vxlan->default_dst;
2374 struct net_device *lowerdev;
2375 int max_mtu;
2376 2375
2377 lowerdev = __dev_get_by_index(vxlan->net, dst->remote_ifindex); 2376 if (lowerdev)
2378 if (lowerdev == NULL) 2377 max_mtu = lowerdev->mtu;
2379 return eth_change_mtu(dev, new_mtu);
2380 2378
2381 if (dst->remote_ip.sa.sa_family == AF_INET6) 2379 if (dst->remote_ip.sa.sa_family == AF_INET6)
2382 max_mtu = lowerdev->mtu - VXLAN6_HEADROOM; 2380 max_mtu -= VXLAN6_HEADROOM;
2383 else 2381 else
2384 max_mtu = lowerdev->mtu - VXLAN_HEADROOM; 2382 max_mtu -= VXLAN_HEADROOM;
2385 2383
2386 if (new_mtu < 68 || new_mtu > max_mtu) 2384 if (new_mtu < 68)
2387 return -EINVAL; 2385 return -EINVAL;
2388 2386
2387 if (new_mtu > max_mtu) {
2388 if (strict)
2389 return -EINVAL;
2390
2391 new_mtu = max_mtu;
2392 }
2393
2389 dev->mtu = new_mtu; 2394 dev->mtu = new_mtu;
2390 return 0; 2395 return 0;
2391} 2396}
2392 2397
2398static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
2399{
2400 struct vxlan_dev *vxlan = netdev_priv(dev);
2401 struct vxlan_rdst *dst = &vxlan->default_dst;
2402 struct net_device *lowerdev = __dev_get_by_index(vxlan->net,
2403 dst->remote_ifindex);
2404 return __vxlan_change_mtu(dev, lowerdev, dst, new_mtu, true);
2405}
2406
2393static int egress_ipv4_tun_info(struct net_device *dev, struct sk_buff *skb, 2407static int egress_ipv4_tun_info(struct net_device *dev, struct sk_buff *skb,
2394 struct ip_tunnel_info *info, 2408 struct ip_tunnel_info *info,
2395 __be16 sport, __be16 dport) 2409 __be16 sport, __be16 dport)
@@ -2765,6 +2779,7 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
2765 int err; 2779 int err;
2766 bool use_ipv6 = false; 2780 bool use_ipv6 = false;
2767 __be16 default_port = vxlan->cfg.dst_port; 2781 __be16 default_port = vxlan->cfg.dst_port;
2782 struct net_device *lowerdev = NULL;
2768 2783
2769 vxlan->net = src_net; 2784 vxlan->net = src_net;
2770 2785
@@ -2785,9 +2800,7 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
2785 } 2800 }
2786 2801
2787 if (conf->remote_ifindex) { 2802 if (conf->remote_ifindex) {
2788 struct net_device *lowerdev 2803 lowerdev = __dev_get_by_index(src_net, conf->remote_ifindex);
2789 = __dev_get_by_index(src_net, conf->remote_ifindex);
2790
2791 dst->remote_ifindex = conf->remote_ifindex; 2804 dst->remote_ifindex = conf->remote_ifindex;
2792 2805
2793 if (!lowerdev) { 2806 if (!lowerdev) {
@@ -2811,6 +2824,12 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
2811 needed_headroom = lowerdev->hard_header_len; 2824 needed_headroom = lowerdev->hard_header_len;
2812 } 2825 }
2813 2826
2827 if (conf->mtu) {
2828 err = __vxlan_change_mtu(dev, lowerdev, dst, conf->mtu, false);
2829 if (err)
2830 return err;
2831 }
2832
2814 if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA) 2833 if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA)
2815 needed_headroom += VXLAN6_HEADROOM; 2834 needed_headroom += VXLAN6_HEADROOM;
2816 else 2835 else
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 6db96ea0144f..dda9abf6b89c 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -230,6 +230,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
230int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd); 230int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd);
231int ip_tunnel_encap(struct sk_buff *skb, struct ip_tunnel *t, 231int ip_tunnel_encap(struct sk_buff *skb, struct ip_tunnel *t,
232 u8 *protocol, struct flowi4 *fl4); 232 u8 *protocol, struct flowi4 *fl4);
233int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict);
233int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu); 234int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu);
234 235
235struct rtnl_link_stats64 *ip_tunnel_get_stats64(struct net_device *dev, 236struct rtnl_link_stats64 *ip_tunnel_get_stats64(struct net_device *dev,
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 7c51c4e1661f..56fdf4e0dce4 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -1240,6 +1240,14 @@ struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
1240 err = ipgre_newlink(net, dev, tb, NULL); 1240 err = ipgre_newlink(net, dev, tb, NULL);
1241 if (err < 0) 1241 if (err < 0)
1242 goto out; 1242 goto out;
1243
1244 /* openvswitch users expect packet sizes to be unrestricted,
1245 * so set the largest MTU we can.
1246 */
1247 err = __ip_tunnel_change_mtu(dev, IP_MAX_MTU, false);
1248 if (err)
1249 goto out;
1250
1243 return dev; 1251 return dev;
1244out: 1252out:
1245 free_netdev(dev); 1253 free_netdev(dev);
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index c7bd72e9b544..89e8861e05fc 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -943,17 +943,31 @@ done:
943} 943}
944EXPORT_SYMBOL_GPL(ip_tunnel_ioctl); 944EXPORT_SYMBOL_GPL(ip_tunnel_ioctl);
945 945
946int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu) 946int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict)
947{ 947{
948 struct ip_tunnel *tunnel = netdev_priv(dev); 948 struct ip_tunnel *tunnel = netdev_priv(dev);
949 int t_hlen = tunnel->hlen + sizeof(struct iphdr); 949 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
950 int max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen;
950 951
951 if (new_mtu < 68 || 952 if (new_mtu < 68)
952 new_mtu > 0xFFF8 - dev->hard_header_len - t_hlen)
953 return -EINVAL; 953 return -EINVAL;
954
955 if (new_mtu > max_mtu) {
956 if (strict)
957 return -EINVAL;
958
959 new_mtu = max_mtu;
960 }
961
954 dev->mtu = new_mtu; 962 dev->mtu = new_mtu;
955 return 0; 963 return 0;
956} 964}
965EXPORT_SYMBOL_GPL(__ip_tunnel_change_mtu);
966
967int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu)
968{
969 return __ip_tunnel_change_mtu(dev, new_mtu, true);
970}
957EXPORT_SYMBOL_GPL(ip_tunnel_change_mtu); 971EXPORT_SYMBOL_GPL(ip_tunnel_change_mtu);
958 972
959static void ip_tunnel_dev_free(struct net_device *dev) 973static void ip_tunnel_dev_free(struct net_device *dev)
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
index 1605691d9414..de9cb19efb6a 100644
--- a/net/openvswitch/vport-vxlan.c
+++ b/net/openvswitch/vport-vxlan.c
@@ -91,6 +91,8 @@ static struct vport *vxlan_tnl_create(const struct vport_parms *parms)
91 struct vxlan_config conf = { 91 struct vxlan_config conf = {
92 .no_share = true, 92 .no_share = true,
93 .flags = VXLAN_F_COLLECT_METADATA, 93 .flags = VXLAN_F_COLLECT_METADATA,
94 /* Don't restrict the packets that can be sent by MTU */
95 .mtu = IP_MAX_MTU,
94 }; 96 };
95 97
96 if (!options) { 98 if (!options) {