aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
authorJiri Pirko <jpirko@redhat.com>2011-03-12 03:14:39 +0000
committerDavid S. Miller <davem@davemloft.net>2011-03-16 12:53:54 -0700
commit8a4eb5734e8d1dc60a8c28576bbbdfdcc643626d (patch)
treeed4cd2f9a2a04a30994a8f8964a81834c895c0c9 /net/core/dev.c
parentbonding: get rid of IFF_SLAVE_INACTIVE netdev->priv_flag (diff)
downloadlinux-dev-8a4eb5734e8d1dc60a8c28576bbbdfdcc643626d.tar.xz
linux-dev-8a4eb5734e8d1dc60a8c28576bbbdfdcc643626d.zip
net: introduce rx_handler results and logic around that
This patch allows rx_handlers to better signalize what to do next to it's caller. That makes skb->deliver_no_wcard no longer needed. kernel-doc for rx_handler_result is taken from Nicolas' patch. Signed-off-by: Jiri Pirko <jpirko@redhat.com> Reviewed-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 0d39032e9621..0b88eba97dab 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3070,6 +3070,8 @@ out:
* on a failure.
*
* The caller must hold the rtnl_mutex.
+ *
+ * For a general description of rx_handler, see enum rx_handler_result.
*/
int netdev_rx_handler_register(struct net_device *dev,
rx_handler_func_t *rx_handler,
@@ -3129,6 +3131,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
rx_handler_func_t *rx_handler;
struct net_device *orig_dev;
struct net_device *null_or_dev;
+ bool deliver_exact = false;
int ret = NET_RX_DROP;
__be16 type;
@@ -3181,18 +3184,22 @@ ncls:
rx_handler = rcu_dereference(skb->dev->rx_handler);
if (rx_handler) {
- struct net_device *prev_dev;
-
if (pt_prev) {
ret = deliver_skb(skb, pt_prev, orig_dev);
pt_prev = NULL;
}
- prev_dev = skb->dev;
- skb = rx_handler(skb);
- if (!skb)
+ switch (rx_handler(&skb)) {
+ case RX_HANDLER_CONSUMED:
goto out;
- if (skb->dev != prev_dev)
+ case RX_HANDLER_ANOTHER:
goto another_round;
+ case RX_HANDLER_EXACT:
+ deliver_exact = true;
+ case RX_HANDLER_PASS:
+ break;
+ default:
+ BUG();
+ }
}
if (vlan_tx_tag_present(skb)) {
@@ -3210,7 +3217,7 @@ ncls:
vlan_on_bond_hook(skb);
/* deliver only exact match when indicated */
- null_or_dev = skb->deliver_no_wcard ? skb->dev : NULL;
+ null_or_dev = deliver_exact ? skb->dev : NULL;
type = skb->protocol;
list_for_each_entry_rcu(ptype,