diff options
author | Sainath Grandhi <sainath.grandhi@intel.com> | 2017-02-10 19:03:49 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-02-11 20:59:41 -0500 |
commit | 6fe3faf86757eb7f078ff06b23b206f17dc4fb36 (patch) | |
tree | 4602f5f435ad34f406ec980694daae4faf5d6119 /drivers/net/tap.c | |
parent | ebc05ba7e8600b52a2a0c87a43105143368aca2a (diff) |
tap: Abstract type of virtual interface from tap implementation
macvlan object is re-structured to hold tap related elements in a separate
entity, tap_dev. Upon NETDEV_REGISTER device_event, tap_dev is registered with
idr and fetched again on tap_open. Few of the tap functions are modified to
accepted tap_dev as argument. tap_dev object includes callbacks to be used by
underlying virtual interface to take care of tx and rx accounting.
Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tap.c')
-rw-r--r-- | drivers/net/tap.c | 264 |
1 files changed, 118 insertions, 146 deletions
diff --git a/drivers/net/tap.c b/drivers/net/tap.c index 04ba9782c2f3..7d3e8b18f5e6 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c | |||
@@ -1,5 +1,5 @@ | |||
1 | #include <linux/etherdevice.h> | 1 | #include <linux/etherdevice.h> |
2 | #include <linux/if_macvlan.h> | 2 | #include <linux/if_tap.h> |
3 | #include <linux/if_vlan.h> | 3 | #include <linux/if_vlan.h> |
4 | #include <linux/interrupt.h> | 4 | #include <linux/interrupt.h> |
5 | #include <linux/nsproxy.h> | 5 | #include <linux/nsproxy.h> |
@@ -23,30 +23,6 @@ | |||
23 | #include <linux/virtio_net.h> | 23 | #include <linux/virtio_net.h> |
24 | #include <linux/skb_array.h> | 24 | #include <linux/skb_array.h> |
25 | 25 | ||
26 | /* | ||
27 | * A tap queue is the central object of this driver, it connects | ||
28 | * an open character device to a macvlan interface. There can be | ||
29 | * multiple queues on one interface, which map back to queues | ||
30 | * implemented in hardware on the underlying device. | ||
31 | * | ||
32 | * tap_proto is used to allocate queues through the sock allocation | ||
33 | * mechanism. | ||
34 | * | ||
35 | */ | ||
36 | struct tap_queue { | ||
37 | struct sock sk; | ||
38 | struct socket sock; | ||
39 | struct socket_wq wq; | ||
40 | int vnet_hdr_sz; | ||
41 | struct macvlan_dev __rcu *vlan; | ||
42 | struct file *file; | ||
43 | unsigned int flags; | ||
44 | u16 queue_index; | ||
45 | bool enabled; | ||
46 | struct list_head next; | ||
47 | struct skb_array skb_array; | ||
48 | }; | ||
49 | |||
50 | #define TAP_IFFEATURES (IFF_VNET_HDR | IFF_MULTI_QUEUE) | 26 | #define TAP_IFFEATURES (IFF_VNET_HDR | IFF_MULTI_QUEUE) |
51 | 27 | ||
52 | #define TAP_VNET_LE 0x80000000 | 28 | #define TAP_VNET_LE 0x80000000 |
@@ -137,7 +113,7 @@ static const struct proto_ops tap_socket_ops; | |||
137 | #define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO) | 113 | #define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO) |
138 | #define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG | NETIF_F_FRAGLIST) | 114 | #define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG | NETIF_F_FRAGLIST) |
139 | 115 | ||
140 | static struct macvlan_dev *tap_get_vlan_rcu(const struct net_device *dev) | 116 | static struct tap_dev *tap_dev_get_rcu(const struct net_device *dev) |
141 | { | 117 | { |
142 | return rcu_dereference(dev->rx_handler_data); | 118 | return rcu_dereference(dev->rx_handler_data); |
143 | } | 119 | } |
@@ -159,10 +135,9 @@ static struct macvlan_dev *tap_get_vlan_rcu(const struct net_device *dev) | |||
159 | * when both our references and any pending SKBs are gone. | 135 | * when both our references and any pending SKBs are gone. |
160 | */ | 136 | */ |
161 | 137 | ||
162 | static int tap_enable_queue(struct net_device *dev, struct file *file, | 138 | static int tap_enable_queue(struct tap_dev *tap, struct file *file, |
163 | struct tap_queue *q) | 139 | struct tap_queue *q) |
164 | { | 140 | { |
165 | struct macvlan_dev *vlan = netdev_priv(dev); | ||
166 | int err = -EINVAL; | 141 | int err = -EINVAL; |
167 | 142 | ||
168 | ASSERT_RTNL(); | 143 | ASSERT_RTNL(); |
@@ -171,62 +146,60 @@ static int tap_enable_queue(struct net_device *dev, struct file *file, | |||
171 | goto out; | 146 | goto out; |
172 | 147 | ||
173 | err = 0; | 148 | err = 0; |
174 | rcu_assign_pointer(vlan->taps[vlan->numvtaps], q); | 149 | rcu_assign_pointer(tap->taps[tap->numvtaps], q); |
175 | q->queue_index = vlan->numvtaps; | 150 | q->queue_index = tap->numvtaps; |
176 | q->enabled = true; | 151 | q->enabled = true; |
177 | 152 | ||
178 | vlan->numvtaps++; | 153 | tap->numvtaps++; |
179 | out: | 154 | out: |
180 | return err; | 155 | return err; |
181 | } | 156 | } |
182 | 157 | ||
183 | /* Requires RTNL */ | 158 | /* Requires RTNL */ |
184 | static int tap_set_queue(struct net_device *dev, struct file *file, | 159 | static int tap_set_queue(struct tap_dev *tap, struct file *file, |
185 | struct tap_queue *q) | 160 | struct tap_queue *q) |
186 | { | 161 | { |
187 | struct macvlan_dev *vlan = netdev_priv(dev); | 162 | if (tap->numqueues == MAX_TAP_QUEUES) |
188 | |||
189 | if (vlan->numqueues == MAX_TAP_QUEUES) | ||
190 | return -EBUSY; | 163 | return -EBUSY; |
191 | 164 | ||
192 | rcu_assign_pointer(q->vlan, vlan); | 165 | rcu_assign_pointer(q->tap, tap); |
193 | rcu_assign_pointer(vlan->taps[vlan->numvtaps], q); | 166 | rcu_assign_pointer(tap->taps[tap->numvtaps], q); |
194 | sock_hold(&q->sk); | 167 | sock_hold(&q->sk); |
195 | 168 | ||
196 | q->file = file; | 169 | q->file = file; |
197 | q->queue_index = vlan->numvtaps; | 170 | q->queue_index = tap->numvtaps; |
198 | q->enabled = true; | 171 | q->enabled = true; |
199 | file->private_data = q; | 172 | file->private_data = q; |
200 | list_add_tail(&q->next, &vlan->queue_list); | 173 | list_add_tail(&q->next, &tap->queue_list); |
201 | 174 | ||
202 | vlan->numvtaps++; | 175 | tap->numvtaps++; |
203 | vlan->numqueues++; | 176 | tap->numqueues++; |
204 | 177 | ||
205 | return 0; | 178 | return 0; |
206 | } | 179 | } |
207 | 180 | ||
208 | static int tap_disable_queue(struct tap_queue *q) | 181 | static int tap_disable_queue(struct tap_queue *q) |
209 | { | 182 | { |
210 | struct macvlan_dev *vlan; | 183 | struct tap_dev *tap; |
211 | struct tap_queue *nq; | 184 | struct tap_queue *nq; |
212 | 185 | ||
213 | ASSERT_RTNL(); | 186 | ASSERT_RTNL(); |
214 | if (!q->enabled) | 187 | if (!q->enabled) |
215 | return -EINVAL; | 188 | return -EINVAL; |
216 | 189 | ||
217 | vlan = rtnl_dereference(q->vlan); | 190 | tap = rtnl_dereference(q->tap); |
218 | 191 | ||
219 | if (vlan) { | 192 | if (tap) { |
220 | int index = q->queue_index; | 193 | int index = q->queue_index; |
221 | BUG_ON(index >= vlan->numvtaps); | 194 | BUG_ON(index >= tap->numvtaps); |
222 | nq = rtnl_dereference(vlan->taps[vlan->numvtaps - 1]); | 195 | nq = rtnl_dereference(tap->taps[tap->numvtaps - 1]); |
223 | nq->queue_index = index; | 196 | nq->queue_index = index; |
224 | 197 | ||
225 | rcu_assign_pointer(vlan->taps[index], nq); | 198 | rcu_assign_pointer(tap->taps[index], nq); |
226 | RCU_INIT_POINTER(vlan->taps[vlan->numvtaps - 1], NULL); | 199 | RCU_INIT_POINTER(tap->taps[tap->numvtaps - 1], NULL); |
227 | q->enabled = false; | 200 | q->enabled = false; |
228 | 201 | ||
229 | vlan->numvtaps--; | 202 | tap->numvtaps--; |
230 | } | 203 | } |
231 | 204 | ||
232 | return 0; | 205 | return 0; |
@@ -242,17 +215,17 @@ static int tap_disable_queue(struct tap_queue *q) | |||
242 | */ | 215 | */ |
243 | static void tap_put_queue(struct tap_queue *q) | 216 | static void tap_put_queue(struct tap_queue *q) |
244 | { | 217 | { |
245 | struct macvlan_dev *vlan; | 218 | struct tap_dev *tap; |
246 | 219 | ||
247 | rtnl_lock(); | 220 | rtnl_lock(); |
248 | vlan = rtnl_dereference(q->vlan); | 221 | tap = rtnl_dereference(q->tap); |
249 | 222 | ||
250 | if (vlan) { | 223 | if (tap) { |
251 | if (q->enabled) | 224 | if (q->enabled) |
252 | BUG_ON(tap_disable_queue(q)); | 225 | BUG_ON(tap_disable_queue(q)); |
253 | 226 | ||
254 | vlan->numqueues--; | 227 | tap->numqueues--; |
255 | RCU_INIT_POINTER(q->vlan, NULL); | 228 | RCU_INIT_POINTER(q->tap, NULL); |
256 | sock_put(&q->sk); | 229 | sock_put(&q->sk); |
257 | list_del_init(&q->next); | 230 | list_del_init(&q->next); |
258 | } | 231 | } |
@@ -270,17 +243,16 @@ static void tap_put_queue(struct tap_queue *q) | |||
270 | * Cache vlan->numvtaps since it can become zero during the execution | 243 | * Cache vlan->numvtaps since it can become zero during the execution |
271 | * of this function. | 244 | * of this function. |
272 | */ | 245 | */ |
273 | static struct tap_queue *tap_get_queue(struct net_device *dev, | 246 | static struct tap_queue *tap_get_queue(struct tap_dev *tap, |
274 | struct sk_buff *skb) | 247 | struct sk_buff *skb) |
275 | { | 248 | { |
276 | struct macvlan_dev *vlan = netdev_priv(dev); | 249 | struct tap_queue *queue = NULL; |
277 | struct tap_queue *tap = NULL; | ||
278 | /* Access to taps array is protected by rcu, but access to numvtaps | 250 | /* Access to taps array is protected by rcu, but access to numvtaps |
279 | * isn't. Below we use it to lookup a queue, but treat it as a hint | 251 | * isn't. Below we use it to lookup a queue, but treat it as a hint |
280 | * and validate that the result isn't NULL - in case we are | 252 | * and validate that the result isn't NULL - in case we are |
281 | * racing against queue removal. | 253 | * racing against queue removal. |
282 | */ | 254 | */ |
283 | int numvtaps = ACCESS_ONCE(vlan->numvtaps); | 255 | int numvtaps = ACCESS_ONCE(tap->numvtaps); |
284 | __u32 rxq; | 256 | __u32 rxq; |
285 | 257 | ||
286 | if (!numvtaps) | 258 | if (!numvtaps) |
@@ -292,7 +264,7 @@ static struct tap_queue *tap_get_queue(struct net_device *dev, | |||
292 | /* Check if we can use flow to select a queue */ | 264 | /* Check if we can use flow to select a queue */ |
293 | rxq = skb_get_hash(skb); | 265 | rxq = skb_get_hash(skb); |
294 | if (rxq) { | 266 | if (rxq) { |
295 | tap = rcu_dereference(vlan->taps[rxq % numvtaps]); | 267 | queue = rcu_dereference(tap->taps[rxq % numvtaps]); |
296 | goto out; | 268 | goto out; |
297 | } | 269 | } |
298 | 270 | ||
@@ -302,14 +274,14 @@ static struct tap_queue *tap_get_queue(struct net_device *dev, | |||
302 | while (unlikely(rxq >= numvtaps)) | 274 | while (unlikely(rxq >= numvtaps)) |
303 | rxq -= numvtaps; | 275 | rxq -= numvtaps; |
304 | 276 | ||
305 | tap = rcu_dereference(vlan->taps[rxq]); | 277 | queue = rcu_dereference(tap->taps[rxq]); |
306 | goto out; | 278 | goto out; |
307 | } | 279 | } |
308 | 280 | ||
309 | single: | 281 | single: |
310 | tap = rcu_dereference(vlan->taps[0]); | 282 | queue = rcu_dereference(tap->taps[0]); |
311 | out: | 283 | out: |
312 | return tap; | 284 | return queue; |
313 | } | 285 | } |
314 | 286 | ||
315 | /* | 287 | /* |
@@ -317,39 +289,38 @@ out: | |||
317 | * that it holds on all queues and safely set the pointer | 289 | * that it holds on all queues and safely set the pointer |
318 | * from the queues to NULL. | 290 | * from the queues to NULL. |
319 | */ | 291 | */ |
320 | void tap_del_queues(struct net_device *dev) | 292 | void tap_del_queues(struct tap_dev *tap) |
321 | { | 293 | { |
322 | struct macvlan_dev *vlan = netdev_priv(dev); | ||
323 | struct tap_queue *q, *tmp; | 294 | struct tap_queue *q, *tmp; |
324 | 295 | ||
325 | ASSERT_RTNL(); | 296 | ASSERT_RTNL(); |
326 | list_for_each_entry_safe(q, tmp, &vlan->queue_list, next) { | 297 | list_for_each_entry_safe(q, tmp, &tap->queue_list, next) { |
327 | list_del_init(&q->next); | 298 | list_del_init(&q->next); |
328 | RCU_INIT_POINTER(q->vlan, NULL); | 299 | RCU_INIT_POINTER(q->tap, NULL); |
329 | if (q->enabled) | 300 | if (q->enabled) |
330 | vlan->numvtaps--; | 301 | tap->numvtaps--; |
331 | vlan->numqueues--; | 302 | tap->numqueues--; |
332 | sock_put(&q->sk); | 303 | sock_put(&q->sk); |
333 | } | 304 | } |
334 | BUG_ON(vlan->numvtaps); | 305 | BUG_ON(tap->numvtaps); |
335 | BUG_ON(vlan->numqueues); | 306 | BUG_ON(tap->numqueues); |
336 | /* guarantee that any future tap_set_queue will fail */ | 307 | /* guarantee that any future tap_set_queue will fail */ |
337 | vlan->numvtaps = MAX_TAP_QUEUES; | 308 | tap->numvtaps = MAX_TAP_QUEUES; |
338 | } | 309 | } |
339 | 310 | ||
340 | rx_handler_result_t tap_handle_frame(struct sk_buff **pskb) | 311 | rx_handler_result_t tap_handle_frame(struct sk_buff **pskb) |
341 | { | 312 | { |
342 | struct sk_buff *skb = *pskb; | 313 | struct sk_buff *skb = *pskb; |
343 | struct net_device *dev = skb->dev; | 314 | struct net_device *dev = skb->dev; |
344 | struct macvlan_dev *vlan; | 315 | struct tap_dev *tap; |
345 | struct tap_queue *q; | 316 | struct tap_queue *q; |
346 | netdev_features_t features = TAP_FEATURES; | 317 | netdev_features_t features = TAP_FEATURES; |
347 | 318 | ||
348 | vlan = tap_get_vlan_rcu(dev); | 319 | tap = tap_dev_get_rcu(dev); |
349 | if (!vlan) | 320 | if (!tap) |
350 | return RX_HANDLER_PASS; | 321 | return RX_HANDLER_PASS; |
351 | 322 | ||
352 | q = tap_get_queue(dev, skb); | 323 | q = tap_get_queue(tap, skb); |
353 | if (!q) | 324 | if (!q) |
354 | return RX_HANDLER_PASS; | 325 | return RX_HANDLER_PASS; |
355 | 326 | ||
@@ -363,7 +334,7 @@ rx_handler_result_t tap_handle_frame(struct sk_buff **pskb) | |||
363 | * enabled. | 334 | * enabled. |
364 | */ | 335 | */ |
365 | if (q->flags & IFF_VNET_HDR) | 336 | if (q->flags & IFF_VNET_HDR) |
366 | features |= vlan->tap_features; | 337 | features |= tap->tap_features; |
367 | if (netif_needs_gso(skb, features)) { | 338 | if (netif_needs_gso(skb, features)) { |
368 | struct sk_buff *segs = __skb_gso_segment(skb, features, false); | 339 | struct sk_buff *segs = __skb_gso_segment(skb, features, false); |
369 | 340 | ||
@@ -408,50 +379,51 @@ wake_up: | |||
408 | 379 | ||
409 | drop: | 380 | drop: |
410 | /* Count errors/drops only here, thus don't care about args. */ | 381 | /* Count errors/drops only here, thus don't care about args. */ |
411 | macvlan_count_rx(vlan, 0, 0, 0); | 382 | if (tap->count_rx_dropped) |
383 | tap->count_rx_dropped(tap); | ||
412 | kfree_skb(skb); | 384 | kfree_skb(skb); |
413 | return RX_HANDLER_CONSUMED; | 385 | return RX_HANDLER_CONSUMED; |
414 | } | 386 | } |
415 | 387 | ||
416 | int tap_get_minor(struct macvlan_dev *vlan) | 388 | int tap_get_minor(struct tap_dev *tap) |
417 | { | 389 | { |
418 | int retval = -ENOMEM; | 390 | int retval = -ENOMEM; |
419 | 391 | ||
420 | mutex_lock(&macvtap_major.minor_lock); | 392 | mutex_lock(&macvtap_major.minor_lock); |
421 | retval = idr_alloc(&macvtap_major.minor_idr, vlan, 1, TAP_NUM_DEVS, GFP_KERNEL); | 393 | retval = idr_alloc(&macvtap_major.minor_idr, tap, 1, TAP_NUM_DEVS, GFP_KERNEL); |
422 | if (retval >= 0) { | 394 | if (retval >= 0) { |
423 | vlan->minor = retval; | 395 | tap->minor = retval; |
424 | } else if (retval == -ENOSPC) { | 396 | } else if (retval == -ENOSPC) { |
425 | netdev_err(vlan->dev, "Too many tap devices\n"); | 397 | netdev_err(tap->dev, "Too many tap devices\n"); |
426 | retval = -EINVAL; | 398 | retval = -EINVAL; |
427 | } | 399 | } |
428 | mutex_unlock(&macvtap_major.minor_lock); | 400 | mutex_unlock(&macvtap_major.minor_lock); |
429 | return retval < 0 ? retval : 0; | 401 | return retval < 0 ? retval : 0; |
430 | } | 402 | } |
431 | 403 | ||
432 | void tap_free_minor(struct macvlan_dev *vlan) | 404 | void tap_free_minor(struct tap_dev *tap) |
433 | { | 405 | { |
434 | mutex_lock(&macvtap_major.minor_lock); | 406 | mutex_lock(&macvtap_major.minor_lock); |
435 | if (vlan->minor) { | 407 | if (tap->minor) { |
436 | idr_remove(&macvtap_major.minor_idr, vlan->minor); | 408 | idr_remove(&macvtap_major.minor_idr, tap->minor); |
437 | vlan->minor = 0; | 409 | tap->minor = 0; |
438 | } | 410 | } |
439 | mutex_unlock(&macvtap_major.minor_lock); | 411 | mutex_unlock(&macvtap_major.minor_lock); |
440 | } | 412 | } |
441 | 413 | ||
442 | static struct net_device *dev_get_by_tap_minor(int minor) | 414 | static struct tap_dev *dev_get_by_tap_minor(int minor) |
443 | { | 415 | { |
444 | struct net_device *dev = NULL; | 416 | struct net_device *dev = NULL; |
445 | struct macvlan_dev *vlan; | 417 | struct tap_dev *tap; |
446 | 418 | ||
447 | mutex_lock(&macvtap_major.minor_lock); | 419 | mutex_lock(&macvtap_major.minor_lock); |
448 | vlan = idr_find(&macvtap_major.minor_idr, minor); | 420 | tap = idr_find(&macvtap_major.minor_idr, minor); |
449 | if (vlan) { | 421 | if (tap) { |
450 | dev = vlan->dev; | 422 | dev = tap->dev; |
451 | dev_hold(dev); | 423 | dev_hold(dev); |
452 | } | 424 | } |
453 | mutex_unlock(&macvtap_major.minor_lock); | 425 | mutex_unlock(&macvtap_major.minor_lock); |
454 | return dev; | 426 | return tap; |
455 | } | 427 | } |
456 | 428 | ||
457 | static void tap_sock_write_space(struct sock *sk) | 429 | static void tap_sock_write_space(struct sock *sk) |
@@ -477,13 +449,13 @@ static void tap_sock_destruct(struct sock *sk) | |||
477 | static int tap_open(struct inode *inode, struct file *file) | 449 | static int tap_open(struct inode *inode, struct file *file) |
478 | { | 450 | { |
479 | struct net *net = current->nsproxy->net_ns; | 451 | struct net *net = current->nsproxy->net_ns; |
480 | struct net_device *dev; | 452 | struct tap_dev *tap; |
481 | struct tap_queue *q; | 453 | struct tap_queue *q; |
482 | int err = -ENODEV; | 454 | int err = -ENODEV; |
483 | 455 | ||
484 | rtnl_lock(); | 456 | rtnl_lock(); |
485 | dev = dev_get_by_tap_minor(iminor(inode)); | 457 | tap = dev_get_by_tap_minor(iminor(inode)); |
486 | if (!dev) | 458 | if (!tap) |
487 | goto err; | 459 | goto err; |
488 | 460 | ||
489 | err = -ENOMEM; | 461 | err = -ENOMEM; |
@@ -511,18 +483,18 @@ static int tap_open(struct inode *inode, struct file *file) | |||
511 | * The macvlan supports zerocopy iff the lower device supports zero | 483 | * The macvlan supports zerocopy iff the lower device supports zero |
512 | * copy so we don't have to look at the lower device directly. | 484 | * copy so we don't have to look at the lower device directly. |
513 | */ | 485 | */ |
514 | if ((dev->features & NETIF_F_HIGHDMA) && (dev->features & NETIF_F_SG)) | 486 | if ((tap->dev->features & NETIF_F_HIGHDMA) && (tap->dev->features & NETIF_F_SG)) |
515 | sock_set_flag(&q->sk, SOCK_ZEROCOPY); | 487 | sock_set_flag(&q->sk, SOCK_ZEROCOPY); |
516 | 488 | ||
517 | err = -ENOMEM; | 489 | err = -ENOMEM; |
518 | if (skb_array_init(&q->skb_array, dev->tx_queue_len, GFP_KERNEL)) | 490 | if (skb_array_init(&q->skb_array, tap->dev->tx_queue_len, GFP_KERNEL)) |
519 | goto err_array; | 491 | goto err_array; |
520 | 492 | ||
521 | err = tap_set_queue(dev, file, q); | 493 | err = tap_set_queue(tap, file, q); |
522 | if (err) | 494 | if (err) |
523 | goto err_queue; | 495 | goto err_queue; |
524 | 496 | ||
525 | dev_put(dev); | 497 | dev_put(tap->dev); |
526 | 498 | ||
527 | rtnl_unlock(); | 499 | rtnl_unlock(); |
528 | return err; | 500 | return err; |
@@ -532,8 +504,8 @@ err_queue: | |||
532 | err_array: | 504 | err_array: |
533 | sock_put(&q->sk); | 505 | sock_put(&q->sk); |
534 | err: | 506 | err: |
535 | if (dev) | 507 | if (tap) |
536 | dev_put(dev); | 508 | dev_put(tap->dev); |
537 | 509 | ||
538 | rtnl_unlock(); | 510 | rtnl_unlock(); |
539 | return err; | 511 | return err; |
@@ -601,7 +573,7 @@ static ssize_t tap_get_user(struct tap_queue *q, struct msghdr *m, | |||
601 | { | 573 | { |
602 | int good_linear = SKB_MAX_HEAD(TAP_RESERVE); | 574 | int good_linear = SKB_MAX_HEAD(TAP_RESERVE); |
603 | struct sk_buff *skb; | 575 | struct sk_buff *skb; |
604 | struct macvlan_dev *vlan; | 576 | struct tap_dev *tap; |
605 | unsigned long total_len = iov_iter_count(from); | 577 | unsigned long total_len = iov_iter_count(from); |
606 | unsigned long len = total_len; | 578 | unsigned long len = total_len; |
607 | int err; | 579 | int err; |
@@ -698,7 +670,7 @@ static ssize_t tap_get_user(struct tap_queue *q, struct msghdr *m, | |||
698 | skb_set_network_header(skb, depth); | 670 | skb_set_network_header(skb, depth); |
699 | 671 | ||
700 | rcu_read_lock(); | 672 | rcu_read_lock(); |
701 | vlan = rcu_dereference(q->vlan); | 673 | tap = rcu_dereference(q->tap); |
702 | /* copy skb_ubuf_info for callback when skb has no error */ | 674 | /* copy skb_ubuf_info for callback when skb has no error */ |
703 | if (zerocopy) { | 675 | if (zerocopy) { |
704 | skb_shinfo(skb)->destructor_arg = m->msg_control; | 676 | skb_shinfo(skb)->destructor_arg = m->msg_control; |
@@ -709,8 +681,8 @@ static ssize_t tap_get_user(struct tap_queue *q, struct msghdr *m, | |||
709 | uarg->callback(uarg, false); | 681 | uarg->callback(uarg, false); |
710 | } | 682 | } |
711 | 683 | ||
712 | if (vlan) { | 684 | if (tap) { |
713 | skb->dev = vlan->dev; | 685 | skb->dev = tap->dev; |
714 | dev_queue_xmit(skb); | 686 | dev_queue_xmit(skb); |
715 | } else { | 687 | } else { |
716 | kfree_skb(skb); | 688 | kfree_skb(skb); |
@@ -724,9 +696,9 @@ err_kfree: | |||
724 | 696 | ||
725 | err: | 697 | err: |
726 | rcu_read_lock(); | 698 | rcu_read_lock(); |
727 | vlan = rcu_dereference(q->vlan); | 699 | tap = rcu_dereference(q->tap); |
728 | if (vlan) | 700 | if (tap && tap->count_tx_dropped) |
729 | this_cpu_inc(vlan->pcpu_stats->tx_dropped); | 701 | tap->count_tx_dropped(tap); |
730 | rcu_read_unlock(); | 702 | rcu_read_unlock(); |
731 | 703 | ||
732 | return err; | 704 | return err; |
@@ -853,55 +825,55 @@ static ssize_t tap_read_iter(struct kiocb *iocb, struct iov_iter *to) | |||
853 | return ret; | 825 | return ret; |
854 | } | 826 | } |
855 | 827 | ||
856 | static struct macvlan_dev *tap_get_vlan(struct tap_queue *q) | 828 | static struct tap_dev *tap_get_tap_dev(struct tap_queue *q) |
857 | { | 829 | { |
858 | struct macvlan_dev *vlan; | 830 | struct tap_dev *tap; |
859 | 831 | ||
860 | ASSERT_RTNL(); | 832 | ASSERT_RTNL(); |
861 | vlan = rtnl_dereference(q->vlan); | 833 | tap = rtnl_dereference(q->tap); |
862 | if (vlan) | 834 | if (tap) |
863 | dev_hold(vlan->dev); | 835 | dev_hold(tap->dev); |
864 | 836 | ||
865 | return vlan; | 837 | return tap; |
866 | } | 838 | } |
867 | 839 | ||
868 | static void tap_put_vlan(struct macvlan_dev *vlan) | 840 | static void tap_put_tap_dev(struct tap_dev *tap) |
869 | { | 841 | { |
870 | dev_put(vlan->dev); | 842 | dev_put(tap->dev); |
871 | } | 843 | } |
872 | 844 | ||
873 | static int tap_ioctl_set_queue(struct file *file, unsigned int flags) | 845 | static int tap_ioctl_set_queue(struct file *file, unsigned int flags) |
874 | { | 846 | { |
875 | struct tap_queue *q = file->private_data; | 847 | struct tap_queue *q = file->private_data; |
876 | struct macvlan_dev *vlan; | 848 | struct tap_dev *tap; |
877 | int ret; | 849 | int ret; |
878 | 850 | ||
879 | vlan = tap_get_vlan(q); | 851 | tap = tap_get_tap_dev(q); |
880 | if (!vlan) | 852 | if (!tap) |
881 | return -EINVAL; | 853 | return -EINVAL; |
882 | 854 | ||
883 | if (flags & IFF_ATTACH_QUEUE) | 855 | if (flags & IFF_ATTACH_QUEUE) |
884 | ret = tap_enable_queue(vlan->dev, file, q); | 856 | ret = tap_enable_queue(tap, file, q); |
885 | else if (flags & IFF_DETACH_QUEUE) | 857 | else if (flags & IFF_DETACH_QUEUE) |
886 | ret = tap_disable_queue(q); | 858 | ret = tap_disable_queue(q); |
887 | else | 859 | else |
888 | ret = -EINVAL; | 860 | ret = -EINVAL; |
889 | 861 | ||
890 | tap_put_vlan(vlan); | 862 | tap_put_tap_dev(tap); |
891 | return ret; | 863 | return ret; |
892 | } | 864 | } |
893 | 865 | ||
894 | static int set_offload(struct tap_queue *q, unsigned long arg) | 866 | static int set_offload(struct tap_queue *q, unsigned long arg) |
895 | { | 867 | { |
896 | struct macvlan_dev *vlan; | 868 | struct tap_dev *tap; |
897 | netdev_features_t features; | 869 | netdev_features_t features; |
898 | netdev_features_t feature_mask = 0; | 870 | netdev_features_t feature_mask = 0; |
899 | 871 | ||
900 | vlan = rtnl_dereference(q->vlan); | 872 | tap = rtnl_dereference(q->tap); |
901 | if (!vlan) | 873 | if (!tap) |
902 | return -ENOLINK; | 874 | return -ENOLINK; |
903 | 875 | ||
904 | features = vlan->dev->features; | 876 | features = tap->dev->features; |
905 | 877 | ||
906 | if (arg & TUN_F_CSUM) { | 878 | if (arg & TUN_F_CSUM) { |
907 | feature_mask = NETIF_F_HW_CSUM; | 879 | feature_mask = NETIF_F_HW_CSUM; |
@@ -935,9 +907,9 @@ static int set_offload(struct tap_queue *q, unsigned long arg) | |||
935 | /* tap_features are the same as features on tun/tap and | 907 | /* tap_features are the same as features on tun/tap and |
936 | * reflect user expectations. | 908 | * reflect user expectations. |
937 | */ | 909 | */ |
938 | vlan->tap_features = feature_mask; | 910 | tap->tap_features = feature_mask; |
939 | vlan->set_features = features; | 911 | if (tap->update_features) |
940 | netdev_update_features(vlan->dev); | 912 | tap->update_features(tap, features); |
941 | 913 | ||
942 | return 0; | 914 | return 0; |
943 | } | 915 | } |
@@ -949,7 +921,7 @@ static long tap_ioctl(struct file *file, unsigned int cmd, | |||
949 | unsigned long arg) | 921 | unsigned long arg) |
950 | { | 922 | { |
951 | struct tap_queue *q = file->private_data; | 923 | struct tap_queue *q = file->private_data; |
952 | struct macvlan_dev *vlan; | 924 | struct tap_dev *tap; |
953 | void __user *argp = (void __user *)arg; | 925 | void __user *argp = (void __user *)arg; |
954 | struct ifreq __user *ifr = argp; | 926 | struct ifreq __user *ifr = argp; |
955 | unsigned int __user *up = argp; | 927 | unsigned int __user *up = argp; |
@@ -975,18 +947,18 @@ static long tap_ioctl(struct file *file, unsigned int cmd, | |||
975 | 947 | ||
976 | case TUNGETIFF: | 948 | case TUNGETIFF: |
977 | rtnl_lock(); | 949 | rtnl_lock(); |
978 | vlan = tap_get_vlan(q); | 950 | tap = tap_get_tap_dev(q); |
979 | if (!vlan) { | 951 | if (!tap) { |
980 | rtnl_unlock(); | 952 | rtnl_unlock(); |
981 | return -ENOLINK; | 953 | return -ENOLINK; |
982 | } | 954 | } |
983 | 955 | ||
984 | ret = 0; | 956 | ret = 0; |
985 | u = q->flags; | 957 | u = q->flags; |
986 | if (copy_to_user(&ifr->ifr_name, vlan->dev->name, IFNAMSIZ) || | 958 | if (copy_to_user(&ifr->ifr_name, tap->dev->name, IFNAMSIZ) || |
987 | put_user(u, &ifr->ifr_flags)) | 959 | put_user(u, &ifr->ifr_flags)) |
988 | ret = -EFAULT; | 960 | ret = -EFAULT; |
989 | tap_put_vlan(vlan); | 961 | tap_put_tap_dev(tap); |
990 | rtnl_unlock(); | 962 | rtnl_unlock(); |
991 | return ret; | 963 | return ret; |
992 | 964 | ||
@@ -1059,18 +1031,18 @@ static long tap_ioctl(struct file *file, unsigned int cmd, | |||
1059 | 1031 | ||
1060 | case SIOCGIFHWADDR: | 1032 | case SIOCGIFHWADDR: |
1061 | rtnl_lock(); | 1033 | rtnl_lock(); |
1062 | vlan = tap_get_vlan(q); | 1034 | tap = tap_get_tap_dev(q); |
1063 | if (!vlan) { | 1035 | if (!tap) { |
1064 | rtnl_unlock(); | 1036 | rtnl_unlock(); |
1065 | return -ENOLINK; | 1037 | return -ENOLINK; |
1066 | } | 1038 | } |
1067 | ret = 0; | 1039 | ret = 0; |
1068 | u = vlan->dev->type; | 1040 | u = tap->dev->type; |
1069 | if (copy_to_user(&ifr->ifr_name, vlan->dev->name, IFNAMSIZ) || | 1041 | if (copy_to_user(&ifr->ifr_name, tap->dev->name, IFNAMSIZ) || |
1070 | copy_to_user(&ifr->ifr_hwaddr.sa_data, vlan->dev->dev_addr, ETH_ALEN) || | 1042 | copy_to_user(&ifr->ifr_hwaddr.sa_data, tap->dev->dev_addr, ETH_ALEN) || |
1071 | put_user(u, &ifr->ifr_hwaddr.sa_family)) | 1043 | put_user(u, &ifr->ifr_hwaddr.sa_family)) |
1072 | ret = -EFAULT; | 1044 | ret = -EFAULT; |
1073 | tap_put_vlan(vlan); | 1045 | tap_put_tap_dev(tap); |
1074 | rtnl_unlock(); | 1046 | rtnl_unlock(); |
1075 | return ret; | 1047 | return ret; |
1076 | 1048 | ||
@@ -1078,13 +1050,13 @@ static long tap_ioctl(struct file *file, unsigned int cmd, | |||
1078 | if (copy_from_user(&sa, &ifr->ifr_hwaddr, sizeof(sa))) | 1050 | if (copy_from_user(&sa, &ifr->ifr_hwaddr, sizeof(sa))) |
1079 | return -EFAULT; | 1051 | return -EFAULT; |
1080 | rtnl_lock(); | 1052 | rtnl_lock(); |
1081 | vlan = tap_get_vlan(q); | 1053 | tap = tap_get_tap_dev(q); |
1082 | if (!vlan) { | 1054 | if (!tap) { |
1083 | rtnl_unlock(); | 1055 | rtnl_unlock(); |
1084 | return -ENOLINK; | 1056 | return -ENOLINK; |
1085 | } | 1057 | } |
1086 | ret = dev_set_mac_address(vlan->dev, &sa); | 1058 | ret = dev_set_mac_address(tap->dev, &sa); |
1087 | tap_put_vlan(vlan); | 1059 | tap_put_tap_dev(tap); |
1088 | rtnl_unlock(); | 1060 | rtnl_unlock(); |
1089 | return ret; | 1061 | return ret; |
1090 | 1062 | ||
@@ -1167,19 +1139,19 @@ struct socket *tap_get_socket(struct file *file) | |||
1167 | } | 1139 | } |
1168 | EXPORT_SYMBOL_GPL(tap_get_socket); | 1140 | EXPORT_SYMBOL_GPL(tap_get_socket); |
1169 | 1141 | ||
1170 | int tap_queue_resize(struct macvlan_dev *vlan) | 1142 | int tap_queue_resize(struct tap_dev *tap) |
1171 | { | 1143 | { |
1172 | struct net_device *dev = vlan->dev; | 1144 | struct net_device *dev = tap->dev; |
1173 | struct tap_queue *q; | 1145 | struct tap_queue *q; |
1174 | struct skb_array **arrays; | 1146 | struct skb_array **arrays; |
1175 | int n = vlan->numqueues; | 1147 | int n = tap->numqueues; |
1176 | int ret, i = 0; | 1148 | int ret, i = 0; |
1177 | 1149 | ||
1178 | arrays = kmalloc(sizeof *arrays * n, GFP_KERNEL); | 1150 | arrays = kmalloc(sizeof *arrays * n, GFP_KERNEL); |
1179 | if (!arrays) | 1151 | if (!arrays) |
1180 | return -ENOMEM; | 1152 | return -ENOMEM; |
1181 | 1153 | ||
1182 | list_for_each_entry(q, &vlan->queue_list, next) | 1154 | list_for_each_entry(q, &tap->queue_list, next) |
1183 | arrays[i++] = &q->skb_array; | 1155 | arrays[i++] = &q->skb_array; |
1184 | 1156 | ||
1185 | ret = skb_array_resize_multiple(arrays, n, | 1157 | ret = skb_array_resize_multiple(arrays, n, |