summaryrefslogtreecommitdiffstats
path: root/drivers/net/macvlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/macvlan.c')
-rw-r--r--drivers/net/macvlan.c105
1 files changed, 71 insertions, 34 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 87e8d4cb4057..0ef0eb0db945 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -37,8 +37,14 @@ struct macvlan_port {
37 struct net_device *dev; 37 struct net_device *dev;
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}; 41};
41 42
43#define macvlan_port_get_rcu(dev) \
44 ((struct macvlan_port *) rcu_dereference(dev->rx_handler_data))
45#define macvlan_port_get(dev) ((struct macvlan_port *) dev->rx_handler_data)
46#define macvlan_port_exists(dev) (dev->priv_flags & IFF_MACVLAN_PORT)
47
42static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port, 48static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port,
43 const unsigned char *addr) 49 const unsigned char *addr)
44{ 50{
@@ -145,15 +151,17 @@ static void macvlan_broadcast(struct sk_buff *skb,
145} 151}
146 152
147/* called under rcu_read_lock() from netif_receive_skb */ 153/* called under rcu_read_lock() from netif_receive_skb */
148static struct sk_buff *macvlan_handle_frame(struct macvlan_port *port, 154static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
149 struct sk_buff *skb)
150{ 155{
156 struct macvlan_port *port;
151 const struct ethhdr *eth = eth_hdr(skb); 157 const struct ethhdr *eth = eth_hdr(skb);
152 const struct macvlan_dev *vlan; 158 const struct macvlan_dev *vlan;
153 const struct macvlan_dev *src; 159 const struct macvlan_dev *src;
154 struct net_device *dev; 160 struct net_device *dev;
155 unsigned int len; 161 unsigned int len = 0;
162 int ret = NET_RX_DROP;
156 163
164 port = macvlan_port_get_rcu(skb->dev);
157 if (is_multicast_ether_addr(eth->h_dest)) { 165 if (is_multicast_ether_addr(eth->h_dest)) {
158 src = macvlan_hash_lookup(port, eth->h_source); 166 src = macvlan_hash_lookup(port, eth->h_source);
159 if (!src) 167 if (!src)
@@ -188,14 +196,16 @@ static struct sk_buff *macvlan_handle_frame(struct macvlan_port *port,
188 } 196 }
189 len = skb->len + ETH_HLEN; 197 len = skb->len + ETH_HLEN;
190 skb = skb_share_check(skb, GFP_ATOMIC); 198 skb = skb_share_check(skb, GFP_ATOMIC);
191 macvlan_count_rx(vlan, len, skb != NULL, 0);
192 if (!skb) 199 if (!skb)
193 return NULL; 200 goto out;
194 201
195 skb->dev = dev; 202 skb->dev = dev;
196 skb->pkt_type = PACKET_HOST; 203 skb->pkt_type = PACKET_HOST;
197 204
198 vlan->receive(skb); 205 ret = vlan->receive(skb);
206
207out:
208 macvlan_count_rx(vlan, len, ret == NET_RX_SUCCESS, 0);
199 return NULL; 209 return NULL;
200} 210}
201 211
@@ -424,29 +434,38 @@ static void macvlan_uninit(struct net_device *dev)
424 free_percpu(vlan->rx_stats); 434 free_percpu(vlan->rx_stats);
425} 435}
426 436
427static struct net_device_stats *macvlan_dev_get_stats(struct net_device *dev) 437static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev,
438 struct rtnl_link_stats64 *stats)
428{ 439{
429 struct net_device_stats *stats = &dev->stats;
430 struct macvlan_dev *vlan = netdev_priv(dev); 440 struct macvlan_dev *vlan = netdev_priv(dev);
431 441
432 dev_txq_stats_fold(dev, stats); 442 dev_txq_stats_fold(dev, stats);
433 443
434 if (vlan->rx_stats) { 444 if (vlan->rx_stats) {
435 struct macvlan_rx_stats *p, rx = {0}; 445 struct macvlan_rx_stats *p, accum = {0};
446 u64 rx_packets, rx_bytes, rx_multicast;
447 unsigned int start;
436 int i; 448 int i;
437 449
438 for_each_possible_cpu(i) { 450 for_each_possible_cpu(i) {
439 p = per_cpu_ptr(vlan->rx_stats, i); 451 p = per_cpu_ptr(vlan->rx_stats, i);
440 rx.rx_packets += p->rx_packets; 452 do {
441 rx.rx_bytes += p->rx_bytes; 453 start = u64_stats_fetch_begin_bh(&p->syncp);
442 rx.rx_errors += p->rx_errors; 454 rx_packets = p->rx_packets;
443 rx.multicast += p->multicast; 455 rx_bytes = p->rx_bytes;
456 rx_multicast = p->rx_multicast;
457 } while (u64_stats_fetch_retry_bh(&p->syncp, start));
458 accum.rx_packets += rx_packets;
459 accum.rx_bytes += rx_bytes;
460 accum.rx_multicast += rx_multicast;
461 /* rx_errors is an ulong, updated without syncp protection */
462 accum.rx_errors += p->rx_errors;
444 } 463 }
445 stats->rx_packets = rx.rx_packets; 464 stats->rx_packets = accum.rx_packets;
446 stats->rx_bytes = rx.rx_bytes; 465 stats->rx_bytes = accum.rx_bytes;
447 stats->rx_errors = rx.rx_errors; 466 stats->rx_errors = accum.rx_errors;
448 stats->rx_dropped = rx.rx_errors; 467 stats->rx_dropped = accum.rx_errors;
449 stats->multicast = rx.multicast; 468 stats->multicast = accum.rx_multicast;
450 } 469 }
451 return stats; 470 return stats;
452} 471}
@@ -495,11 +514,11 @@ static const struct net_device_ops macvlan_netdev_ops = {
495 .ndo_change_rx_flags = macvlan_change_rx_flags, 514 .ndo_change_rx_flags = macvlan_change_rx_flags,
496 .ndo_set_mac_address = macvlan_set_mac_address, 515 .ndo_set_mac_address = macvlan_set_mac_address,
497 .ndo_set_multicast_list = macvlan_set_multicast_list, 516 .ndo_set_multicast_list = macvlan_set_multicast_list,
498 .ndo_get_stats = macvlan_dev_get_stats, 517 .ndo_get_stats64 = macvlan_dev_get_stats64,
499 .ndo_validate_addr = eth_validate_addr, 518 .ndo_validate_addr = eth_validate_addr,
500}; 519};
501 520
502static void macvlan_setup(struct net_device *dev) 521void macvlan_common_setup(struct net_device *dev)
503{ 522{
504 ether_setup(dev); 523 ether_setup(dev);
505 524
@@ -508,6 +527,12 @@ static void macvlan_setup(struct net_device *dev)
508 dev->destructor = free_netdev; 527 dev->destructor = free_netdev;
509 dev->header_ops = &macvlan_hard_header_ops, 528 dev->header_ops = &macvlan_hard_header_ops,
510 dev->ethtool_ops = &macvlan_ethtool_ops; 529 dev->ethtool_ops = &macvlan_ethtool_ops;
530}
531EXPORT_SYMBOL_GPL(macvlan_common_setup);
532
533static void macvlan_setup(struct net_device *dev)
534{
535 macvlan_common_setup(dev);
511 dev->tx_queue_len = 0; 536 dev->tx_queue_len = 0;
512} 537}
513 538
@@ -515,6 +540,7 @@ static int macvlan_port_create(struct net_device *dev)
515{ 540{
516 struct macvlan_port *port; 541 struct macvlan_port *port;
517 unsigned int i; 542 unsigned int i;
543 int err;
518 544
519 if (dev->type != ARPHRD_ETHER || dev->flags & IFF_LOOPBACK) 545 if (dev->type != ARPHRD_ETHER || dev->flags & IFF_LOOPBACK)
520 return -EINVAL; 546 return -EINVAL;
@@ -527,19 +553,32 @@ static int macvlan_port_create(struct net_device *dev)
527 INIT_LIST_HEAD(&port->vlans); 553 INIT_LIST_HEAD(&port->vlans);
528 for (i = 0; i < MACVLAN_HASH_SIZE; i++) 554 for (i = 0; i < MACVLAN_HASH_SIZE; i++)
529 INIT_HLIST_HEAD(&port->vlan_hash[i]); 555 INIT_HLIST_HEAD(&port->vlan_hash[i]);
530 rcu_assign_pointer(dev->macvlan_port, port); 556
531 return 0; 557 err = netdev_rx_handler_register(dev, macvlan_handle_frame, port);
558 if (err)
559 kfree(port);
560
561 dev->priv_flags |= IFF_MACVLAN_PORT;
562 return err;
532} 563}
533 564
534static void macvlan_port_destroy(struct net_device *dev) 565static void macvlan_port_rcu_free(struct rcu_head *head)
535{ 566{
536 struct macvlan_port *port = dev->macvlan_port; 567 struct macvlan_port *port;
537 568
538 rcu_assign_pointer(dev->macvlan_port, NULL); 569 port = container_of(head, struct macvlan_port, rcu);
539 synchronize_rcu();
540 kfree(port); 570 kfree(port);
541} 571}
542 572
573static void macvlan_port_destroy(struct net_device *dev)
574{
575 struct macvlan_port *port = macvlan_port_get(dev);
576
577 dev->priv_flags &= ~IFF_MACVLAN_PORT;
578 netdev_rx_handler_unregister(dev);
579 call_rcu(&port->rcu, macvlan_port_rcu_free);
580}
581
543static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[]) 582static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
544{ 583{
545 if (tb[IFLA_ADDRESS]) { 584 if (tb[IFLA_ADDRESS]) {
@@ -615,12 +654,12 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
615 if (!tb[IFLA_ADDRESS]) 654 if (!tb[IFLA_ADDRESS])
616 random_ether_addr(dev->dev_addr); 655 random_ether_addr(dev->dev_addr);
617 656
618 if (lowerdev->macvlan_port == NULL) { 657 if (!macvlan_port_exists(lowerdev)) {
619 err = macvlan_port_create(lowerdev); 658 err = macvlan_port_create(lowerdev);
620 if (err < 0) 659 if (err < 0)
621 return err; 660 return err;
622 } 661 }
623 port = lowerdev->macvlan_port; 662 port = macvlan_port_get(lowerdev);
624 663
625 vlan->lowerdev = lowerdev; 664 vlan->lowerdev = lowerdev;
626 vlan->dev = dev; 665 vlan->dev = dev;
@@ -705,7 +744,6 @@ int macvlan_link_register(struct rtnl_link_ops *ops)
705 /* common fields */ 744 /* common fields */
706 ops->priv_size = sizeof(struct macvlan_dev); 745 ops->priv_size = sizeof(struct macvlan_dev);
707 ops->get_tx_queues = macvlan_get_tx_queues; 746 ops->get_tx_queues = macvlan_get_tx_queues;
708 ops->setup = macvlan_setup;
709 ops->validate = macvlan_validate; 747 ops->validate = macvlan_validate;
710 ops->maxtype = IFLA_MACVLAN_MAX; 748 ops->maxtype = IFLA_MACVLAN_MAX;
711 ops->policy = macvlan_policy; 749 ops->policy = macvlan_policy;
@@ -719,6 +757,7 @@ EXPORT_SYMBOL_GPL(macvlan_link_register);
719 757
720static struct rtnl_link_ops macvlan_link_ops = { 758static struct rtnl_link_ops macvlan_link_ops = {
721 .kind = "macvlan", 759 .kind = "macvlan",
760 .setup = macvlan_setup,
722 .newlink = macvlan_newlink, 761 .newlink = macvlan_newlink,
723 .dellink = macvlan_dellink, 762 .dellink = macvlan_dellink,
724}; 763};
@@ -730,10 +769,11 @@ static int macvlan_device_event(struct notifier_block *unused,
730 struct macvlan_dev *vlan, *next; 769 struct macvlan_dev *vlan, *next;
731 struct macvlan_port *port; 770 struct macvlan_port *port;
732 771
733 port = dev->macvlan_port; 772 if (!macvlan_port_exists(dev))
734 if (port == NULL)
735 return NOTIFY_DONE; 773 return NOTIFY_DONE;
736 774
775 port = macvlan_port_get(dev);
776
737 switch (event) { 777 switch (event) {
738 case NETDEV_CHANGE: 778 case NETDEV_CHANGE:
739 list_for_each_entry(vlan, &port->vlans, list) 779 list_for_each_entry(vlan, &port->vlans, list)
@@ -767,14 +807,12 @@ static int __init macvlan_init_module(void)
767 int err; 807 int err;
768 808
769 register_netdevice_notifier(&macvlan_notifier_block); 809 register_netdevice_notifier(&macvlan_notifier_block);
770 macvlan_handle_frame_hook = macvlan_handle_frame;
771 810
772 err = macvlan_link_register(&macvlan_link_ops); 811 err = macvlan_link_register(&macvlan_link_ops);
773 if (err < 0) 812 if (err < 0)
774 goto err1; 813 goto err1;
775 return 0; 814 return 0;
776err1: 815err1:
777 macvlan_handle_frame_hook = NULL;
778 unregister_netdevice_notifier(&macvlan_notifier_block); 816 unregister_netdevice_notifier(&macvlan_notifier_block);
779 return err; 817 return err;
780} 818}
@@ -782,7 +820,6 @@ err1:
782static void __exit macvlan_cleanup_module(void) 820static void __exit macvlan_cleanup_module(void)
783{ 821{
784 rtnl_link_unregister(&macvlan_link_ops); 822 rtnl_link_unregister(&macvlan_link_ops);
785 macvlan_handle_frame_hook = NULL;
786 unregister_netdevice_notifier(&macvlan_notifier_block); 823 unregister_netdevice_notifier(&macvlan_notifier_block);
787} 824}
788 825