@@ -2623,16 +2623,19 @@ static void vxlan_setup(struct net_device *dev)
2623
2623
netif_keep_dst (dev );
2624
2624
dev -> priv_flags |= IFF_NO_QUEUE ;
2625
2625
2626
+ /* MTU range: 68 - 65535 */
2627
+ dev -> min_mtu = ETH_MIN_MTU ;
2628
+ dev -> max_mtu = ETH_MAX_MTU ;
2629
+
2626
2630
INIT_LIST_HEAD (& vxlan -> next );
2627
2631
spin_lock_init (& vxlan -> hash_lock );
2628
2632
2629
2633
init_timer_deferrable (& vxlan -> age_timer );
2630
2634
vxlan -> age_timer .function = vxlan_cleanup ;
2631
2635
vxlan -> age_timer .data = (unsigned long ) vxlan ;
2632
2636
2633
- vxlan -> cfg .dst_port = htons (vxlan_port );
2634
-
2635
2637
vxlan -> dev = dev ;
2638
+ vxlan -> net = dev_net (dev );
2636
2639
2637
2640
gro_cells_init (& vxlan -> gro_cells , dev );
2638
2641
@@ -2701,11 +2704,19 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
2701
2704
}
2702
2705
}
2703
2706
2707
+ if (tb [IFLA_MTU ]) {
2708
+ u32 mtu = nla_get_u32 (data [IFLA_MTU ]);
2709
+
2710
+ if (mtu < ETH_MIN_MTU || mtu > ETH_MAX_MTU )
2711
+ return - EINVAL ;
2712
+ }
2713
+
2704
2714
if (!data )
2705
2715
return - EINVAL ;
2706
2716
2707
2717
if (data [IFLA_VXLAN_ID ]) {
2708
- __u32 id = nla_get_u32 (data [IFLA_VXLAN_ID ]);
2718
+ u32 id = nla_get_u32 (data [IFLA_VXLAN_ID ]);
2719
+
2709
2720
if (id >= VXLAN_N_VID )
2710
2721
return - ERANGE ;
2711
2722
}
@@ -2866,148 +2877,151 @@ static int vxlan_sock_add(struct vxlan_dev *vxlan)
2866
2877
return ret ;
2867
2878
}
2868
2879
2869
- static int vxlan_dev_configure (struct net * src_net , struct net_device * dev ,
2870
- struct vxlan_config * conf ,
2871
- bool changelink )
2880
+ static int vxlan_config_validate (struct net * src_net , struct vxlan_config * conf ,
2881
+ struct net_device * * lower ,
2882
+ struct vxlan_dev * old )
2872
2883
{
2873
2884
struct vxlan_net * vn = net_generic (src_net , vxlan_net_id );
2874
- struct vxlan_dev * vxlan = netdev_priv (dev ), * tmp ;
2875
- struct vxlan_rdst * dst = & vxlan -> default_dst ;
2876
- unsigned short needed_headroom = ETH_HLEN ;
2885
+ struct vxlan_dev * tmp ;
2877
2886
bool use_ipv6 = false;
2878
- __be16 default_port = vxlan -> cfg .dst_port ;
2879
- struct net_device * lowerdev = NULL ;
2880
2887
2881
- if (!changelink ) {
2882
- if (conf -> flags & VXLAN_F_GPE ) {
2883
- /* For now, allow GPE only together with
2884
- * COLLECT_METADATA. This can be relaxed later; in such
2885
- * case, the other side of the PtP link will have to be
2886
- * provided.
2887
- */
2888
- if ((conf -> flags & ~VXLAN_F_ALLOWED_GPE ) ||
2889
- !(conf -> flags & VXLAN_F_COLLECT_METADATA )) {
2890
- pr_info ("unsupported combination of extensions\n" );
2891
- return - EINVAL ;
2892
- }
2893
- vxlan_raw_setup (dev );
2894
- } else {
2895
- vxlan_ether_setup (dev );
2888
+ if (conf -> flags & VXLAN_F_GPE ) {
2889
+ /* For now, allow GPE only together with
2890
+ * COLLECT_METADATA. This can be relaxed later; in such
2891
+ * case, the other side of the PtP link will have to be
2892
+ * provided.
2893
+ */
2894
+ if ((conf -> flags & ~VXLAN_F_ALLOWED_GPE ) ||
2895
+ !(conf -> flags & VXLAN_F_COLLECT_METADATA )) {
2896
+ return - EINVAL ;
2896
2897
}
2897
-
2898
- /* MTU range: 68 - 65535 */
2899
- dev -> min_mtu = ETH_MIN_MTU ;
2900
- dev -> max_mtu = ETH_MAX_MTU ;
2901
- vxlan -> net = src_net ;
2902
2898
}
2903
2899
2904
- dst -> remote_vni = conf -> vni ;
2905
-
2906
- memcpy (& dst -> remote_ip , & conf -> remote_ip , sizeof (conf -> remote_ip ));
2907
-
2908
- /* Unless IPv6 is explicitly requested, assume IPv4 */
2909
- if (!dst -> remote_ip .sa .sa_family )
2910
- dst -> remote_ip .sa .sa_family = AF_INET ;
2900
+ if (!conf -> remote_ip .sa .sa_family )
2901
+ conf -> remote_ip .sa .sa_family = AF_INET ;
2911
2902
2912
- if (dst -> remote_ip .sa .sa_family == AF_INET6 ||
2913
- vxlan -> cfg . saddr .sa .sa_family == AF_INET6 ) {
2903
+ if (conf -> remote_ip .sa .sa_family == AF_INET6 ||
2904
+ conf -> saddr .sa .sa_family == AF_INET6 ) {
2914
2905
if (!IS_ENABLED (CONFIG_IPV6 ))
2915
2906
return - EPFNOSUPPORT ;
2916
2907
use_ipv6 = true;
2917
- vxlan -> flags |= VXLAN_F_IPV6 ;
2908
+ conf -> flags |= VXLAN_F_IPV6 ;
2918
2909
}
2919
2910
2920
- if (conf -> label && !use_ipv6 ) {
2921
- pr_info ("label only supported in use with IPv6\n" );
2911
+ if (conf -> label && !use_ipv6 )
2922
2912
return - EINVAL ;
2923
- }
2924
2913
2925
- if (conf -> remote_ifindex &&
2926
- conf -> remote_ifindex != vxlan -> cfg .remote_ifindex ) {
2927
- lowerdev = __dev_get_by_index (src_net , conf -> remote_ifindex );
2928
- dst -> remote_ifindex = conf -> remote_ifindex ;
2914
+ if (conf -> remote_ifindex ) {
2915
+ struct net_device * lowerdev ;
2929
2916
2930
- if (!lowerdev ) {
2931
- pr_info ("ifindex %d does not exist\n" ,
2932
- dst -> remote_ifindex );
2917
+ lowerdev = __dev_get_by_index (src_net , conf -> remote_ifindex );
2918
+ if (!lowerdev )
2933
2919
return - ENODEV ;
2934
- }
2935
2920
2936
2921
#if IS_ENABLED (CONFIG_IPV6 )
2937
2922
if (use_ipv6 ) {
2938
2923
struct inet6_dev * idev = __in6_dev_get (lowerdev );
2939
- if (idev && idev -> cnf .disable_ipv6 ) {
2940
- pr_info ("IPv6 is disabled via sysctl\n" );
2924
+ if (idev && idev -> cnf .disable_ipv6 )
2941
2925
return - EPERM ;
2942
- }
2943
2926
}
2944
2927
#endif
2945
2928
2946
- if (!conf -> mtu )
2947
- dev -> mtu = lowerdev -> mtu -
2948
- (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM );
2929
+ * lower = lowerdev ;
2930
+ } else {
2931
+ if (vxlan_addr_multicast (& conf -> remote_ip ))
2932
+ return - EINVAL ;
2949
2933
2950
- needed_headroom = lowerdev -> hard_header_len ;
2951
- } else if (!conf -> remote_ifindex &&
2952
- vxlan_addr_multicast (& dst -> remote_ip )) {
2953
- pr_info ("multicast destination requires interface to be specified\n" );
2954
- return - EINVAL ;
2934
+ * lower = NULL ;
2955
2935
}
2956
2936
2957
- if (lowerdev ) {
2958
- dev -> gso_max_size = lowerdev -> gso_max_size ;
2959
- dev -> gso_max_segs = lowerdev -> gso_max_segs ;
2937
+ if (!conf -> dst_port ) {
2938
+ if (conf -> flags & VXLAN_F_GPE )
2939
+ conf -> dst_port = htons (4790 ); /* IANA VXLAN-GPE port */
2940
+ else
2941
+ conf -> dst_port = htons (vxlan_port );
2960
2942
}
2961
2943
2962
- if (conf -> mtu ) {
2963
- int max_mtu = ETH_MAX_MTU ;
2944
+ if (! conf -> age_interval )
2945
+ conf -> age_interval = FDB_AGE_DEFAULT ;
2964
2946
2965
- if (lowerdev )
2966
- max_mtu = lowerdev -> mtu ;
2947
+ list_for_each_entry (tmp , & vn -> vxlan_list , next ) {
2948
+ if (tmp == old )
2949
+ continue ;
2967
2950
2968
- max_mtu -= (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM );
2951
+ if (tmp -> cfg .vni == conf -> vni &&
2952
+ (tmp -> default_dst .remote_ip .sa .sa_family == AF_INET6 ||
2953
+ tmp -> cfg .saddr .sa .sa_family == AF_INET6 ) == use_ipv6 &&
2954
+ tmp -> cfg .dst_port == conf -> dst_port &&
2955
+ (tmp -> flags & VXLAN_F_RCV_FLAGS ) ==
2956
+ (conf -> flags & VXLAN_F_RCV_FLAGS ))
2957
+ return - EEXIST ;
2958
+ }
2969
2959
2970
- if ( conf -> mtu < dev -> min_mtu || conf -> mtu > dev -> max_mtu )
2971
- return - EINVAL ;
2960
+ return 0 ;
2961
+ }
2972
2962
2973
- dev -> mtu = conf -> mtu ;
2963
+ static void vxlan_config_apply (struct net_device * dev ,
2964
+ struct vxlan_config * conf ,
2965
+ struct net_device * lowerdev , bool changelink )
2966
+ {
2967
+ struct vxlan_dev * vxlan = netdev_priv (dev );
2968
+ struct vxlan_rdst * dst = & vxlan -> default_dst ;
2969
+ unsigned short needed_headroom = ETH_HLEN ;
2970
+ bool use_ipv6 = !!(conf -> flags & VXLAN_F_IPV6 );
2971
+ int max_mtu = ETH_MAX_MTU ;
2972
+
2973
+ if (!changelink ) {
2974
+ if (conf -> flags & VXLAN_F_GPE )
2975
+ vxlan_raw_setup (dev );
2976
+ else
2977
+ vxlan_ether_setup (dev );
2974
2978
2975
- if (conf -> mtu > max_mtu )
2976
- dev -> mtu = max_mtu ;
2979
+ if (conf -> mtu )
2980
+ dev -> mtu = conf -> mtu ;
2977
2981
}
2978
2982
2983
+ dst -> remote_vni = conf -> vni ;
2984
+
2985
+ memcpy (& dst -> remote_ip , & conf -> remote_ip , sizeof (conf -> remote_ip ));
2986
+
2987
+ if (lowerdev ) {
2988
+ dst -> remote_ifindex = conf -> remote_ifindex ;
2989
+
2990
+ dev -> gso_max_size = lowerdev -> gso_max_size ;
2991
+ dev -> gso_max_segs = lowerdev -> gso_max_segs ;
2992
+
2993
+ needed_headroom = lowerdev -> hard_header_len ;
2994
+
2995
+ max_mtu = lowerdev -> mtu - (use_ipv6 ? VXLAN6_HEADROOM :
2996
+ VXLAN_HEADROOM );
2997
+ }
2998
+
2999
+ if (dev -> mtu > max_mtu )
3000
+ dev -> mtu = max_mtu ;
3001
+
2979
3002
if (use_ipv6 || conf -> flags & VXLAN_F_COLLECT_METADATA )
2980
3003
needed_headroom += VXLAN6_HEADROOM ;
2981
3004
else
2982
3005
needed_headroom += VXLAN_HEADROOM ;
2983
3006
dev -> needed_headroom = needed_headroom ;
2984
3007
2985
3008
memcpy (& vxlan -> cfg , conf , sizeof (* conf ));
2986
- if (!vxlan -> cfg .dst_port ) {
2987
- if (conf -> flags & VXLAN_F_GPE )
2988
- vxlan -> cfg .dst_port = htons (4790 ); /* IANA VXLAN-GPE port */
2989
- else
2990
- vxlan -> cfg .dst_port = default_port ;
2991
- }
2992
3009
vxlan -> flags |= conf -> flags ;
3010
+ }
2993
3011
2994
- if (!vxlan -> cfg .age_interval )
2995
- vxlan -> cfg .age_interval = FDB_AGE_DEFAULT ;
3012
+ static int vxlan_dev_configure (struct net * src_net , struct net_device * dev ,
3013
+ struct vxlan_config * conf ,
3014
+ bool changelink )
3015
+ {
3016
+ struct vxlan_dev * vxlan = netdev_priv (dev );
3017
+ struct net_device * lowerdev ;
3018
+ int ret ;
2996
3019
2997
- if (changelink )
2998
- return 0 ;
3020
+ ret = vxlan_config_validate (src_net , conf , & lowerdev , vxlan );
3021
+ if (ret )
3022
+ return ret ;
2999
3023
3000
- list_for_each_entry (tmp , & vn -> vxlan_list , next ) {
3001
- if (tmp -> cfg .vni == conf -> vni &&
3002
- (tmp -> default_dst .remote_ip .sa .sa_family == AF_INET6 ||
3003
- tmp -> cfg .saddr .sa .sa_family == AF_INET6 ) == use_ipv6 &&
3004
- tmp -> cfg .dst_port == vxlan -> cfg .dst_port &&
3005
- (tmp -> flags & VXLAN_F_RCV_FLAGS ) ==
3006
- (vxlan -> flags & VXLAN_F_RCV_FLAGS )) {
3007
- pr_info ("duplicate VNI %u\n" , be32_to_cpu (conf -> vni ));
3008
- return - EEXIST ;
3009
- }
3010
- }
3024
+ vxlan_config_apply (dev , conf , lowerdev , changelink );
3011
3025
3012
3026
return 0 ;
3013
3027
}
0 commit comments