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/bridge/br_input.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/bridge/br_input.c')
-rw-r--r-- | net/bridge/br_input.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 88e4aa9cb1f9..e2160792e1bc 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -139,21 +139,22 @@ static inline int is_link_local(const unsigned char *dest) | |||
139 | * Return NULL if skb is handled | 139 | * Return NULL if skb is handled |
140 | * note: already called with rcu_read_lock | 140 | * note: already called with rcu_read_lock |
141 | */ | 141 | */ |
142 | struct sk_buff *br_handle_frame(struct sk_buff *skb) | 142 | rx_handler_result_t br_handle_frame(struct sk_buff **pskb) |
143 | { | 143 | { |
144 | struct net_bridge_port *p; | 144 | struct net_bridge_port *p; |
145 | struct sk_buff *skb = *pskb; | ||
145 | const unsigned char *dest = eth_hdr(skb)->h_dest; | 146 | const unsigned char *dest = eth_hdr(skb)->h_dest; |
146 | br_should_route_hook_t *rhook; | 147 | br_should_route_hook_t *rhook; |
147 | 148 | ||
148 | if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) | 149 | if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) |
149 | return skb; | 150 | return RX_HANDLER_PASS; |
150 | 151 | ||
151 | if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) | 152 | if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) |
152 | goto drop; | 153 | goto drop; |
153 | 154 | ||
154 | skb = skb_share_check(skb, GFP_ATOMIC); | 155 | skb = skb_share_check(skb, GFP_ATOMIC); |
155 | if (!skb) | 156 | if (!skb) |
156 | return NULL; | 157 | return RX_HANDLER_CONSUMED; |
157 | 158 | ||
158 | p = br_port_get_rcu(skb->dev); | 159 | p = br_port_get_rcu(skb->dev); |
159 | 160 | ||
@@ -167,10 +168,12 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb) | |||
167 | goto forward; | 168 | goto forward; |
168 | 169 | ||
169 | if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, | 170 | if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, |
170 | NULL, br_handle_local_finish)) | 171 | NULL, br_handle_local_finish)) { |
171 | return NULL; /* frame consumed by filter */ | 172 | return RX_HANDLER_CONSUMED; /* consumed by filter */ |
172 | else | 173 | } else { |
173 | return skb; /* continue processing */ | 174 | *pskb = skb; |
175 | return RX_HANDLER_PASS; /* continue processing */ | ||
176 | } | ||
174 | } | 177 | } |
175 | 178 | ||
176 | forward: | 179 | forward: |
@@ -178,8 +181,10 @@ forward: | |||
178 | case BR_STATE_FORWARDING: | 181 | case BR_STATE_FORWARDING: |
179 | rhook = rcu_dereference(br_should_route_hook); | 182 | rhook = rcu_dereference(br_should_route_hook); |
180 | if (rhook) { | 183 | if (rhook) { |
181 | if ((*rhook)(skb)) | 184 | if ((*rhook)(skb)) { |
182 | return skb; | 185 | *pskb = skb; |
186 | return RX_HANDLER_PASS; | ||
187 | } | ||
183 | dest = eth_hdr(skb)->h_dest; | 188 | dest = eth_hdr(skb)->h_dest; |
184 | } | 189 | } |
185 | /* fall through */ | 190 | /* fall through */ |
@@ -194,5 +199,5 @@ forward: | |||
194 | drop: | 199 | drop: |
195 | kfree_skb(skb); | 200 | kfree_skb(skb); |
196 | } | 201 | } |
197 | return NULL; | 202 | return RX_HANDLER_CONSUMED; |
198 | } | 203 | } |