diff options
author | Daniel Borkmann <dborkman@redhat.com> | 2013-12-17 18:21:08 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-22 18:01:08 -0500 |
commit | 345010b5c488d754ecff98c4435a2a82949c9cf4 (patch) | |
tree | 74bc9c0f4cf20c54828271b2e2789820cf99dd4f | |
parent | 289dccbe141e01efc5968fe39a0993c9f611375e (diff) |
net: vxlan: use custom ndo_change_mtu handler
When adding a new vxlan device to an "underlying carrier" (here:
dst->remote_ifindex), the MTU size assigned to the vxlan device
is the MTU at setup time of the carrier - needed headroom, when
adding a vxlan device w/o explicit carrier, then it defaults
to 1500.
In case of an explicit carrier that supports jumbo frames, we
currently cannot change vxlan MTU via ip(8) to > 1500 in
post-setup time, as vxlan driver uses eth_change_mtu() as default
method for manually setting MTU.
Hence, use a custom implementation that only falls back to
eth_change_mtu() in case we didn't use a dev parameter on device
setup time, and otherwise allow a max MTU setting of the carrier
incl. adjustment for headroom.
Reported-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Acked-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/vxlan.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index ea203c1aaa24..aef44aa44fe3 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -2014,6 +2014,29 @@ static void vxlan_set_multicast_list(struct net_device *dev) | |||
2014 | { | 2014 | { |
2015 | } | 2015 | } |
2016 | 2016 | ||
2017 | static int vxlan_change_mtu(struct net_device *dev, int new_mtu) | ||
2018 | { | ||
2019 | struct vxlan_dev *vxlan = netdev_priv(dev); | ||
2020 | struct vxlan_rdst *dst = &vxlan->default_dst; | ||
2021 | struct net_device *lowerdev; | ||
2022 | int max_mtu; | ||
2023 | |||
2024 | lowerdev = __dev_get_by_index(dev_net(dev), dst->remote_ifindex); | ||
2025 | if (lowerdev == NULL) | ||
2026 | return eth_change_mtu(dev, new_mtu); | ||
2027 | |||
2028 | if (dst->remote_ip.sa.sa_family == AF_INET6) | ||
2029 | max_mtu = lowerdev->mtu - VXLAN6_HEADROOM; | ||
2030 | else | ||
2031 | max_mtu = lowerdev->mtu - VXLAN_HEADROOM; | ||
2032 | |||
2033 | if (new_mtu < 68 || new_mtu > max_mtu) | ||
2034 | return -EINVAL; | ||
2035 | |||
2036 | dev->mtu = new_mtu; | ||
2037 | return 0; | ||
2038 | } | ||
2039 | |||
2017 | static const struct net_device_ops vxlan_netdev_ops = { | 2040 | static const struct net_device_ops vxlan_netdev_ops = { |
2018 | .ndo_init = vxlan_init, | 2041 | .ndo_init = vxlan_init, |
2019 | .ndo_uninit = vxlan_uninit, | 2042 | .ndo_uninit = vxlan_uninit, |
@@ -2022,7 +2045,7 @@ static const struct net_device_ops vxlan_netdev_ops = { | |||
2022 | .ndo_start_xmit = vxlan_xmit, | 2045 | .ndo_start_xmit = vxlan_xmit, |
2023 | .ndo_get_stats64 = ip_tunnel_get_stats64, | 2046 | .ndo_get_stats64 = ip_tunnel_get_stats64, |
2024 | .ndo_set_rx_mode = vxlan_set_multicast_list, | 2047 | .ndo_set_rx_mode = vxlan_set_multicast_list, |
2025 | .ndo_change_mtu = eth_change_mtu, | 2048 | .ndo_change_mtu = vxlan_change_mtu, |
2026 | .ndo_validate_addr = eth_validate_addr, | 2049 | .ndo_validate_addr = eth_validate_addr, |
2027 | .ndo_set_mac_address = eth_mac_addr, | 2050 | .ndo_set_mac_address = eth_mac_addr, |
2028 | .ndo_fdb_add = vxlan_fdb_add, | 2051 | .ndo_fdb_add = vxlan_fdb_add, |