@@ -2729,40 +2729,51 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],
2729
2729
{
2730
2730
if (tb [IFLA_ADDRESS ]) {
2731
2731
if (nla_len (tb [IFLA_ADDRESS ]) != ETH_ALEN ) {
2732
- pr_debug ("invalid link address (not ethernet)\n" );
2732
+ NL_SET_ERR_MSG_ATTR (extack , tb [IFLA_ADDRESS ],
2733
+ "Provided link layer address is not Ethernet" );
2733
2734
return - EINVAL ;
2734
2735
}
2735
2736
2736
2737
if (!is_valid_ether_addr (nla_data (tb [IFLA_ADDRESS ]))) {
2737
- pr_debug ("invalid all zero ethernet address\n" );
2738
+ NL_SET_ERR_MSG_ATTR (extack , tb [IFLA_ADDRESS ],
2739
+ "Provided Ethernet address is not unicast" );
2738
2740
return - EADDRNOTAVAIL ;
2739
2741
}
2740
2742
}
2741
2743
2742
2744
if (tb [IFLA_MTU ]) {
2743
2745
u32 mtu = nla_get_u32 (tb [IFLA_MTU ]);
2744
2746
2745
- if (mtu < ETH_MIN_MTU || mtu > ETH_MAX_MTU )
2747
+ if (mtu < ETH_MIN_MTU || mtu > ETH_MAX_MTU ) {
2748
+ NL_SET_ERR_MSG_ATTR (extack , tb [IFLA_MTU ],
2749
+ "MTU must be between 68 and 65535" );
2746
2750
return - EINVAL ;
2751
+ }
2747
2752
}
2748
2753
2749
- if (!data )
2754
+ if (!data ) {
2755
+ NL_SET_ERR_MSG (extack ,
2756
+ "Required attributes not provided to perform the operation" );
2750
2757
return - EINVAL ;
2758
+ }
2751
2759
2752
2760
if (data [IFLA_VXLAN_ID ]) {
2753
2761
u32 id = nla_get_u32 (data [IFLA_VXLAN_ID ]);
2754
2762
2755
- if (id >= VXLAN_N_VID )
2763
+ if (id >= VXLAN_N_VID ) {
2764
+ NL_SET_ERR_MSG_ATTR (extack , tb [IFLA_VXLAN_ID ],
2765
+ "VXLAN ID must be lower than 16777216" );
2756
2766
return - ERANGE ;
2767
+ }
2757
2768
}
2758
2769
2759
2770
if (data [IFLA_VXLAN_PORT_RANGE ]) {
2760
2771
const struct ifla_vxlan_port_range * p
2761
2772
= nla_data (data [IFLA_VXLAN_PORT_RANGE ]);
2762
2773
2763
2774
if (ntohs (p -> high ) < ntohs (p -> low )) {
2764
- pr_debug ( "port range %u .. %u not valid\n" ,
2765
- ntohs ( p -> low ), ntohs ( p -> high ) );
2775
+ NL_SET_ERR_MSG_ATTR ( extack , tb [ IFLA_VXLAN_PORT_RANGE ] ,
2776
+ "Invalid source port range" );
2766
2777
return - EINVAL ;
2767
2778
}
2768
2779
}
@@ -2919,7 +2930,8 @@ static int vxlan_sock_add(struct vxlan_dev *vxlan)
2919
2930
2920
2931
static int vxlan_config_validate (struct net * src_net , struct vxlan_config * conf ,
2921
2932
struct net_device * * lower ,
2922
- struct vxlan_dev * old )
2933
+ struct vxlan_dev * old ,
2934
+ struct netlink_ext_ack * extack )
2923
2935
{
2924
2936
struct vxlan_net * vn = net_generic (src_net , vxlan_net_id );
2925
2937
struct vxlan_dev * tmp ;
@@ -2933,6 +2945,8 @@ static int vxlan_config_validate(struct net *src_net, struct vxlan_config *conf,
2933
2945
*/
2934
2946
if ((conf -> flags & ~VXLAN_F_ALLOWED_GPE ) ||
2935
2947
!(conf -> flags & VXLAN_F_COLLECT_METADATA )) {
2948
+ NL_SET_ERR_MSG (extack ,
2949
+ "VXLAN GPE does not support this combination of attributes" );
2936
2950
return - EINVAL ;
2937
2951
}
2938
2952
}
@@ -2947,15 +2961,23 @@ static int vxlan_config_validate(struct net *src_net, struct vxlan_config *conf,
2947
2961
conf -> saddr .sa .sa_family = conf -> remote_ip .sa .sa_family ;
2948
2962
}
2949
2963
2950
- if (conf -> saddr .sa .sa_family != conf -> remote_ip .sa .sa_family )
2964
+ if (conf -> saddr .sa .sa_family != conf -> remote_ip .sa .sa_family ) {
2965
+ NL_SET_ERR_MSG (extack ,
2966
+ "Local and remote address must be from the same family" );
2951
2967
return - EINVAL ;
2968
+ }
2952
2969
2953
- if (vxlan_addr_multicast (& conf -> saddr ))
2970
+ if (vxlan_addr_multicast (& conf -> saddr )) {
2971
+ NL_SET_ERR_MSG (extack , "Local address cannot be multicast" );
2954
2972
return - EINVAL ;
2973
+ }
2955
2974
2956
2975
if (conf -> saddr .sa .sa_family == AF_INET6 ) {
2957
- if (!IS_ENABLED (CONFIG_IPV6 ))
2976
+ if (!IS_ENABLED (CONFIG_IPV6 )) {
2977
+ NL_SET_ERR_MSG (extack ,
2978
+ "IPv6 support not enabled in the kernel" );
2958
2979
return - EPFNOSUPPORT ;
2980
+ }
2959
2981
use_ipv6 = true;
2960
2982
conf -> flags |= VXLAN_F_IPV6 ;
2961
2983
@@ -2967,46 +2989,68 @@ static int vxlan_config_validate(struct net *src_net, struct vxlan_config *conf,
2967
2989
2968
2990
if (local_type & IPV6_ADDR_LINKLOCAL ) {
2969
2991
if (!(remote_type & IPV6_ADDR_LINKLOCAL ) &&
2970
- (remote_type != IPV6_ADDR_ANY ))
2992
+ (remote_type != IPV6_ADDR_ANY )) {
2993
+ NL_SET_ERR_MSG (extack ,
2994
+ "Invalid combination of local and remote address scopes" );
2971
2995
return - EINVAL ;
2996
+ }
2972
2997
2973
2998
conf -> flags |= VXLAN_F_IPV6_LINKLOCAL ;
2974
2999
} else {
2975
3000
if (remote_type ==
2976
- (IPV6_ADDR_UNICAST | IPV6_ADDR_LINKLOCAL ))
3001
+ (IPV6_ADDR_UNICAST | IPV6_ADDR_LINKLOCAL )) {
3002
+ NL_SET_ERR_MSG (extack ,
3003
+ "Invalid combination of local and remote address scopes" );
2977
3004
return - EINVAL ;
3005
+ }
2978
3006
2979
3007
conf -> flags &= ~VXLAN_F_IPV6_LINKLOCAL ;
2980
3008
}
2981
3009
}
2982
3010
}
2983
3011
2984
- if (conf -> label && !use_ipv6 )
3012
+ if (conf -> label && !use_ipv6 ) {
3013
+ NL_SET_ERR_MSG (extack ,
3014
+ "Label attribute only applies to IPv6 VXLAN devices" );
2985
3015
return - EINVAL ;
3016
+ }
2986
3017
2987
3018
if (conf -> remote_ifindex ) {
2988
3019
struct net_device * lowerdev ;
2989
3020
2990
3021
lowerdev = __dev_get_by_index (src_net , conf -> remote_ifindex );
2991
- if (!lowerdev )
3022
+ if (!lowerdev ) {
3023
+ NL_SET_ERR_MSG (extack ,
3024
+ "Invalid local interface, device not found" );
2992
3025
return - ENODEV ;
3026
+ }
2993
3027
2994
3028
#if IS_ENABLED (CONFIG_IPV6 )
2995
3029
if (use_ipv6 ) {
2996
3030
struct inet6_dev * idev = __in6_dev_get (lowerdev );
2997
- if (idev && idev -> cnf .disable_ipv6 )
3031
+ if (idev && idev -> cnf .disable_ipv6 ) {
3032
+ NL_SET_ERR_MSG (extack ,
3033
+ "IPv6 support disabled by administrator" );
2998
3034
return - EPERM ;
3035
+ }
2999
3036
}
3000
3037
#endif
3001
3038
3002
3039
* lower = lowerdev ;
3003
3040
} else {
3004
- if (vxlan_addr_multicast (& conf -> remote_ip ))
3041
+ if (vxlan_addr_multicast (& conf -> remote_ip )) {
3042
+ NL_SET_ERR_MSG (extack ,
3043
+ "Local interface required for multicast remote destination" );
3044
+
3005
3045
return - EINVAL ;
3046
+ }
3006
3047
3007
3048
#if IS_ENABLED (CONFIG_IPV6 )
3008
- if (conf -> flags & VXLAN_F_IPV6_LINKLOCAL )
3049
+ if (conf -> flags & VXLAN_F_IPV6_LINKLOCAL ) {
3050
+ NL_SET_ERR_MSG (extack ,
3051
+ "Local interface required for link-local local/remote addresses" );
3009
3052
return - EINVAL ;
3053
+ }
3010
3054
#endif
3011
3055
3012
3056
* lower = NULL ;
@@ -3038,6 +3082,8 @@ static int vxlan_config_validate(struct net *src_net, struct vxlan_config *conf,
3038
3082
tmp -> cfg .remote_ifindex != conf -> remote_ifindex )
3039
3083
continue ;
3040
3084
3085
+ NL_SET_ERR_MSG (extack ,
3086
+ "A VXLAN device with the specified VNI already exists" );
3041
3087
return - EEXIST ;
3042
3088
}
3043
3089
@@ -3097,14 +3143,14 @@ static void vxlan_config_apply(struct net_device *dev,
3097
3143
}
3098
3144
3099
3145
static int vxlan_dev_configure (struct net * src_net , struct net_device * dev ,
3100
- struct vxlan_config * conf ,
3101
- bool changelink )
3146
+ struct vxlan_config * conf , bool changelink ,
3147
+ struct netlink_ext_ack * extack )
3102
3148
{
3103
3149
struct vxlan_dev * vxlan = netdev_priv (dev );
3104
3150
struct net_device * lowerdev ;
3105
3151
int ret ;
3106
3152
3107
- ret = vxlan_config_validate (src_net , conf , & lowerdev , vxlan );
3153
+ ret = vxlan_config_validate (src_net , conf , & lowerdev , vxlan , extack );
3108
3154
if (ret )
3109
3155
return ret ;
3110
3156
@@ -3114,13 +3160,14 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
3114
3160
}
3115
3161
3116
3162
static int __vxlan_dev_create (struct net * net , struct net_device * dev ,
3117
- struct vxlan_config * conf )
3163
+ struct vxlan_config * conf ,
3164
+ struct netlink_ext_ack * extack )
3118
3165
{
3119
3166
struct vxlan_net * vn = net_generic (net , vxlan_net_id );
3120
3167
struct vxlan_dev * vxlan = netdev_priv (dev );
3121
3168
int err ;
3122
3169
3123
- err = vxlan_dev_configure (net , dev , conf , false);
3170
+ err = vxlan_dev_configure (net , dev , conf , false, extack );
3124
3171
if (err )
3125
3172
return err ;
3126
3173
@@ -3366,7 +3413,7 @@ static int vxlan_newlink(struct net *src_net, struct net_device *dev,
3366
3413
if (err )
3367
3414
return err ;
3368
3415
3369
- return __vxlan_dev_create (src_net , dev , & conf );
3416
+ return __vxlan_dev_create (src_net , dev , & conf , extack );
3370
3417
}
3371
3418
3372
3419
static int vxlan_changelink (struct net_device * dev , struct nlattr * tb [],
@@ -3386,7 +3433,7 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[],
3386
3433
3387
3434
memcpy (& old_dst , dst , sizeof (struct vxlan_rdst ));
3388
3435
3389
- err = vxlan_dev_configure (vxlan -> net , dev , & conf , true);
3436
+ err = vxlan_dev_configure (vxlan -> net , dev , & conf , true, extack );
3390
3437
if (err )
3391
3438
return err ;
3392
3439
@@ -3592,7 +3639,7 @@ struct net_device *vxlan_dev_create(struct net *net, const char *name,
3592
3639
if (IS_ERR (dev ))
3593
3640
return dev ;
3594
3641
3595
- err = __vxlan_dev_create (net , dev , conf );
3642
+ err = __vxlan_dev_create (net , dev , conf , NULL );
3596
3643
if (err < 0 ) {
3597
3644
free_netdev (dev );
3598
3645
return ERR_PTR (err );
0 commit comments