diff options
author | Jiri Pirko <jpirko@redhat.com> | 2010-06-01 17:52:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-02 10:11:15 -0400 |
commit | ab95bfe01f9872459c8678572ccadbf646badad0 (patch) | |
tree | 8e11f94077c9a80f7af52ce3dd50591a686561d7 /net/bridge/br_input.c | |
parent | 20c59de2e6b6bc74bbf714dcd4e720afe8d516cf (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/bridge/br_input.c')
-rw-r--r-- | net/bridge/br_input.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index d36e700f7a26..99647d8f95c8 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -131,15 +131,19 @@ static inline int is_link_local(const unsigned char *dest) | |||
131 | } | 131 | } |
132 | 132 | ||
133 | /* | 133 | /* |
134 | * Called via br_handle_frame_hook. | ||
135 | * Return NULL if skb is handled | 134 | * Return NULL if skb is handled |
136 | * note: already called with rcu_read_lock (preempt_disabled) | 135 | * note: already called with rcu_read_lock (preempt_disabled) from |
136 | * netif_receive_skb | ||
137 | */ | 137 | */ |
138 | struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb) | 138 | struct sk_buff *br_handle_frame(struct sk_buff *skb) |
139 | { | 139 | { |
140 | struct net_bridge_port *p; | ||
140 | const unsigned char *dest = eth_hdr(skb)->h_dest; | 141 | const unsigned char *dest = eth_hdr(skb)->h_dest; |
141 | int (*rhook)(struct sk_buff *skb); | 142 | int (*rhook)(struct sk_buff *skb); |
142 | 143 | ||
144 | if (skb->pkt_type == PACKET_LOOPBACK) | ||
145 | return skb; | ||
146 | |||
143 | if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) | 147 | if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) |
144 | goto drop; | 148 | goto drop; |
145 | 149 | ||
@@ -147,6 +151,8 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb) | |||
147 | if (!skb) | 151 | if (!skb) |
148 | return NULL; | 152 | return NULL; |
149 | 153 | ||
154 | p = rcu_dereference(skb->dev->br_port); | ||
155 | |||
150 | if (unlikely(is_link_local(dest))) { | 156 | if (unlikely(is_link_local(dest))) { |
151 | /* Pause frames shouldn't be passed up by driver anyway */ | 157 | /* Pause frames shouldn't be passed up by driver anyway */ |
152 | if (skb->protocol == htons(ETH_P_PAUSE)) | 158 | if (skb->protocol == htons(ETH_P_PAUSE)) |