aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
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 /net/core/dev.c
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 'net/core/dev.c')
-rw-r--r--net/core/dev.c119
1 files changed, 55 insertions, 64 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index ffca5c1066fa..ec01a5998d70 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2604,70 +2604,14 @@ static inline int deliver_skb(struct sk_buff *skb,
2604 return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); 2604 return pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
2605} 2605}
2606 2606
2607#if defined(CONFIG_BRIDGE) || defined (CONFIG_BRIDGE_MODULE) 2607#if (defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)) && \
2608 2608 (defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE))
2609#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
2610/* This hook is defined here for ATM LANE */ 2609/* This hook is defined here for ATM LANE */
2611int (*br_fdb_test_addr_hook)(struct net_device *dev, 2610int (*br_fdb_test_addr_hook)(struct net_device *dev,
2612 unsigned char *addr) __read_mostly; 2611 unsigned char *addr) __read_mostly;
2613EXPORT_SYMBOL_GPL(br_fdb_test_addr_hook); 2612EXPORT_SYMBOL_GPL(br_fdb_test_addr_hook);
2614#endif 2613#endif
2615 2614
2616/*
2617 * If bridge module is loaded call bridging hook.
2618 * returns NULL if packet was consumed.
2619 */
2620struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p,
2621 struct sk_buff *skb) __read_mostly;
2622EXPORT_SYMBOL_GPL(br_handle_frame_hook);
2623
2624static inline struct sk_buff *handle_bridge(struct sk_buff *skb,
2625 struct packet_type **pt_prev, int *ret,
2626 struct net_device *orig_dev)
2627{
2628 struct net_bridge_port *port;
2629
2630 if (skb->pkt_type == PACKET_LOOPBACK ||
2631 (port = rcu_dereference(skb->dev->br_port)) == NULL)
2632 return skb;
2633
2634 if (*pt_prev) {
2635 *ret = deliver_skb(skb, *pt_prev, orig_dev);
2636 *pt_prev = NULL;
2637 }
2638
2639 return br_handle_frame_hook(port, skb);
2640}
2641#else
2642#define handle_bridge(skb, pt_prev, ret, orig_dev) (skb)
2643#endif
2644
2645#if defined(CONFIG_MACVLAN) || defined(CONFIG_MACVLAN_MODULE)
2646struct sk_buff *(*macvlan_handle_frame_hook)(struct macvlan_port *p,
2647 struct sk_buff *skb) __read_mostly;
2648EXPORT_SYMBOL_GPL(macvlan_handle_frame_hook);
2649
2650static inline struct sk_buff *handle_macvlan(struct sk_buff *skb,
2651 struct packet_type **pt_prev,
2652 int *ret,
2653 struct net_device *orig_dev)
2654{
2655 struct macvlan_port *port;
2656
2657 port = rcu_dereference(skb->dev->macvlan_port);
2658 if (!port)
2659 return skb;
2660
2661 if (*pt_prev) {
2662 *ret = deliver_skb(skb, *pt_prev, orig_dev);
2663 *pt_prev = NULL;
2664 }
2665 return macvlan_handle_frame_hook(port, skb);
2666}
2667#else
2668#define handle_macvlan(skb, pt_prev, ret, orig_dev) (skb)
2669#endif
2670
2671#ifdef CONFIG_NET_CLS_ACT 2615#ifdef CONFIG_NET_CLS_ACT
2672/* TODO: Maybe we should just force sch_ingress to be compiled in 2616/* TODO: Maybe we should just force sch_ingress to be compiled in
2673 * when CONFIG_NET_CLS_ACT is? otherwise some useless instructions 2617 * when CONFIG_NET_CLS_ACT is? otherwise some useless instructions
@@ -2763,6 +2707,47 @@ void netif_nit_deliver(struct sk_buff *skb)
2763 rcu_read_unlock(); 2707 rcu_read_unlock();
2764} 2708}
2765 2709
2710/**
2711 * netdev_rx_handler_register - register receive handler
2712 * @dev: device to register a handler for
2713 * @rx_handler: receive handler to register
2714 *
2715 * Register a receive hander for a device. This handler will then be
2716 * called from __netif_receive_skb. A negative errno code is returned
2717 * on a failure.
2718 *
2719 * The caller must hold the rtnl_mutex.
2720 */
2721int netdev_rx_handler_register(struct net_device *dev,
2722 rx_handler_func_t *rx_handler)
2723{
2724 ASSERT_RTNL();
2725
2726 if (dev->rx_handler)
2727 return -EBUSY;
2728
2729 rcu_assign_pointer(dev->rx_handler, rx_handler);
2730
2731 return 0;
2732}
2733EXPORT_SYMBOL_GPL(netdev_rx_handler_register);
2734
2735/**
2736 * netdev_rx_handler_unregister - unregister receive handler
2737 * @dev: device to unregister a handler from
2738 *
2739 * Unregister a receive hander from a device.
2740 *
2741 * The caller must hold the rtnl_mutex.
2742 */
2743void netdev_rx_handler_unregister(struct net_device *dev)
2744{
2745
2746 ASSERT_RTNL();
2747 rcu_assign_pointer(dev->rx_handler, NULL);
2748}
2749EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
2750
2766static inline void skb_bond_set_mac_by_master(struct sk_buff *skb, 2751static inline void skb_bond_set_mac_by_master(struct sk_buff *skb,
2767 struct net_device *master) 2752 struct net_device *master)
2768{ 2753{
@@ -2815,6 +2800,7 @@ EXPORT_SYMBOL(__skb_bond_should_drop);
2815static int __netif_receive_skb(struct sk_buff *skb) 2800static int __netif_receive_skb(struct sk_buff *skb)
2816{ 2801{
2817 struct packet_type *ptype, *pt_prev; 2802 struct packet_type *ptype, *pt_prev;
2803 rx_handler_func_t *rx_handler;
2818 struct net_device *orig_dev; 2804 struct net_device *orig_dev;
2819 struct net_device *master; 2805 struct net_device *master;
2820 struct net_device *null_or_orig; 2806 struct net_device *null_or_orig;
@@ -2877,12 +2863,17 @@ static int __netif_receive_skb(struct sk_buff *skb)
2877ncls: 2863ncls:
2878#endif 2864#endif
2879 2865
2880 skb = handle_bridge(skb, &pt_prev, &ret, orig_dev); 2866 /* Handle special case of bridge or macvlan */
2881 if (!skb) 2867 rx_handler = rcu_dereference(skb->dev->rx_handler);
2882 goto out; 2868 if (rx_handler) {
2883 skb = handle_macvlan(skb, &pt_prev, &ret, orig_dev); 2869 if (pt_prev) {
2884 if (!skb) 2870 ret = deliver_skb(skb, pt_prev, orig_dev);
2885 goto out; 2871 pt_prev = NULL;
2872 }
2873 skb = rx_handler(skb);
2874 if (!skb)
2875 goto out;
2876 }
2886 2877
2887 /* 2878 /*
2888 * Make sure frames received on VLAN interfaces stacked on 2879 * Make sure frames received on VLAN interfaces stacked on