aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJiri Pirko <jpirko@redhat.com>2010-06-01 17:52:08 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-02 10:11:15 -0400
commitab95bfe01f9872459c8678572ccadbf646badad0 (patch)
tree8e11f94077c9a80f7af52ce3dd50591a686561d7 /drivers
parent20c59de2e6b6bc74bbf714dcd4e720afe8d516cf (diff)
net: replace hooks in __netif_receive_skb V5
What this patch does is it removes two receive frame hooks (for bridge and for macvlan) from __netif_receive_skb. These are replaced them with a single hook for both. It only supports one hook per device because it makes no sense to do bridging and macvlan on the same device. Then a network driver (of virtual netdev like macvlan or bridge) can register an rx_handler for needed net device. Signed-off-by: Jiri Pirko <jpirko@redhat.com> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/macvlan.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 87e8d4cb4057..53422ce26f7f 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -145,15 +145,16 @@ static void macvlan_broadcast(struct sk_buff *skb,
145} 145}
146 146
147/* called under rcu_read_lock() from netif_receive_skb */ 147/* called under rcu_read_lock() from netif_receive_skb */
148static struct sk_buff *macvlan_handle_frame(struct macvlan_port *port, 148static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
149 struct sk_buff *skb)
150{ 149{
150 struct macvlan_port *port;
151 const struct ethhdr *eth = eth_hdr(skb); 151 const struct ethhdr *eth = eth_hdr(skb);
152 const struct macvlan_dev *vlan; 152 const struct macvlan_dev *vlan;
153 const struct macvlan_dev *src; 153 const struct macvlan_dev *src;
154 struct net_device *dev; 154 struct net_device *dev;
155 unsigned int len; 155 unsigned int len;
156 156
157 port = rcu_dereference(skb->dev->macvlan_port);
157 if (is_multicast_ether_addr(eth->h_dest)) { 158 if (is_multicast_ether_addr(eth->h_dest)) {
158 src = macvlan_hash_lookup(port, eth->h_source); 159 src = macvlan_hash_lookup(port, eth->h_source);
159 if (!src) 160 if (!src)
@@ -515,6 +516,7 @@ static int macvlan_port_create(struct net_device *dev)
515{ 516{
516 struct macvlan_port *port; 517 struct macvlan_port *port;
517 unsigned int i; 518 unsigned int i;
519 int err;
518 520
519 if (dev->type != ARPHRD_ETHER || dev->flags & IFF_LOOPBACK) 521 if (dev->type != ARPHRD_ETHER || dev->flags & IFF_LOOPBACK)
520 return -EINVAL; 522 return -EINVAL;
@@ -528,13 +530,21 @@ static int macvlan_port_create(struct net_device *dev)
528 for (i = 0; i < MACVLAN_HASH_SIZE; i++) 530 for (i = 0; i < MACVLAN_HASH_SIZE; i++)
529 INIT_HLIST_HEAD(&port->vlan_hash[i]); 531 INIT_HLIST_HEAD(&port->vlan_hash[i]);
530 rcu_assign_pointer(dev->macvlan_port, port); 532 rcu_assign_pointer(dev->macvlan_port, port);
531 return 0; 533
534 err = netdev_rx_handler_register(dev, macvlan_handle_frame);
535 if (err) {
536 rcu_assign_pointer(dev->macvlan_port, NULL);
537 kfree(port);
538 }
539
540 return err;
532} 541}
533 542
534static void macvlan_port_destroy(struct net_device *dev) 543static void macvlan_port_destroy(struct net_device *dev)
535{ 544{
536 struct macvlan_port *port = dev->macvlan_port; 545 struct macvlan_port *port = dev->macvlan_port;
537 546
547 netdev_rx_handler_unregister(dev);
538 rcu_assign_pointer(dev->macvlan_port, NULL); 548 rcu_assign_pointer(dev->macvlan_port, NULL);
539 synchronize_rcu(); 549 synchronize_rcu();
540 kfree(port); 550 kfree(port);
@@ -767,14 +777,12 @@ static int __init macvlan_init_module(void)
767 int err; 777 int err;
768 778
769 register_netdevice_notifier(&macvlan_notifier_block); 779 register_netdevice_notifier(&macvlan_notifier_block);
770 macvlan_handle_frame_hook = macvlan_handle_frame;
771 780
772 err = macvlan_link_register(&macvlan_link_ops); 781 err = macvlan_link_register(&macvlan_link_ops);
773 if (err < 0) 782 if (err < 0)
774 goto err1; 783 goto err1;
775 return 0; 784 return 0;
776err1: 785err1:
777 macvlan_handle_frame_hook = NULL;
778 unregister_netdevice_notifier(&macvlan_notifier_block); 786 unregister_netdevice_notifier(&macvlan_notifier_block);
779 return err; 787 return err;
780} 788}
@@ -782,7 +790,6 @@ err1:
782static void __exit macvlan_cleanup_module(void) 790static void __exit macvlan_cleanup_module(void)
783{ 791{
784 rtnl_link_unregister(&macvlan_link_ops); 792 rtnl_link_unregister(&macvlan_link_ops);
785 macvlan_handle_frame_hook = NULL;
786 unregister_netdevice_notifier(&macvlan_notifier_block); 793 unregister_netdevice_notifier(&macvlan_notifier_block);
787} 794}
788 795