aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
authorJiri Pirko <jpirko@redhat.com>2011-03-11 22:14:39 -0500
committerDavid S. Miller <davem@davemloft.net>2011-03-16 15:53:54 -0400
commit8a4eb5734e8d1dc60a8c28576bbbdfdcc643626d (patch)
treeed4cd2f9a2a04a30994a8f8964a81834c895c0c9 /net/core/dev.c
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/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:
3070 * on a failure. 3070 * on a failure.
3071 * 3071 *
3072 * The caller must hold the rtnl_mutex. 3072 * The caller must hold the rtnl_mutex.
3073 *
3074 * For a general description of rx_handler, see enum rx_handler_result.
3073 */ 3075 */
3074int netdev_rx_handler_register(struct net_device *dev, 3076int netdev_rx_handler_register(struct net_device *dev,
3075 rx_handler_func_t *rx_handler, 3077 rx_handler_func_t *rx_handler,
@@ -3129,6 +3131,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
3129 rx_handler_func_t *rx_handler; 3131 rx_handler_func_t *rx_handler;
3130 struct net_device *orig_dev; 3132 struct net_device *orig_dev;
3131 struct net_device *null_or_dev; 3133 struct net_device *null_or_dev;
3134 bool deliver_exact = false;
3132 int ret = NET_RX_DROP; 3135 int ret = NET_RX_DROP;
3133 __be16 type; 3136 __be16 type;
3134 3137
@@ -3181,18 +3184,22 @@ ncls:
3181 3184
3182 rx_handler = rcu_dereference(skb->dev->rx_handler); 3185 rx_handler = rcu_dereference(skb->dev->rx_handler);
3183 if (rx_handler) { 3186 if (rx_handler) {
3184 struct net_device *prev_dev;
3185
3186 if (pt_prev) { 3187 if (pt_prev) {
3187 ret = deliver_skb(skb, pt_prev, orig_dev); 3188 ret = deliver_skb(skb, pt_prev, orig_dev);
3188 pt_prev = NULL; 3189 pt_prev = NULL;
3189 } 3190 }
3190 prev_dev = skb->dev; 3191 switch (rx_handler(&skb)) {
3191 skb = rx_handler(skb); 3192 case RX_HANDLER_CONSUMED:
3192 if (!skb)
3193 goto out; 3193 goto out;
3194 if (skb->dev != prev_dev) 3194 case RX_HANDLER_ANOTHER:
3195 goto another_round; 3195 goto another_round;
3196 case RX_HANDLER_EXACT:
3197 deliver_exact = true;
3198 case RX_HANDLER_PASS:
3199 break;
3200 default:
3201 BUG();
3202 }
3196 } 3203 }
3197 3204
3198 if (vlan_tx_tag_present(skb)) { 3205 if (vlan_tx_tag_present(skb)) {
@@ -3210,7 +3217,7 @@ ncls:
3210 vlan_on_bond_hook(skb); 3217 vlan_on_bond_hook(skb);
3211 3218
3212 /* deliver only exact match when indicated */ 3219 /* deliver only exact match when indicated */
3213 null_or_dev = skb->deliver_no_wcard ? skb->dev : NULL; 3220 null_or_dev = deliver_exact ? skb->dev : NULL;
3214 3221
3215 type = skb->protocol; 3222 type = skb->protocol;
3216 list_for_each_entry_rcu(ptype, 3223 list_for_each_entry_rcu(ptype,