[BRIDGE]: Properly dereference the br_should_route_hook
This hook is protected with the RCU, so simple if (br_should_route_hook) br_should_route_hook(...) is not enough on some architectures. Use the rcu_dereference/rcu_assign_pointer in this case. Fixed Stephen's comment concerning using the typeof(). Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
17efdd4575
commit
82de382ce8
@ -122,6 +122,7 @@ static inline int is_link_local(const unsigned char *dest)
|
||||
struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
|
||||
{
|
||||
const unsigned char *dest = eth_hdr(skb)->h_dest;
|
||||
int (*rhook)(struct sk_buff *skb);
|
||||
|
||||
if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
|
||||
goto drop;
|
||||
@ -147,9 +148,9 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
|
||||
|
||||
switch (p->state) {
|
||||
case BR_STATE_FORWARDING:
|
||||
|
||||
if (br_should_route_hook) {
|
||||
if (br_should_route_hook(skb))
|
||||
rhook = rcu_dereference(br_should_route_hook);
|
||||
if (rhook != NULL) {
|
||||
if (rhook(skb))
|
||||
return skb;
|
||||
dest = eth_hdr(skb)->h_dest;
|
||||
}
|
||||
|
@ -70,13 +70,13 @@ static int __init ebtable_broute_init(void)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* see br_input.c */
|
||||
br_should_route_hook = ebt_broute;
|
||||
rcu_assign_pointer(br_should_route_hook, ebt_broute);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit ebtable_broute_fini(void)
|
||||
{
|
||||
br_should_route_hook = NULL;
|
||||
rcu_assign_pointer(br_should_route_hook, NULL);
|
||||
synchronize_net();
|
||||
ebt_unregister_table(&broute_table);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user