aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/macvlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/macvlan.c')
-rw-r--r--drivers/net/macvlan.c113
1 files changed, 67 insertions, 46 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 0fc9dc7f20db..6ed577b065df 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -38,6 +38,7 @@ struct macvlan_port {
38 struct hlist_head vlan_hash[MACVLAN_HASH_SIZE]; 38 struct hlist_head vlan_hash[MACVLAN_HASH_SIZE];
39 struct list_head vlans; 39 struct list_head vlans;
40 struct rcu_head rcu; 40 struct rcu_head rcu;
41 bool passthru;
41}; 42};
42 43
43#define macvlan_port_get_rcu(dev) \ 44#define macvlan_port_get_rcu(dev) \
@@ -169,6 +170,7 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
169 macvlan_broadcast(skb, port, NULL, 170 macvlan_broadcast(skb, port, NULL,
170 MACVLAN_MODE_PRIVATE | 171 MACVLAN_MODE_PRIVATE |
171 MACVLAN_MODE_VEPA | 172 MACVLAN_MODE_VEPA |
173 MACVLAN_MODE_PASSTHRU|
172 MACVLAN_MODE_BRIDGE); 174 MACVLAN_MODE_BRIDGE);
173 else if (src->mode == MACVLAN_MODE_VEPA) 175 else if (src->mode == MACVLAN_MODE_VEPA)
174 /* flood to everyone except source */ 176 /* flood to everyone except source */
@@ -185,7 +187,10 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
185 return skb; 187 return skb;
186 } 188 }
187 189
188 vlan = macvlan_hash_lookup(port, eth->h_dest); 190 if (port->passthru)
191 vlan = list_first_entry(&port->vlans, struct macvlan_dev, list);
192 else
193 vlan = macvlan_hash_lookup(port, eth->h_dest);
189 if (vlan == NULL) 194 if (vlan == NULL)
190 return skb; 195 return skb;
191 196
@@ -243,18 +248,22 @@ xmit_world:
243netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, 248netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
244 struct net_device *dev) 249 struct net_device *dev)
245{ 250{
246 int i = skb_get_queue_mapping(skb);
247 struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
248 unsigned int len = skb->len; 251 unsigned int len = skb->len;
249 int ret; 252 int ret;
253 const struct macvlan_dev *vlan = netdev_priv(dev);
250 254
251 ret = macvlan_queue_xmit(skb, dev); 255 ret = macvlan_queue_xmit(skb, dev);
252 if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { 256 if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
253 txq->tx_packets++; 257 struct macvlan_pcpu_stats *pcpu_stats;
254 txq->tx_bytes += len;
255 } else
256 txq->tx_dropped++;
257 258
259 pcpu_stats = this_cpu_ptr(vlan->pcpu_stats);
260 u64_stats_update_begin(&pcpu_stats->syncp);
261 pcpu_stats->tx_packets++;
262 pcpu_stats->tx_bytes += len;
263 u64_stats_update_end(&pcpu_stats->syncp);
264 } else {
265 this_cpu_inc(vlan->pcpu_stats->tx_dropped);
266 }
258 return ret; 267 return ret;
259} 268}
260EXPORT_SYMBOL_GPL(macvlan_start_xmit); 269EXPORT_SYMBOL_GPL(macvlan_start_xmit);
@@ -284,6 +293,11 @@ static int macvlan_open(struct net_device *dev)
284 struct net_device *lowerdev = vlan->lowerdev; 293 struct net_device *lowerdev = vlan->lowerdev;
285 int err; 294 int err;
286 295
296 if (vlan->port->passthru) {
297 dev_set_promiscuity(lowerdev, 1);
298 goto hash_add;
299 }
300
287 err = -EBUSY; 301 err = -EBUSY;
288 if (macvlan_addr_busy(vlan->port, dev->dev_addr)) 302 if (macvlan_addr_busy(vlan->port, dev->dev_addr))
289 goto out; 303 goto out;
@@ -296,6 +310,8 @@ static int macvlan_open(struct net_device *dev)
296 if (err < 0) 310 if (err < 0)
297 goto del_unicast; 311 goto del_unicast;
298 } 312 }
313
314hash_add:
299 macvlan_hash_add(vlan); 315 macvlan_hash_add(vlan);
300 return 0; 316 return 0;
301 317
@@ -310,12 +326,18 @@ static int macvlan_stop(struct net_device *dev)
310 struct macvlan_dev *vlan = netdev_priv(dev); 326 struct macvlan_dev *vlan = netdev_priv(dev);
311 struct net_device *lowerdev = vlan->lowerdev; 327 struct net_device *lowerdev = vlan->lowerdev;
312 328
329 if (vlan->port->passthru) {
330 dev_set_promiscuity(lowerdev, -1);
331 goto hash_del;
332 }
333
313 dev_mc_unsync(lowerdev, dev); 334 dev_mc_unsync(lowerdev, dev);
314 if (dev->flags & IFF_ALLMULTI) 335 if (dev->flags & IFF_ALLMULTI)
315 dev_set_allmulti(lowerdev, -1); 336 dev_set_allmulti(lowerdev, -1);
316 337
317 dev_uc_del(lowerdev, dev->dev_addr); 338 dev_uc_del(lowerdev, dev->dev_addr);
318 339
340hash_del:
319 macvlan_hash_del(vlan); 341 macvlan_hash_del(vlan);
320 return 0; 342 return 0;
321} 343}
@@ -414,14 +436,15 @@ static int macvlan_init(struct net_device *dev)
414 dev->state = (dev->state & ~MACVLAN_STATE_MASK) | 436 dev->state = (dev->state & ~MACVLAN_STATE_MASK) |
415 (lowerdev->state & MACVLAN_STATE_MASK); 437 (lowerdev->state & MACVLAN_STATE_MASK);
416 dev->features = lowerdev->features & MACVLAN_FEATURES; 438 dev->features = lowerdev->features & MACVLAN_FEATURES;
439 dev->features |= NETIF_F_LLTX;
417 dev->gso_max_size = lowerdev->gso_max_size; 440 dev->gso_max_size = lowerdev->gso_max_size;
418 dev->iflink = lowerdev->ifindex; 441 dev->iflink = lowerdev->ifindex;
419 dev->hard_header_len = lowerdev->hard_header_len; 442 dev->hard_header_len = lowerdev->hard_header_len;
420 443
421 macvlan_set_lockdep_class(dev); 444 macvlan_set_lockdep_class(dev);
422 445
423 vlan->rx_stats = alloc_percpu(struct macvlan_rx_stats); 446 vlan->pcpu_stats = alloc_percpu(struct macvlan_pcpu_stats);
424 if (!vlan->rx_stats) 447 if (!vlan->pcpu_stats)
425 return -ENOMEM; 448 return -ENOMEM;
426 449
427 return 0; 450 return 0;
@@ -431,7 +454,7 @@ static void macvlan_uninit(struct net_device *dev)
431{ 454{
432 struct macvlan_dev *vlan = netdev_priv(dev); 455 struct macvlan_dev *vlan = netdev_priv(dev);
433 456
434 free_percpu(vlan->rx_stats); 457 free_percpu(vlan->pcpu_stats);
435} 458}
436 459
437static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev, 460static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev,
@@ -439,33 +462,38 @@ static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev,
439{ 462{
440 struct macvlan_dev *vlan = netdev_priv(dev); 463 struct macvlan_dev *vlan = netdev_priv(dev);
441 464
442 dev_txq_stats_fold(dev, stats); 465 if (vlan->pcpu_stats) {
443 466 struct macvlan_pcpu_stats *p;
444 if (vlan->rx_stats) { 467 u64 rx_packets, rx_bytes, rx_multicast, tx_packets, tx_bytes;
445 struct macvlan_rx_stats *p, accum = {0}; 468 u32 rx_errors = 0, tx_dropped = 0;
446 u64 rx_packets, rx_bytes, rx_multicast;
447 unsigned int start; 469 unsigned int start;
448 int i; 470 int i;
449 471
450 for_each_possible_cpu(i) { 472 for_each_possible_cpu(i) {
451 p = per_cpu_ptr(vlan->rx_stats, i); 473 p = per_cpu_ptr(vlan->pcpu_stats, i);
452 do { 474 do {
453 start = u64_stats_fetch_begin_bh(&p->syncp); 475 start = u64_stats_fetch_begin_bh(&p->syncp);
454 rx_packets = p->rx_packets; 476 rx_packets = p->rx_packets;
455 rx_bytes = p->rx_bytes; 477 rx_bytes = p->rx_bytes;
456 rx_multicast = p->rx_multicast; 478 rx_multicast = p->rx_multicast;
479 tx_packets = p->tx_packets;
480 tx_bytes = p->tx_bytes;
457 } while (u64_stats_fetch_retry_bh(&p->syncp, start)); 481 } while (u64_stats_fetch_retry_bh(&p->syncp, start));
458 accum.rx_packets += rx_packets; 482
459 accum.rx_bytes += rx_bytes; 483 stats->rx_packets += rx_packets;
460 accum.rx_multicast += rx_multicast; 484 stats->rx_bytes += rx_bytes;
461 /* rx_errors is an ulong, updated without syncp protection */ 485 stats->multicast += rx_multicast;
462 accum.rx_errors += p->rx_errors; 486 stats->tx_packets += tx_packets;
487 stats->tx_bytes += tx_bytes;
488 /* rx_errors & tx_dropped are u32, updated
489 * without syncp protection.
490 */
491 rx_errors += p->rx_errors;
492 tx_dropped += p->tx_dropped;
463 } 493 }
464 stats->rx_packets = accum.rx_packets; 494 stats->rx_errors = rx_errors;
465 stats->rx_bytes = accum.rx_bytes; 495 stats->rx_dropped = rx_errors;
466 stats->rx_errors = accum.rx_errors; 496 stats->tx_dropped = tx_dropped;
467 stats->rx_dropped = accum.rx_errors;
468 stats->multicast = accum.rx_multicast;
469 } 497 }
470 return stats; 498 return stats;
471} 499}
@@ -549,6 +577,7 @@ static int macvlan_port_create(struct net_device *dev)
549 if (port == NULL) 577 if (port == NULL)
550 return -ENOMEM; 578 return -ENOMEM;
551 579
580 port->passthru = false;
552 port->dev = dev; 581 port->dev = dev;
553 INIT_LIST_HEAD(&port->vlans); 582 INIT_LIST_HEAD(&port->vlans);
554 for (i = 0; i < MACVLAN_HASH_SIZE; i++) 583 for (i = 0; i < MACVLAN_HASH_SIZE; i++)
@@ -593,6 +622,7 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
593 case MACVLAN_MODE_PRIVATE: 622 case MACVLAN_MODE_PRIVATE:
594 case MACVLAN_MODE_VEPA: 623 case MACVLAN_MODE_VEPA:
595 case MACVLAN_MODE_BRIDGE: 624 case MACVLAN_MODE_BRIDGE:
625 case MACVLAN_MODE_PASSTHRU:
596 break; 626 break;
597 default: 627 default:
598 return -EINVAL; 628 return -EINVAL;
@@ -601,25 +631,6 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
601 return 0; 631 return 0;
602} 632}
603 633
604static int macvlan_get_tx_queues(struct net *net,
605 struct nlattr *tb[],
606 unsigned int *num_tx_queues,
607 unsigned int *real_num_tx_queues)
608{
609 struct net_device *real_dev;
610
611 if (!tb[IFLA_LINK])
612 return -EINVAL;
613
614 real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK]));
615 if (!real_dev)
616 return -ENODEV;
617
618 *num_tx_queues = real_dev->num_tx_queues;
619 *real_num_tx_queues = real_dev->real_num_tx_queues;
620 return 0;
621}
622
623int macvlan_common_newlink(struct net *src_net, struct net_device *dev, 634int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
624 struct nlattr *tb[], struct nlattr *data[], 635 struct nlattr *tb[], struct nlattr *data[],
625 int (*receive)(struct sk_buff *skb), 636 int (*receive)(struct sk_buff *skb),
@@ -661,6 +672,10 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
661 } 672 }
662 port = macvlan_port_get(lowerdev); 673 port = macvlan_port_get(lowerdev);
663 674
675 /* Only 1 macvlan device can be created in passthru mode */
676 if (port->passthru)
677 return -EINVAL;
678
664 vlan->lowerdev = lowerdev; 679 vlan->lowerdev = lowerdev;
665 vlan->dev = dev; 680 vlan->dev = dev;
666 vlan->port = port; 681 vlan->port = port;
@@ -671,6 +686,13 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
671 if (data && data[IFLA_MACVLAN_MODE]) 686 if (data && data[IFLA_MACVLAN_MODE])
672 vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]); 687 vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
673 688
689 if (vlan->mode == MACVLAN_MODE_PASSTHRU) {
690 if (!list_empty(&port->vlans))
691 return -EINVAL;
692 port->passthru = true;
693 memcpy(dev->dev_addr, lowerdev->dev_addr, ETH_ALEN);
694 }
695
674 err = register_netdevice(dev); 696 err = register_netdevice(dev);
675 if (err < 0) 697 if (err < 0)
676 goto destroy_port; 698 goto destroy_port;
@@ -743,7 +765,6 @@ int macvlan_link_register(struct rtnl_link_ops *ops)
743{ 765{
744 /* common fields */ 766 /* common fields */
745 ops->priv_size = sizeof(struct macvlan_dev); 767 ops->priv_size = sizeof(struct macvlan_dev);
746 ops->get_tx_queues = macvlan_get_tx_queues;
747 ops->validate = macvlan_validate; 768 ops->validate = macvlan_validate;
748 ops->maxtype = IFLA_MACVLAN_MAX; 769 ops->maxtype = IFLA_MACVLAN_MAX;
749 ops->policy = macvlan_policy; 770 ops->policy = macvlan_policy;