提交 15cf5523 编写于 作者: M Marek Lindner 提交者: Greg Kroah-Hartman

Staging: batman-adv: register the batman-adv packet type per interface

Batman-adv globally registered the batman-adv packet type and installed
a hook to batman_skb_recv(). Each interface receiving a packet with that
type would end up in this function which then had to loop through all
batman-adv internal interface structures to find the its meta data. The
more interfaces a system had the longer the loops might take. Each and
every packet goes through this function making it a performance critical
loop.

This patch installs the hook for each activated interface. The called
batman_skb_recv() can distinguish these calls, therefore avoiding the
loop through the interface structures.
Signed-off-by: NMarek Lindner <lindner_marek@yahoo.de>
[sven.eckelmann@gmx.de: Rework on top of current version]
Signed-off-by: NSven Eckelmann <sven.eckelmann@gmx.de>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 d52e90ae
...@@ -265,6 +265,11 @@ int hardif_enable_interface(struct batman_if *batman_if) ...@@ -265,6 +265,11 @@ int hardif_enable_interface(struct batman_if *batman_if)
batman_if->if_status = IF_INACTIVE; batman_if->if_status = IF_INACTIVE;
orig_hash_add_if(batman_if, bat_priv->num_ifaces); orig_hash_add_if(batman_if, bat_priv->num_ifaces);
batman_if->batman_adv_ptype.type = __constant_htons(ETH_P_BATMAN);
batman_if->batman_adv_ptype.func = batman_skb_recv;
batman_if->batman_adv_ptype.dev = batman_if->net_dev;
dev_add_pack(&batman_if->batman_adv_ptype);
atomic_set(&batman_if->seqno, 1); atomic_set(&batman_if->seqno, 1);
atomic_set(&batman_if->frag_seqno, 1); atomic_set(&batman_if->frag_seqno, 1);
bat_info(soft_device, "Adding interface: %s\n", batman_if->dev); bat_info(soft_device, "Adding interface: %s\n", batman_if->dev);
...@@ -319,6 +324,8 @@ void hardif_disable_interface(struct batman_if *batman_if) ...@@ -319,6 +324,8 @@ void hardif_disable_interface(struct batman_if *batman_if)
return; return;
bat_info(soft_device, "Removing interface: %s\n", batman_if->dev); bat_info(soft_device, "Removing interface: %s\n", batman_if->dev);
dev_remove_pack(&batman_if->batman_adv_ptype);
bat_priv->num_ifaces--; bat_priv->num_ifaces--;
orig_hash_del_if(batman_if, bat_priv->num_ifaces); orig_hash_del_if(batman_if, bat_priv->num_ifaces);
...@@ -468,6 +475,7 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, ...@@ -468,6 +475,7 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
struct batman_if *batman_if; struct batman_if *batman_if;
int ret; int ret;
batman_if = container_of(ptype, struct batman_if, batman_adv_ptype);
skb = skb_share_check(skb, GFP_ATOMIC); skb = skb_share_check(skb, GFP_ATOMIC);
/* skb was released by skb_share_check() */ /* skb was released by skb_share_check() */
...@@ -486,10 +494,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, ...@@ -486,10 +494,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
|| !skb_mac_header(skb))) || !skb_mac_header(skb)))
goto err_free; goto err_free;
batman_if = get_batman_if_by_netdev(skb->dev);
if (!batman_if)
goto err_free;
/* discard frames on not active interfaces */ /* discard frames on not active interfaces */
if (batman_if->if_status != IF_ACTIVE) if (batman_if->if_status != IF_ACTIVE)
goto err_free; goto err_free;
......
...@@ -49,11 +49,6 @@ struct net_device *soft_device; ...@@ -49,11 +49,6 @@ struct net_device *soft_device;
unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
atomic_t module_state; atomic_t module_state;
static struct packet_type batman_adv_packet_type __read_mostly = {
.type = __constant_htons(ETH_P_BATMAN),
.func = batman_skb_recv,
};
struct workqueue_struct *bat_event_workqueue; struct workqueue_struct *bat_event_workqueue;
static int __init batman_init(void) static int __init batman_init(void)
...@@ -103,7 +98,6 @@ static int __init batman_init(void) ...@@ -103,7 +98,6 @@ static int __init batman_init(void)
goto unreg_sysfs; goto unreg_sysfs;
register_netdevice_notifier(&hard_if_notifier); register_netdevice_notifier(&hard_if_notifier);
dev_add_pack(&batman_adv_packet_type);
pr_info("B.A.T.M.A.N. advanced %s%s (compatibility version %i) " pr_info("B.A.T.M.A.N. advanced %s%s (compatibility version %i) "
"loaded\n", SOURCE_VERSION, REVISION_VERSION_STR, "loaded\n", SOURCE_VERSION, REVISION_VERSION_STR,
...@@ -140,8 +134,6 @@ static void __exit batman_exit(void) ...@@ -140,8 +134,6 @@ static void __exit batman_exit(void)
soft_device = NULL; soft_device = NULL;
} }
dev_remove_pack(&batman_adv_packet_type);
destroy_workqueue(bat_event_workqueue); destroy_workqueue(bat_event_workqueue);
bat_event_workqueue = NULL; bat_event_workqueue = NULL;
} }
...@@ -185,8 +177,6 @@ void deactivate_module(void) ...@@ -185,8 +177,6 @@ void deactivate_module(void)
vis_quit(); vis_quit();
/* TODO: unregister BATMAN pack */
originator_free(); originator_free();
hna_local_free(); hna_local_free();
......
...@@ -46,7 +46,7 @@ struct batman_if { ...@@ -46,7 +46,7 @@ struct batman_if {
int packet_len; int packet_len;
struct kobject *hardif_obj; struct kobject *hardif_obj;
struct rcu_head rcu; struct rcu_head rcu;
struct packet_type batman_adv_ptype;
}; };
/** /**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册