diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2013-09-27 12:03:39 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-11-20 15:27:47 -0500 |
commit | b44cfec16dac9c2aba3581c57488bad1989778f7 (patch) | |
tree | d44f1bd64ff59d85cbbe6d1a42ba8b1ebae70f85 | |
parent | 7e19d6db7caebd7b8ffe29ff687cc399b59790bc (diff) |
batman-adv: set up network coding packet handlers during module init
commit 6c519bad7b19a2c14a075b400edabaa630330123 upstream.
batman-adv saves its table of packet handlers as a global state, so handlers
must be set up only once (and setting them up a second time will fail).
The recently-added network coding support tries to set up its handler each time
a new softif is registered, which obviously fails when more that one softif is
used (and in consequence, the softif creation fails).
Fix this by splitting up batadv_nc_init into batadv_nc_init (which is called
only once) and batadv_nc_mesh_init (which is called for each softif); in
addition batadv_nc_free is renamed to batadv_nc_mesh_free to keep naming
consistent.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
Cc: David Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | net/batman-adv/main.c | 5 | ||||
-rw-r--r-- | net/batman-adv/network-coding.c | 28 | ||||
-rw-r--r-- | net/batman-adv/network-coding.h | 14 |
3 files changed, 31 insertions, 16 deletions
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 51aafd669cbb..f1cb1f56cda9 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c | |||
@@ -61,6 +61,7 @@ static int __init batadv_init(void) | |||
61 | batadv_recv_handler_init(); | 61 | batadv_recv_handler_init(); |
62 | 62 | ||
63 | batadv_iv_init(); | 63 | batadv_iv_init(); |
64 | batadv_nc_init(); | ||
64 | 65 | ||
65 | batadv_event_workqueue = create_singlethread_workqueue("bat_events"); | 66 | batadv_event_workqueue = create_singlethread_workqueue("bat_events"); |
66 | 67 | ||
@@ -138,7 +139,7 @@ int batadv_mesh_init(struct net_device *soft_iface) | |||
138 | if (ret < 0) | 139 | if (ret < 0) |
139 | goto err; | 140 | goto err; |
140 | 141 | ||
141 | ret = batadv_nc_init(bat_priv); | 142 | ret = batadv_nc_mesh_init(bat_priv); |
142 | if (ret < 0) | 143 | if (ret < 0) |
143 | goto err; | 144 | goto err; |
144 | 145 | ||
@@ -163,7 +164,7 @@ void batadv_mesh_free(struct net_device *soft_iface) | |||
163 | batadv_vis_quit(bat_priv); | 164 | batadv_vis_quit(bat_priv); |
164 | 165 | ||
165 | batadv_gw_node_purge(bat_priv); | 166 | batadv_gw_node_purge(bat_priv); |
166 | batadv_nc_free(bat_priv); | 167 | batadv_nc_mesh_free(bat_priv); |
167 | batadv_dat_free(bat_priv); | 168 | batadv_dat_free(bat_priv); |
168 | batadv_bla_free(bat_priv); | 169 | batadv_bla_free(bat_priv); |
169 | 170 | ||
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index e84629ece9b7..f97aeee2201c 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c | |||
@@ -35,6 +35,20 @@ static int batadv_nc_recv_coded_packet(struct sk_buff *skb, | |||
35 | struct batadv_hard_iface *recv_if); | 35 | struct batadv_hard_iface *recv_if); |
36 | 36 | ||
37 | /** | 37 | /** |
38 | * batadv_nc_init - one-time initialization for network coding | ||
39 | */ | ||
40 | int __init batadv_nc_init(void) | ||
41 | { | ||
42 | int ret; | ||
43 | |||
44 | /* Register our packet type */ | ||
45 | ret = batadv_recv_handler_register(BATADV_CODED, | ||
46 | batadv_nc_recv_coded_packet); | ||
47 | |||
48 | return ret; | ||
49 | } | ||
50 | |||
51 | /** | ||
38 | * batadv_nc_start_timer - initialise the nc periodic worker | 52 | * batadv_nc_start_timer - initialise the nc periodic worker |
39 | * @bat_priv: the bat priv with all the soft interface information | 53 | * @bat_priv: the bat priv with all the soft interface information |
40 | */ | 54 | */ |
@@ -45,10 +59,10 @@ static void batadv_nc_start_timer(struct batadv_priv *bat_priv) | |||
45 | } | 59 | } |
46 | 60 | ||
47 | /** | 61 | /** |
48 | * batadv_nc_init - initialise coding hash table and start house keeping | 62 | * batadv_nc_mesh_init - initialise coding hash table and start house keeping |
49 | * @bat_priv: the bat priv with all the soft interface information | 63 | * @bat_priv: the bat priv with all the soft interface information |
50 | */ | 64 | */ |
51 | int batadv_nc_init(struct batadv_priv *bat_priv) | 65 | int batadv_nc_mesh_init(struct batadv_priv *bat_priv) |
52 | { | 66 | { |
53 | bat_priv->nc.timestamp_fwd_flush = jiffies; | 67 | bat_priv->nc.timestamp_fwd_flush = jiffies; |
54 | bat_priv->nc.timestamp_sniffed_purge = jiffies; | 68 | bat_priv->nc.timestamp_sniffed_purge = jiffies; |
@@ -70,11 +84,6 @@ int batadv_nc_init(struct batadv_priv *bat_priv) | |||
70 | batadv_hash_set_lock_class(bat_priv->nc.coding_hash, | 84 | batadv_hash_set_lock_class(bat_priv->nc.coding_hash, |
71 | &batadv_nc_decoding_hash_lock_class_key); | 85 | &batadv_nc_decoding_hash_lock_class_key); |
72 | 86 | ||
73 | /* Register our packet type */ | ||
74 | if (batadv_recv_handler_register(BATADV_CODED, | ||
75 | batadv_nc_recv_coded_packet) < 0) | ||
76 | goto err; | ||
77 | |||
78 | INIT_DELAYED_WORK(&bat_priv->nc.work, batadv_nc_worker); | 87 | INIT_DELAYED_WORK(&bat_priv->nc.work, batadv_nc_worker); |
79 | batadv_nc_start_timer(bat_priv); | 88 | batadv_nc_start_timer(bat_priv); |
80 | 89 | ||
@@ -1722,12 +1731,11 @@ free_nc_packet: | |||
1722 | } | 1731 | } |
1723 | 1732 | ||
1724 | /** | 1733 | /** |
1725 | * batadv_nc_free - clean up network coding memory | 1734 | * batadv_nc_mesh_free - clean up network coding memory |
1726 | * @bat_priv: the bat priv with all the soft interface information | 1735 | * @bat_priv: the bat priv with all the soft interface information |
1727 | */ | 1736 | */ |
1728 | void batadv_nc_free(struct batadv_priv *bat_priv) | 1737 | void batadv_nc_mesh_free(struct batadv_priv *bat_priv) |
1729 | { | 1738 | { |
1730 | batadv_recv_handler_unregister(BATADV_CODED); | ||
1731 | cancel_delayed_work_sync(&bat_priv->nc.work); | 1739 | cancel_delayed_work_sync(&bat_priv->nc.work); |
1732 | 1740 | ||
1733 | batadv_nc_purge_paths(bat_priv, bat_priv->nc.coding_hash, NULL); | 1741 | batadv_nc_purge_paths(bat_priv, bat_priv->nc.coding_hash, NULL); |
diff --git a/net/batman-adv/network-coding.h b/net/batman-adv/network-coding.h index 4fa6d0caddbd..bd4295fb960f 100644 --- a/net/batman-adv/network-coding.h +++ b/net/batman-adv/network-coding.h | |||
@@ -22,8 +22,9 @@ | |||
22 | 22 | ||
23 | #ifdef CONFIG_BATMAN_ADV_NC | 23 | #ifdef CONFIG_BATMAN_ADV_NC |
24 | 24 | ||
25 | int batadv_nc_init(struct batadv_priv *bat_priv); | 25 | int batadv_nc_init(void); |
26 | void batadv_nc_free(struct batadv_priv *bat_priv); | 26 | int batadv_nc_mesh_init(struct batadv_priv *bat_priv); |
27 | void batadv_nc_mesh_free(struct batadv_priv *bat_priv); | ||
27 | void batadv_nc_update_nc_node(struct batadv_priv *bat_priv, | 28 | void batadv_nc_update_nc_node(struct batadv_priv *bat_priv, |
28 | struct batadv_orig_node *orig_node, | 29 | struct batadv_orig_node *orig_node, |
29 | struct batadv_orig_node *orig_neigh_node, | 30 | struct batadv_orig_node *orig_neigh_node, |
@@ -47,12 +48,17 @@ int batadv_nc_init_debugfs(struct batadv_priv *bat_priv); | |||
47 | 48 | ||
48 | #else /* ifdef CONFIG_BATMAN_ADV_NC */ | 49 | #else /* ifdef CONFIG_BATMAN_ADV_NC */ |
49 | 50 | ||
50 | static inline int batadv_nc_init(struct batadv_priv *bat_priv) | 51 | static inline int batadv_nc_init(void) |
51 | { | 52 | { |
52 | return 0; | 53 | return 0; |
53 | } | 54 | } |
54 | 55 | ||
55 | static inline void batadv_nc_free(struct batadv_priv *bat_priv) | 56 | static inline int batadv_nc_mesh_init(struct batadv_priv *bat_priv) |
57 | { | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static inline void batadv_nc_mesh_free(struct batadv_priv *bat_priv) | ||
56 | { | 62 | { |
57 | return; | 63 | return; |
58 | } | 64 | } |