diff options
author | Marek Lindner <lindner_marek@yahoo.de> | 2011-11-28 04:40:17 -0500 |
---|---|---|
committer | Marek Lindner <lindner_marek@yahoo.de> | 2012-02-16 13:50:20 -0500 |
commit | 1c280471b013e26c833fc86acc231c73442cfa21 (patch) | |
tree | ff48395664f514b1c8f2f14e78c5b3c4da653702 /net/batman-adv | |
parent | 6e242f9037f8a82ce2608c20a5460b670b2d5ff4 (diff) |
batman-adv: add infrastructure to change routing algorithm at runtime
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Diffstat (limited to 'net/batman-adv')
-rw-r--r-- | net/batman-adv/bat_algo.h | 27 | ||||
-rw-r--r-- | net/batman-adv/bat_debugfs.c | 22 | ||||
-rw-r--r-- | net/batman-adv/bat_iv_ogm.c | 10 | ||||
-rw-r--r-- | net/batman-adv/main.c | 72 | ||||
-rw-r--r-- | net/batman-adv/main.h | 4 | ||||
-rw-r--r-- | net/batman-adv/soft-interface.c | 4 | ||||
-rw-r--r-- | net/batman-adv/types.h | 6 |
7 files changed, 145 insertions, 0 deletions
diff --git a/net/batman-adv/bat_algo.h b/net/batman-adv/bat_algo.h new file mode 100644 index 000000000000..755379fd367d --- /dev/null +++ b/net/batman-adv/bat_algo.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 B.A.T.M.A.N. contributors: | ||
3 | * | ||
4 | * Marek Lindner | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of version 2 of the GNU General Public | ||
8 | * License as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
18 | * 02110-1301, USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #ifndef _NET_BATMAN_ADV_BAT_ALGO_H_ | ||
23 | #define _NET_BATMAN_ADV_BAT_ALGO_H_ | ||
24 | |||
25 | int bat_iv_init(void); | ||
26 | |||
27 | #endif /* _NET_BATMAN_ADV_BAT_ALGO_H_ */ | ||
diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c index d0af9bf69e46..a7a393eeb935 100644 --- a/net/batman-adv/bat_debugfs.c +++ b/net/batman-adv/bat_debugfs.c | |||
@@ -221,6 +221,11 @@ static void debug_log_cleanup(struct bat_priv *bat_priv) | |||
221 | } | 221 | } |
222 | #endif | 222 | #endif |
223 | 223 | ||
224 | static int bat_algorithms_open(struct inode *inode, struct file *file) | ||
225 | { | ||
226 | return single_open(file, bat_algo_seq_print_text, NULL); | ||
227 | } | ||
228 | |||
224 | static int originators_open(struct inode *inode, struct file *file) | 229 | static int originators_open(struct inode *inode, struct file *file) |
225 | { | 230 | { |
226 | struct net_device *net_dev = (struct net_device *)inode->i_private; | 231 | struct net_device *net_dev = (struct net_device *)inode->i_private; |
@@ -274,6 +279,7 @@ struct bat_debuginfo bat_debuginfo_##_name = { \ | |||
274 | } \ | 279 | } \ |
275 | }; | 280 | }; |
276 | 281 | ||
282 | static BAT_DEBUGINFO(routing_algos, S_IRUGO, bat_algorithms_open); | ||
277 | static BAT_DEBUGINFO(originators, S_IRUGO, originators_open); | 283 | static BAT_DEBUGINFO(originators, S_IRUGO, originators_open); |
278 | static BAT_DEBUGINFO(gateways, S_IRUGO, gateways_open); | 284 | static BAT_DEBUGINFO(gateways, S_IRUGO, gateways_open); |
279 | static BAT_DEBUGINFO(softif_neigh, S_IRUGO, softif_neigh_open); | 285 | static BAT_DEBUGINFO(softif_neigh, S_IRUGO, softif_neigh_open); |
@@ -293,9 +299,25 @@ static struct bat_debuginfo *mesh_debuginfos[] = { | |||
293 | 299 | ||
294 | void debugfs_init(void) | 300 | void debugfs_init(void) |
295 | { | 301 | { |
302 | struct bat_debuginfo *bat_debug; | ||
303 | struct dentry *file; | ||
304 | |||
296 | bat_debugfs = debugfs_create_dir(DEBUGFS_BAT_SUBDIR, NULL); | 305 | bat_debugfs = debugfs_create_dir(DEBUGFS_BAT_SUBDIR, NULL); |
297 | if (bat_debugfs == ERR_PTR(-ENODEV)) | 306 | if (bat_debugfs == ERR_PTR(-ENODEV)) |
298 | bat_debugfs = NULL; | 307 | bat_debugfs = NULL; |
308 | |||
309 | if (!bat_debugfs) | ||
310 | goto out; | ||
311 | |||
312 | bat_debug = &bat_debuginfo_routing_algos; | ||
313 | file = debugfs_create_file(bat_debug->attr.name, | ||
314 | S_IFREG | bat_debug->attr.mode, | ||
315 | bat_debugfs, NULL, &bat_debug->fops); | ||
316 | if (!file) | ||
317 | pr_err("Can't add debugfs file: %s\n", bat_debug->attr.name); | ||
318 | |||
319 | out: | ||
320 | return; | ||
299 | } | 321 | } |
300 | 322 | ||
301 | void debugfs_destroy(void) | 323 | void debugfs_destroy(void) |
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 3402fa575b47..1847efaaa6fd 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "gateway_client.h" | 29 | #include "gateway_client.h" |
30 | #include "hard-interface.h" | 30 | #include "hard-interface.h" |
31 | #include "send.h" | 31 | #include "send.h" |
32 | #include "bat_algo.h" | ||
32 | 33 | ||
33 | void bat_ogm_init(struct hard_iface *hard_iface) | 34 | void bat_ogm_init(struct hard_iface *hard_iface) |
34 | { | 35 | { |
@@ -1172,3 +1173,12 @@ void bat_ogm_receive(struct hard_iface *if_incoming, struct sk_buff *skb) | |||
1172 | } while (bat_ogm_aggr_packet(buff_pos, packet_len, | 1173 | } while (bat_ogm_aggr_packet(buff_pos, packet_len, |
1173 | batman_ogm_packet->tt_num_changes)); | 1174 | batman_ogm_packet->tt_num_changes)); |
1174 | } | 1175 | } |
1176 | |||
1177 | static struct bat_algo_ops batman_iv __read_mostly = { | ||
1178 | .name = "BATMAN IV", | ||
1179 | }; | ||
1180 | |||
1181 | int __init bat_iv_init(void) | ||
1182 | { | ||
1183 | return bat_algo_register(&batman_iv); | ||
1184 | } | ||
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 71b56cf9cdd6..7c87a341f29f 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c | |||
@@ -32,11 +32,14 @@ | |||
32 | #include "gateway_client.h" | 32 | #include "gateway_client.h" |
33 | #include "vis.h" | 33 | #include "vis.h" |
34 | #include "hash.h" | 34 | #include "hash.h" |
35 | #include "bat_algo.h" | ||
35 | 36 | ||
36 | 37 | ||
37 | /* List manipulations on hardif_list have to be rtnl_lock()'ed, | 38 | /* List manipulations on hardif_list have to be rtnl_lock()'ed, |
38 | * list traversals just rcu-locked */ | 39 | * list traversals just rcu-locked */ |
39 | struct list_head hardif_list; | 40 | struct list_head hardif_list; |
41 | char bat_routing_algo[20] = "BATMAN IV"; | ||
42 | static struct hlist_head bat_algo_list; | ||
40 | 43 | ||
41 | unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | 44 | unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
42 | 45 | ||
@@ -45,6 +48,9 @@ struct workqueue_struct *bat_event_workqueue; | |||
45 | static int __init batman_init(void) | 48 | static int __init batman_init(void) |
46 | { | 49 | { |
47 | INIT_LIST_HEAD(&hardif_list); | 50 | INIT_LIST_HEAD(&hardif_list); |
51 | INIT_HLIST_HEAD(&bat_algo_list); | ||
52 | |||
53 | bat_iv_init(); | ||
48 | 54 | ||
49 | /* the name should not be longer than 10 chars - see | 55 | /* the name should not be longer than 10 chars - see |
50 | * http://lwn.net/Articles/23634/ */ | 56 | * http://lwn.net/Articles/23634/ */ |
@@ -172,6 +178,72 @@ int is_my_mac(const uint8_t *addr) | |||
172 | return 0; | 178 | return 0; |
173 | } | 179 | } |
174 | 180 | ||
181 | static struct bat_algo_ops *bat_algo_get(char *name) | ||
182 | { | ||
183 | struct bat_algo_ops *bat_algo_ops = NULL, *bat_algo_ops_tmp; | ||
184 | struct hlist_node *node; | ||
185 | |||
186 | hlist_for_each_entry(bat_algo_ops_tmp, node, &bat_algo_list, list) { | ||
187 | if (strcmp(bat_algo_ops_tmp->name, name) != 0) | ||
188 | continue; | ||
189 | |||
190 | bat_algo_ops = bat_algo_ops_tmp; | ||
191 | break; | ||
192 | } | ||
193 | |||
194 | return bat_algo_ops; | ||
195 | } | ||
196 | |||
197 | int bat_algo_register(struct bat_algo_ops *bat_algo_ops) | ||
198 | { | ||
199 | struct bat_algo_ops *bat_algo_ops_tmp; | ||
200 | int ret = -1; | ||
201 | |||
202 | bat_algo_ops_tmp = bat_algo_get(bat_algo_ops->name); | ||
203 | if (bat_algo_ops_tmp) { | ||
204 | pr_info("Trying to register already registered routing " | ||
205 | "algorithm: %s\n", bat_algo_ops->name); | ||
206 | goto out; | ||
207 | } | ||
208 | |||
209 | INIT_HLIST_NODE(&bat_algo_ops->list); | ||
210 | hlist_add_head(&bat_algo_ops->list, &bat_algo_list); | ||
211 | ret = 0; | ||
212 | |||
213 | out: | ||
214 | return ret; | ||
215 | } | ||
216 | |||
217 | int bat_algo_select(struct bat_priv *bat_priv, char *name) | ||
218 | { | ||
219 | struct bat_algo_ops *bat_algo_ops; | ||
220 | int ret = -1; | ||
221 | |||
222 | bat_algo_ops = bat_algo_get(name); | ||
223 | if (!bat_algo_ops) | ||
224 | goto out; | ||
225 | |||
226 | bat_priv->bat_algo_ops = bat_algo_ops; | ||
227 | ret = 0; | ||
228 | |||
229 | out: | ||
230 | return ret; | ||
231 | } | ||
232 | |||
233 | int bat_algo_seq_print_text(struct seq_file *seq, void *offset) | ||
234 | { | ||
235 | struct bat_algo_ops *bat_algo_ops; | ||
236 | struct hlist_node *node; | ||
237 | |||
238 | seq_printf(seq, "Available routing algorithms:\n"); | ||
239 | |||
240 | hlist_for_each_entry(bat_algo_ops, node, &bat_algo_list, list) { | ||
241 | seq_printf(seq, "%s\n", bat_algo_ops->name); | ||
242 | } | ||
243 | |||
244 | return 0; | ||
245 | } | ||
246 | |||
175 | module_init(batman_init); | 247 | module_init(batman_init); |
176 | module_exit(batman_exit); | 248 | module_exit(batman_exit); |
177 | 249 | ||
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index f9c659b3f3a9..586afafb1b67 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h | |||
@@ -147,6 +147,7 @@ enum dbg_level { | |||
147 | #include <linux/seq_file.h> | 147 | #include <linux/seq_file.h> |
148 | #include "types.h" | 148 | #include "types.h" |
149 | 149 | ||
150 | extern char bat_routing_algo[]; | ||
150 | extern struct list_head hardif_list; | 151 | extern struct list_head hardif_list; |
151 | 152 | ||
152 | extern unsigned char broadcast_addr[]; | 153 | extern unsigned char broadcast_addr[]; |
@@ -157,6 +158,9 @@ void mesh_free(struct net_device *soft_iface); | |||
157 | void inc_module_count(void); | 158 | void inc_module_count(void); |
158 | void dec_module_count(void); | 159 | void dec_module_count(void); |
159 | int is_my_mac(const uint8_t *addr); | 160 | int is_my_mac(const uint8_t *addr); |
161 | int bat_algo_register(struct bat_algo_ops *bat_algo_ops); | ||
162 | int bat_algo_select(struct bat_priv *bat_priv, char *name); | ||
163 | int bat_algo_seq_print_text(struct seq_file *seq, void *offset); | ||
160 | 164 | ||
161 | #ifdef CONFIG_BATMAN_ADV_DEBUG | 165 | #ifdef CONFIG_BATMAN_ADV_DEBUG |
162 | int debug_log(struct bat_priv *bat_priv, const char *fmt, ...) __printf(2, 3); | 166 | int debug_log(struct bat_priv *bat_priv, const char *fmt, ...) __printf(2, 3); |
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index bd8c7cfaeacf..b5aecd5e45cc 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
@@ -855,6 +855,10 @@ struct net_device *softif_create(const char *name) | |||
855 | bat_priv->primary_if = NULL; | 855 | bat_priv->primary_if = NULL; |
856 | bat_priv->num_ifaces = 0; | 856 | bat_priv->num_ifaces = 0; |
857 | 857 | ||
858 | ret = bat_algo_select(bat_priv, bat_routing_algo); | ||
859 | if (ret < 0) | ||
860 | goto unreg_soft_iface; | ||
861 | |||
858 | ret = sysfs_add_meshif(soft_iface); | 862 | ret = sysfs_add_meshif(soft_iface); |
859 | if (ret < 0) | 863 | if (ret < 0) |
860 | goto unreg_soft_iface; | 864 | goto unreg_soft_iface; |
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 35085f410b96..d21ff2cf668e 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h | |||
@@ -206,6 +206,7 @@ struct bat_priv { | |||
206 | atomic_t gw_reselect; | 206 | atomic_t gw_reselect; |
207 | struct hard_iface __rcu *primary_if; /* rcu protected pointer */ | 207 | struct hard_iface __rcu *primary_if; /* rcu protected pointer */ |
208 | struct vis_info *my_vis_info; | 208 | struct vis_info *my_vis_info; |
209 | struct bat_algo_ops *bat_algo_ops; | ||
209 | }; | 210 | }; |
210 | 211 | ||
211 | struct socket_client { | 212 | struct socket_client { |
@@ -344,4 +345,9 @@ struct softif_neigh { | |||
344 | struct rcu_head rcu; | 345 | struct rcu_head rcu; |
345 | }; | 346 | }; |
346 | 347 | ||
348 | struct bat_algo_ops { | ||
349 | struct hlist_node list; | ||
350 | char *name; | ||
351 | }; | ||
352 | |||
347 | #endif /* _NET_BATMAN_ADV_TYPES_H_ */ | 353 | #endif /* _NET_BATMAN_ADV_TYPES_H_ */ |