bridge: add proper RCU annotation to should_route_hook
Add br_should_route_hook_t typedef, this is the only way we can get a clean RCU implementation for function pointer. Move route_hook to location where it is used. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e805168800
commit
a386f99025
|
@ -102,7 +102,9 @@ struct __fdb_entry {
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
|
|
||||||
extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
|
extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
|
||||||
extern int (*br_should_route_hook)(struct sk_buff *skb);
|
|
||||||
|
typedef int (*br_should_route_hook_t)(struct sk_buff *skb);
|
||||||
|
extern br_should_route_hook_t __rcu *br_should_route_hook;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,6 @@
|
||||||
|
|
||||||
#include "br_private.h"
|
#include "br_private.h"
|
||||||
|
|
||||||
int (*br_should_route_hook)(struct sk_buff *skb);
|
|
||||||
|
|
||||||
static const struct stp_proto br_stp_proto = {
|
static const struct stp_proto br_stp_proto = {
|
||||||
.rcv = br_stp_rcv,
|
.rcv = br_stp_rcv,
|
||||||
};
|
};
|
||||||
|
@ -102,8 +100,6 @@ static void __exit br_deinit(void)
|
||||||
br_fdb_fini();
|
br_fdb_fini();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(br_should_route_hook);
|
|
||||||
|
|
||||||
module_init(br_init)
|
module_init(br_init)
|
||||||
module_exit(br_deinit)
|
module_exit(br_deinit)
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -21,6 +21,10 @@
|
||||||
/* Bridge group multicast address 802.1d (pg 51). */
|
/* Bridge group multicast address 802.1d (pg 51). */
|
||||||
const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
|
const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
|
/* Hook for brouter */
|
||||||
|
br_should_route_hook_t __rcu *br_should_route_hook __read_mostly;
|
||||||
|
EXPORT_SYMBOL(br_should_route_hook);
|
||||||
|
|
||||||
static int br_pass_frame_up(struct sk_buff *skb)
|
static int br_pass_frame_up(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev;
|
struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev;
|
||||||
|
@ -139,7 +143,7 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct net_bridge_port *p;
|
struct net_bridge_port *p;
|
||||||
const unsigned char *dest = eth_hdr(skb)->h_dest;
|
const unsigned char *dest = eth_hdr(skb)->h_dest;
|
||||||
int (*rhook)(struct sk_buff *skb);
|
br_should_route_hook_t *rhook;
|
||||||
|
|
||||||
if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
|
if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
|
||||||
return skb;
|
return skb;
|
||||||
|
@ -173,8 +177,8 @@ forward:
|
||||||
switch (p->state) {
|
switch (p->state) {
|
||||||
case BR_STATE_FORWARDING:
|
case BR_STATE_FORWARDING:
|
||||||
rhook = rcu_dereference(br_should_route_hook);
|
rhook = rcu_dereference(br_should_route_hook);
|
||||||
if (rhook != NULL) {
|
if (rhook) {
|
||||||
if (rhook(skb))
|
if ((*rhook)(skb))
|
||||||
return skb;
|
return skb;
|
||||||
dest = eth_hdr(skb)->h_dest;
|
dest = eth_hdr(skb)->h_dest;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,8 @@ static int __init ebtable_broute_init(void)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
/* see br_input.c */
|
/* see br_input.c */
|
||||||
rcu_assign_pointer(br_should_route_hook, ebt_broute);
|
rcu_assign_pointer(br_should_route_hook,
|
||||||
|
(br_should_route_hook_t *)ebt_broute);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue