@@ -127,10 +127,6 @@ struct vxlan_dev {
127
127
__u8 ttl ;
128
128
u32 flags ; /* VXLAN_F_* in vxlan.h */
129
129
130
- struct work_struct sock_work ;
131
- struct work_struct igmp_join ;
132
- struct work_struct igmp_leave ;
133
-
134
130
unsigned long age_interval ;
135
131
struct timer_list age_timer ;
136
132
spinlock_t hash_lock ;
@@ -144,8 +140,6 @@ struct vxlan_dev {
144
140
static u32 vxlan_salt __read_mostly ;
145
141
static struct workqueue_struct * vxlan_wq ;
146
142
147
- static void vxlan_sock_work (struct work_struct * work );
148
-
149
143
#if IS_ENABLED (CONFIG_IPV6 )
150
144
static inline
151
145
bool vxlan_addr_equal (const union vxlan_addr * a , const union vxlan_addr * b )
@@ -1072,11 +1066,6 @@ static bool vxlan_group_used(struct vxlan_net *vn, struct vxlan_dev *dev)
1072
1066
return false;
1073
1067
}
1074
1068
1075
- static void vxlan_sock_hold (struct vxlan_sock * vs )
1076
- {
1077
- atomic_inc (& vs -> refcnt );
1078
- }
1079
-
1080
1069
void vxlan_sock_release (struct vxlan_sock * vs )
1081
1070
{
1082
1071
struct sock * sk = vs -> sock -> sk ;
@@ -1095,69 +1084,62 @@ void vxlan_sock_release(struct vxlan_sock *vs)
1095
1084
}
1096
1085
EXPORT_SYMBOL_GPL (vxlan_sock_release );
1097
1086
1098
- /* Callback to update multicast group membership when first VNI on
1087
+ /* Update multicast group membership when first VNI on
1099
1088
* multicast asddress is brought up
1100
1089
*/
1101
- static void vxlan_igmp_join (struct work_struct * work )
1090
+ static int vxlan_igmp_join (struct vxlan_dev * vxlan )
1102
1091
{
1103
- struct vxlan_dev * vxlan = container_of (work , struct vxlan_dev , igmp_join );
1104
1092
struct vxlan_sock * vs = vxlan -> vn_sock ;
1105
1093
struct sock * sk = vs -> sock -> sk ;
1106
1094
union vxlan_addr * ip = & vxlan -> default_dst .remote_ip ;
1107
1095
int ifindex = vxlan -> default_dst .remote_ifindex ;
1096
+ int ret ;
1108
1097
1109
- rtnl_lock ();
1110
1098
lock_sock (sk );
1111
1099
if (ip -> sa .sa_family == AF_INET ) {
1112
1100
struct ip_mreqn mreq = {
1113
1101
.imr_multiaddr .s_addr = ip -> sin .sin_addr .s_addr ,
1114
1102
.imr_ifindex = ifindex ,
1115
1103
};
1116
1104
1117
- ip_mc_join_group (sk , & mreq );
1105
+ ret = ip_mc_join_group (sk , & mreq );
1118
1106
#if IS_ENABLED (CONFIG_IPV6 )
1119
1107
} else {
1120
- ipv6_stub -> ipv6_sock_mc_join (sk , ifindex ,
1121
- & ip -> sin6 .sin6_addr );
1108
+ ret = ipv6_stub -> ipv6_sock_mc_join (sk , ifindex ,
1109
+ & ip -> sin6 .sin6_addr );
1122
1110
#endif
1123
1111
}
1124
1112
release_sock (sk );
1125
- rtnl_unlock ();
1126
1113
1127
- vxlan_sock_release (vs );
1128
- dev_put (vxlan -> dev );
1114
+ return ret ;
1129
1115
}
1130
1116
1131
1117
/* Inverse of vxlan_igmp_join when last VNI is brought down */
1132
- static void vxlan_igmp_leave (struct work_struct * work )
1118
+ static int vxlan_igmp_leave (struct vxlan_dev * vxlan )
1133
1119
{
1134
- struct vxlan_dev * vxlan = container_of (work , struct vxlan_dev , igmp_leave );
1135
1120
struct vxlan_sock * vs = vxlan -> vn_sock ;
1136
1121
struct sock * sk = vs -> sock -> sk ;
1137
1122
union vxlan_addr * ip = & vxlan -> default_dst .remote_ip ;
1138
1123
int ifindex = vxlan -> default_dst .remote_ifindex ;
1124
+ int ret ;
1139
1125
1140
- rtnl_lock ();
1141
1126
lock_sock (sk );
1142
1127
if (ip -> sa .sa_family == AF_INET ) {
1143
1128
struct ip_mreqn mreq = {
1144
1129
.imr_multiaddr .s_addr = ip -> sin .sin_addr .s_addr ,
1145
1130
.imr_ifindex = ifindex ,
1146
1131
};
1147
1132
1148
- ip_mc_leave_group (sk , & mreq );
1133
+ ret = ip_mc_leave_group (sk , & mreq );
1149
1134
#if IS_ENABLED (CONFIG_IPV6 )
1150
1135
} else {
1151
- ipv6_stub -> ipv6_sock_mc_drop (sk , ifindex ,
1152
- & ip -> sin6 .sin6_addr );
1136
+ ret = ipv6_stub -> ipv6_sock_mc_drop (sk , ifindex ,
1137
+ & ip -> sin6 .sin6_addr );
1153
1138
#endif
1154
1139
}
1155
-
1156
1140
release_sock (sk );
1157
- rtnl_unlock ();
1158
1141
1159
- vxlan_sock_release (vs );
1160
- dev_put (vxlan -> dev );
1142
+ return ret ;
1161
1143
}
1162
1144
1163
1145
static struct vxlanhdr * vxlan_remcsum (struct sk_buff * skb , struct vxlanhdr * vh ,
@@ -2178,37 +2160,22 @@ static void vxlan_cleanup(unsigned long arg)
2178
2160
2179
2161
static void vxlan_vs_add_dev (struct vxlan_sock * vs , struct vxlan_dev * vxlan )
2180
2162
{
2163
+ struct vxlan_net * vn = net_generic (vxlan -> net , vxlan_net_id );
2181
2164
__u32 vni = vxlan -> default_dst .remote_vni ;
2182
2165
2183
2166
vxlan -> vn_sock = vs ;
2167
+ spin_lock (& vn -> sock_lock );
2184
2168
hlist_add_head_rcu (& vxlan -> hlist , vni_head (vs , vni ));
2169
+ spin_unlock (& vn -> sock_lock );
2185
2170
}
2186
2171
2187
2172
/* Setup stats when device is created */
2188
2173
static int vxlan_init (struct net_device * dev )
2189
2174
{
2190
- struct vxlan_dev * vxlan = netdev_priv (dev );
2191
- struct vxlan_net * vn = net_generic (vxlan -> net , vxlan_net_id );
2192
- struct vxlan_sock * vs ;
2193
- bool ipv6 = vxlan -> flags & VXLAN_F_IPV6 ;
2194
-
2195
2175
dev -> tstats = netdev_alloc_pcpu_stats (struct pcpu_sw_netstats );
2196
2176
if (!dev -> tstats )
2197
2177
return - ENOMEM ;
2198
2178
2199
- spin_lock (& vn -> sock_lock );
2200
- vs = vxlan_find_sock (vxlan -> net , ipv6 ? AF_INET6 : AF_INET ,
2201
- vxlan -> dst_port , vxlan -> flags );
2202
- if (vs && atomic_add_unless (& vs -> refcnt , 1 , 0 )) {
2203
- /* If we have a socket with same port already, reuse it */
2204
- vxlan_vs_add_dev (vs , vxlan );
2205
- } else {
2206
- /* otherwise make new socket outside of RTNL */
2207
- dev_hold (dev );
2208
- queue_work (vxlan_wq , & vxlan -> sock_work );
2209
- }
2210
- spin_unlock (& vn -> sock_lock );
2211
-
2212
2179
return 0 ;
2213
2180
}
2214
2181
@@ -2226,35 +2193,38 @@ static void vxlan_fdb_delete_default(struct vxlan_dev *vxlan)
2226
2193
static void vxlan_uninit (struct net_device * dev )
2227
2194
{
2228
2195
struct vxlan_dev * vxlan = netdev_priv (dev );
2229
- struct vxlan_sock * vs = vxlan -> vn_sock ;
2230
2196
2231
2197
vxlan_fdb_delete_default (vxlan );
2232
2198
2233
- if (vs )
2234
- vxlan_sock_release (vs );
2235
2199
free_percpu (dev -> tstats );
2236
2200
}
2237
2201
2238
2202
/* Start ageing timer and join group when device is brought up */
2239
2203
static int vxlan_open (struct net_device * dev )
2240
2204
{
2241
2205
struct vxlan_dev * vxlan = netdev_priv (dev );
2242
- struct vxlan_sock * vs = vxlan -> vn_sock ;
2206
+ struct vxlan_sock * vs ;
2207
+ int ret = 0 ;
2243
2208
2244
- /* socket hasn't been created */
2245
- if (!vs )
2246
- return - ENOTCONN ;
2209
+ vs = vxlan_sock_add (vxlan -> net , vxlan -> dst_port , vxlan_rcv , NULL ,
2210
+ false, vxlan -> flags );
2211
+ if (IS_ERR (vs ))
2212
+ return PTR_ERR (vs );
2213
+
2214
+ vxlan_vs_add_dev (vs , vxlan );
2247
2215
2248
2216
if (vxlan_addr_multicast (& vxlan -> default_dst .remote_ip )) {
2249
- vxlan_sock_hold (vs );
2250
- dev_hold (dev );
2251
- queue_work (vxlan_wq , & vxlan -> igmp_join );
2217
+ ret = vxlan_igmp_join (vxlan );
2218
+ if (ret ) {
2219
+ vxlan_sock_release (vs );
2220
+ return ret ;
2221
+ }
2252
2222
}
2253
2223
2254
2224
if (vxlan -> age_interval )
2255
2225
mod_timer (& vxlan -> age_timer , jiffies + FDB_AGE_INTERVAL );
2256
2226
2257
- return 0 ;
2227
+ return ret ;
2258
2228
}
2259
2229
2260
2230
/* Purge the forwarding table */
@@ -2282,19 +2252,21 @@ static int vxlan_stop(struct net_device *dev)
2282
2252
struct vxlan_dev * vxlan = netdev_priv (dev );
2283
2253
struct vxlan_net * vn = net_generic (vxlan -> net , vxlan_net_id );
2284
2254
struct vxlan_sock * vs = vxlan -> vn_sock ;
2255
+ int ret = 0 ;
2285
2256
2286
2257
if (vs && vxlan_addr_multicast (& vxlan -> default_dst .remote_ip ) &&
2287
2258
!vxlan_group_used (vn , vxlan )) {
2288
- vxlan_sock_hold ( vs );
2289
- dev_hold ( dev );
2290
- queue_work ( vxlan_wq , & vxlan -> igmp_leave ) ;
2259
+ ret = vxlan_igmp_leave ( vxlan );
2260
+ if ( ret )
2261
+ return ret ;
2291
2262
}
2292
2263
2293
2264
del_timer_sync (& vxlan -> age_timer );
2294
2265
2295
2266
vxlan_flush (vxlan );
2267
+ vxlan_sock_release (vs );
2296
2268
2297
- return 0 ;
2269
+ return ret ;
2298
2270
}
2299
2271
2300
2272
/* Stub, nothing needs to be done. */
@@ -2405,9 +2377,6 @@ static void vxlan_setup(struct net_device *dev)
2405
2377
2406
2378
INIT_LIST_HEAD (& vxlan -> next );
2407
2379
spin_lock_init (& vxlan -> hash_lock );
2408
- INIT_WORK (& vxlan -> igmp_join , vxlan_igmp_join );
2409
- INIT_WORK (& vxlan -> igmp_leave , vxlan_igmp_leave );
2410
- INIT_WORK (& vxlan -> sock_work , vxlan_sock_work );
2411
2380
2412
2381
init_timer_deferrable (& vxlan -> age_timer );
2413
2382
vxlan -> age_timer .function = vxlan_cleanup ;
@@ -2554,6 +2523,8 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port,
2554
2523
2555
2524
sock = vxlan_create_sock (net , ipv6 , port , flags );
2556
2525
if (IS_ERR (sock )) {
2526
+ pr_info ("Cannot bind port %d, err=%ld\n" , ntohs (port ),
2527
+ PTR_ERR (sock ));
2557
2528
kfree (vs );
2558
2529
return ERR_CAST (sock );
2559
2530
}
@@ -2593,45 +2564,23 @@ struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
2593
2564
struct vxlan_sock * vs ;
2594
2565
bool ipv6 = flags & VXLAN_F_IPV6 ;
2595
2566
2596
- vs = vxlan_socket_create (net , port , rcv , data , flags );
2597
- if (!IS_ERR (vs ))
2598
- return vs ;
2599
-
2600
- if (no_share ) /* Return error if sharing is not allowed. */
2601
- return vs ;
2602
-
2603
- spin_lock (& vn -> sock_lock );
2604
- vs = vxlan_find_sock (net , ipv6 ? AF_INET6 : AF_INET , port , flags );
2605
- if (vs && ((vs -> rcv != rcv ) ||
2606
- !atomic_add_unless (& vs -> refcnt , 1 , 0 )))
2607
- vs = ERR_PTR (- EBUSY );
2608
- spin_unlock (& vn -> sock_lock );
2609
-
2610
- if (!vs )
2611
- vs = ERR_PTR (- EINVAL );
2567
+ if (!no_share ) {
2568
+ spin_lock (& vn -> sock_lock );
2569
+ vs = vxlan_find_sock (net , ipv6 ? AF_INET6 : AF_INET , port ,
2570
+ flags );
2571
+ if (vs && vs -> rcv == rcv ) {
2572
+ if (!atomic_add_unless (& vs -> refcnt , 1 , 0 ))
2573
+ vs = ERR_PTR (- EBUSY );
2574
+ spin_unlock (& vn -> sock_lock );
2575
+ return vs ;
2576
+ }
2577
+ spin_unlock (& vn -> sock_lock );
2578
+ }
2612
2579
2613
- return vs ;
2580
+ return vxlan_socket_create ( net , port , rcv , data , flags ) ;
2614
2581
}
2615
2582
EXPORT_SYMBOL_GPL (vxlan_sock_add );
2616
2583
2617
- /* Scheduled at device creation to bind to a socket */
2618
- static void vxlan_sock_work (struct work_struct * work )
2619
- {
2620
- struct vxlan_dev * vxlan = container_of (work , struct vxlan_dev , sock_work );
2621
- struct net * net = vxlan -> net ;
2622
- struct vxlan_net * vn = net_generic (net , vxlan_net_id );
2623
- __be16 port = vxlan -> dst_port ;
2624
- struct vxlan_sock * nvs ;
2625
-
2626
- nvs = vxlan_sock_add (net , port , vxlan_rcv , NULL , false, vxlan -> flags );
2627
- spin_lock (& vn -> sock_lock );
2628
- if (!IS_ERR (nvs ))
2629
- vxlan_vs_add_dev (nvs , vxlan );
2630
- spin_unlock (& vn -> sock_lock );
2631
-
2632
- dev_put (vxlan -> dev );
2633
- }
2634
-
2635
2584
static int vxlan_newlink (struct net * src_net , struct net_device * dev ,
2636
2585
struct nlattr * tb [], struct nlattr * data [])
2637
2586
{
0 commit comments