diff options
author | Jiri Pirko <jpirko@redhat.com> | 2011-03-11 22:14:39 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-03-16 15:53:54 -0400 |
commit | 8a4eb5734e8d1dc60a8c28576bbbdfdcc643626d (patch) | |
tree | ed4cd2f9a2a04a30994a8f8964a81834c895c0c9 /net/core/dev.c | |
parent | 2d7011ca79f1a8792e04d131b8ea21db179ab917 (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.c | 21 |
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 | */ |
3074 | int netdev_rx_handler_register(struct net_device *dev, | 3076 | int 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, |