diff options
Diffstat (limited to 'drivers/net/vxlan.c')
-rw-r--r-- | drivers/net/vxlan.c | 64 |
1 files changed, 45 insertions, 19 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 65439188c582..1c32bd104797 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -931,8 +931,10 @@ static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, | |||
931 | cb->nlh->nlmsg_seq, | 931 | cb->nlh->nlmsg_seq, |
932 | RTM_NEWNEIGH, | 932 | RTM_NEWNEIGH, |
933 | NLM_F_MULTI, rd); | 933 | NLM_F_MULTI, rd); |
934 | if (err < 0) | 934 | if (err < 0) { |
935 | cb->args[1] = err; | ||
935 | goto out; | 936 | goto out; |
937 | } | ||
936 | skip: | 938 | skip: |
937 | ++idx; | 939 | ++idx; |
938 | } | 940 | } |
@@ -1306,8 +1308,10 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb) | |||
1306 | gbp = (struct vxlanhdr_gbp *)vxh; | 1308 | gbp = (struct vxlanhdr_gbp *)vxh; |
1307 | md->gbp = ntohs(gbp->policy_id); | 1309 | md->gbp = ntohs(gbp->policy_id); |
1308 | 1310 | ||
1309 | if (tun_dst) | 1311 | if (tun_dst) { |
1310 | tun_dst->u.tun_info.key.tun_flags |= TUNNEL_VXLAN_OPT; | 1312 | tun_dst->u.tun_info.key.tun_flags |= TUNNEL_VXLAN_OPT; |
1313 | tun_dst->u.tun_info.options_len = sizeof(*md); | ||
1314 | } | ||
1311 | 1315 | ||
1312 | if (gbp->dont_learn) | 1316 | if (gbp->dont_learn) |
1313 | md->gbp |= VXLAN_GBP_DONT_LEARN; | 1317 | md->gbp |= VXLAN_GBP_DONT_LEARN; |
@@ -2171,9 +2175,11 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2171 | #endif | 2175 | #endif |
2172 | } | 2176 | } |
2173 | 2177 | ||
2174 | if (vxlan->flags & VXLAN_F_COLLECT_METADATA && | 2178 | if (vxlan->flags & VXLAN_F_COLLECT_METADATA) { |
2175 | info && info->mode & IP_TUNNEL_INFO_TX) { | 2179 | if (info && info->mode & IP_TUNNEL_INFO_TX) |
2176 | vxlan_xmit_one(skb, dev, NULL, false); | 2180 | vxlan_xmit_one(skb, dev, NULL, false); |
2181 | else | ||
2182 | kfree_skb(skb); | ||
2177 | return NETDEV_TX_OK; | 2183 | return NETDEV_TX_OK; |
2178 | } | 2184 | } |
2179 | 2185 | ||
@@ -2367,29 +2373,43 @@ static void vxlan_set_multicast_list(struct net_device *dev) | |||
2367 | { | 2373 | { |
2368 | } | 2374 | } |
2369 | 2375 | ||
2370 | static int vxlan_change_mtu(struct net_device *dev, int new_mtu) | 2376 | static int __vxlan_change_mtu(struct net_device *dev, |
2377 | struct net_device *lowerdev, | ||
2378 | struct vxlan_rdst *dst, int new_mtu, bool strict) | ||
2371 | { | 2379 | { |
2372 | struct vxlan_dev *vxlan = netdev_priv(dev); | 2380 | int max_mtu = IP_MAX_MTU; |
2373 | struct vxlan_rdst *dst = &vxlan->default_dst; | ||
2374 | struct net_device *lowerdev; | ||
2375 | int max_mtu; | ||
2376 | 2381 | ||
2377 | lowerdev = __dev_get_by_index(vxlan->net, dst->remote_ifindex); | 2382 | if (lowerdev) |
2378 | if (lowerdev == NULL) | 2383 | max_mtu = lowerdev->mtu; |
2379 | return eth_change_mtu(dev, new_mtu); | ||
2380 | 2384 | ||
2381 | if (dst->remote_ip.sa.sa_family == AF_INET6) | 2385 | if (dst->remote_ip.sa.sa_family == AF_INET6) |
2382 | max_mtu = lowerdev->mtu - VXLAN6_HEADROOM; | 2386 | max_mtu -= VXLAN6_HEADROOM; |
2383 | else | 2387 | else |
2384 | max_mtu = lowerdev->mtu - VXLAN_HEADROOM; | 2388 | max_mtu -= VXLAN_HEADROOM; |
2385 | 2389 | ||
2386 | if (new_mtu < 68 || new_mtu > max_mtu) | 2390 | if (new_mtu < 68) |
2387 | return -EINVAL; | 2391 | return -EINVAL; |
2388 | 2392 | ||
2393 | if (new_mtu > max_mtu) { | ||
2394 | if (strict) | ||
2395 | return -EINVAL; | ||
2396 | |||
2397 | new_mtu = max_mtu; | ||
2398 | } | ||
2399 | |||
2389 | dev->mtu = new_mtu; | 2400 | dev->mtu = new_mtu; |
2390 | return 0; | 2401 | return 0; |
2391 | } | 2402 | } |
2392 | 2403 | ||
2404 | static int vxlan_change_mtu(struct net_device *dev, int new_mtu) | ||
2405 | { | ||
2406 | struct vxlan_dev *vxlan = netdev_priv(dev); | ||
2407 | struct vxlan_rdst *dst = &vxlan->default_dst; | ||
2408 | struct net_device *lowerdev = __dev_get_by_index(vxlan->net, | ||
2409 | dst->remote_ifindex); | ||
2410 | return __vxlan_change_mtu(dev, lowerdev, dst, new_mtu, true); | ||
2411 | } | ||
2412 | |||
2393 | static int egress_ipv4_tun_info(struct net_device *dev, struct sk_buff *skb, | 2413 | static int egress_ipv4_tun_info(struct net_device *dev, struct sk_buff *skb, |
2394 | struct ip_tunnel_info *info, | 2414 | struct ip_tunnel_info *info, |
2395 | __be16 sport, __be16 dport) | 2415 | __be16 sport, __be16 dport) |
@@ -2523,6 +2543,7 @@ static void vxlan_setup(struct net_device *dev) | |||
2523 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; | 2543 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; |
2524 | dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX; | 2544 | dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX; |
2525 | netif_keep_dst(dev); | 2545 | netif_keep_dst(dev); |
2546 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; | ||
2526 | dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE; | 2547 | dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE; |
2527 | 2548 | ||
2528 | INIT_LIST_HEAD(&vxlan->next); | 2549 | INIT_LIST_HEAD(&vxlan->next); |
@@ -2765,6 +2786,7 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev, | |||
2765 | int err; | 2786 | int err; |
2766 | bool use_ipv6 = false; | 2787 | bool use_ipv6 = false; |
2767 | __be16 default_port = vxlan->cfg.dst_port; | 2788 | __be16 default_port = vxlan->cfg.dst_port; |
2789 | struct net_device *lowerdev = NULL; | ||
2768 | 2790 | ||
2769 | vxlan->net = src_net; | 2791 | vxlan->net = src_net; |
2770 | 2792 | ||
@@ -2785,9 +2807,7 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev, | |||
2785 | } | 2807 | } |
2786 | 2808 | ||
2787 | if (conf->remote_ifindex) { | 2809 | if (conf->remote_ifindex) { |
2788 | struct net_device *lowerdev | 2810 | 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; | 2811 | dst->remote_ifindex = conf->remote_ifindex; |
2792 | 2812 | ||
2793 | if (!lowerdev) { | 2813 | if (!lowerdev) { |
@@ -2811,6 +2831,12 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev, | |||
2811 | needed_headroom = lowerdev->hard_header_len; | 2831 | needed_headroom = lowerdev->hard_header_len; |
2812 | } | 2832 | } |
2813 | 2833 | ||
2834 | if (conf->mtu) { | ||
2835 | err = __vxlan_change_mtu(dev, lowerdev, dst, conf->mtu, false); | ||
2836 | if (err) | ||
2837 | return err; | ||
2838 | } | ||
2839 | |||
2814 | if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA) | 2840 | if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA) |
2815 | needed_headroom += VXLAN6_HEADROOM; | 2841 | needed_headroom += VXLAN6_HEADROOM; |
2816 | else | 2842 | else |