summaryrefslogtreecommitdiffstats
path: root/net/core
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
parent2d7011ca79f1a8792e04d131b8ea21db179ab917 (diff)
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')
-rw-r--r--net/core/dev.c21
-rw-r--r--net/core/skbuff.c1
2 files changed, 14 insertions, 8 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 0d39032e962..0b88eba97da 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,
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 1eb526a848f..801dd08908f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -523,7 +523,6 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
new->ip_summed = old->ip_summed;
skb_copy_queue_mapping(new, old);
new->priority = old->priority;
- new->deliver_no_wcard = old->deliver_no_wcard;
#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
new->ipvs_property = old->ipvs_property;
#endif