]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/batman-adv/main.c
Staging: batman-adv: remove redundant pointer to originator interface
[net-next-2.6.git] / drivers / staging / batman-adv / main.c
CommitLineData
5beef3c9 1/*
9b6d10b7 2 * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
5beef3c9
AL
3 *
4 * Marek Lindner, Simon Wunderlich
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#include "main.h"
23#include "proc.h"
47fdf097 24#include "bat_sysfs.h"
5beef3c9
AL
25#include "routing.h"
26#include "send.h"
8a2e042c 27#include "originator.h"
5beef3c9
AL
28#include "soft-interface.h"
29#include "device.h"
30#include "translation-table.h"
31#include "hard-interface.h"
32#include "types.h"
33#include "vis.h"
34#include "hash.h"
5beef3c9
AL
35
36struct list_head if_list;
37struct hlist_head forw_bat_list;
38struct hlist_head forw_bcast_list;
39struct hashtable_t *orig_hash;
40
41DEFINE_SPINLOCK(orig_hash_lock);
42DEFINE_SPINLOCK(forw_bat_list_lock);
43DEFINE_SPINLOCK(forw_bcast_list_lock);
44
5beef3c9 45atomic_t vis_interval;
5beef3c9
AL
46int16_t num_hna;
47int16_t num_ifs;
48
49struct net_device *soft_device;
50
5beef3c9
AL
51unsigned char broadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
52atomic_t module_state;
53
e7017195 54static struct packet_type batman_adv_packet_type __read_mostly = {
b9b27e4e 55 .type = __constant_htons(ETH_P_BATMAN),
e7017195
SW
56 .func = batman_skb_recv,
57};
58
5beef3c9
AL
59struct workqueue_struct *bat_event_workqueue;
60
734cc82a 61#ifdef CONFIG_BATMAN_ADV_DEBUG
bad2239e
AL
62int debug;
63
64module_param(debug, int, 0644);
65
66int bat_debug_type(int type)
67{
68 return debug & type;
69}
70#endif
71
5beef3c9
AL
72int init_module(void)
73{
74 int retval;
75
76 INIT_LIST_HEAD(&if_list);
77 INIT_HLIST_HEAD(&forw_bat_list);
78 INIT_HLIST_HEAD(&forw_bcast_list);
79
80 atomic_set(&module_state, MODULE_INACTIVE);
81
5beef3c9
AL
82 atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
83 * for debugging now. */
5beef3c9
AL
84
85 /* the name should not be longer than 10 chars - see
86 * http://lwn.net/Articles/23634/ */
87 bat_event_workqueue = create_singlethread_workqueue("bat_events");
88
89 if (!bat_event_workqueue)
90 return -ENOMEM;
91
92 retval = setup_procfs();
93 if (retval < 0)
94 return retval;
95
96 bat_device_init();
97
98 /* initialize layer 2 interface */
99 soft_device = alloc_netdev(sizeof(struct bat_priv) , "bat%d",
100 interface_setup);
101
102 if (!soft_device) {
bad2239e 103 printk(KERN_ERR "batman-adv:Unable to allocate the batman interface\n");
5beef3c9
AL
104 goto end;
105 }
106
107 retval = register_netdev(soft_device);
108
109 if (retval < 0) {
bad2239e 110 printk(KERN_ERR "batman-adv:Unable to register the batman interface: %i\n", retval);
5beef3c9
AL
111 goto free_soft_device;
112 }
113
47fdf097
ML
114 retval = sysfs_add_meshif(soft_device);
115
116 if (retval < 0)
117 goto unreg_soft_device;
118
5beef3c9 119 register_netdevice_notifier(&hard_if_notifier);
e7017195 120 dev_add_pack(&batman_adv_packet_type);
5beef3c9 121
0887635b 122 printk(KERN_INFO "batman-adv:B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded\n",
bad2239e 123 SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION);
5beef3c9
AL
124
125 return 0;
126
47fdf097
ML
127unreg_soft_device:
128 unregister_netdevice(soft_device);
5beef3c9
AL
129free_soft_device:
130 free_netdev(soft_device);
131 soft_device = NULL;
132end:
133 return -ENOMEM;
134}
135
136void cleanup_module(void)
137{
138 shutdown_module();
139
140 if (soft_device) {
47fdf097 141 sysfs_del_meshif(soft_device);
5beef3c9
AL
142 unregister_netdev(soft_device);
143 soft_device = NULL;
144 }
145
e7017195
SW
146 dev_remove_pack(&batman_adv_packet_type);
147
5beef3c9
AL
148 unregister_netdevice_notifier(&hard_if_notifier);
149 cleanup_procfs();
150
151 destroy_workqueue(bat_event_workqueue);
152 bat_event_workqueue = NULL;
153}
154
155/* activates the module, creates bat device, starts timer ... */
156void activate_module(void)
157{
158 if (originator_init() < 1)
159 goto err;
160
161 if (hna_local_init() < 1)
162 goto err;
163
164 if (hna_global_init() < 1)
165 goto err;
166
167 hna_local_add(soft_device->dev_addr);
168
169 if (bat_device_setup() < 1)
170 goto end;
171
172 if (vis_init() < 1)
173 goto err;
174
5beef3c9
AL
175 update_min_mtu();
176 atomic_set(&module_state, MODULE_ACTIVE);
177 goto end;
178
179err:
bad2239e 180 printk(KERN_ERR "batman-adv:Unable to allocate memory for mesh information structures: out of mem ?\n");
5beef3c9
AL
181 shutdown_module();
182end:
183 return;
184}
185
186/* shuts down the whole module.*/
187void shutdown_module(void)
188{
189 atomic_set(&module_state, MODULE_DEACTIVATING);
190
191 purge_outstanding_packets();
192 flush_workqueue(bat_event_workqueue);
193
194 vis_quit();
195
e7017195 196 /* TODO: unregister BATMAN pack */
5beef3c9
AL
197
198 originator_free();
199
200 hna_local_free();
201 hna_global_free();
202
203 synchronize_net();
204 bat_device_destroy();
205
206 hardif_remove_interfaces();
207 synchronize_rcu();
208 atomic_set(&module_state, MODULE_INACTIVE);
209}
210
211void inc_module_count(void)
212{
213 try_module_get(THIS_MODULE);
214}
215
216void dec_module_count(void)
217{
218 module_put(THIS_MODULE);
219}
220
221int addr_to_string(char *buff, uint8_t *addr)
222{
223 return sprintf(buff, "%02x:%02x:%02x:%02x:%02x:%02x",
224 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
225}
226
227/* returns 1 if they are the same originator */
228
229int compare_orig(void *data1, void *data2)
230{
231 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
232}
233
234/* hashfunction to choose an entry in a hash table of given size */
235/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
236int choose_orig(void *data, int32_t size)
237{
238 unsigned char *key = data;
239 uint32_t hash = 0;
240 size_t i;
241
242 for (i = 0; i < 6; i++) {
243 hash += key[i];
244 hash += (hash << 10);
245 hash ^= (hash >> 6);
246 }
247
248 hash += (hash << 3);
249 hash ^= (hash >> 11);
250 hash += (hash << 15);
251
252 return hash % size;
253}
254
255int is_my_mac(uint8_t *addr)
256{
257 struct batman_if *batman_if;
258 rcu_read_lock();
259 list_for_each_entry_rcu(batman_if, &if_list, list) {
260 if ((batman_if->net_dev) &&
261 (compare_orig(batman_if->net_dev->dev_addr, addr))) {
262 rcu_read_unlock();
263 return 1;
264 }
265 }
266 rcu_read_unlock();
267 return 0;
268
269}
270
271int is_bcast(uint8_t *addr)
272{
273 return (addr[0] == (uint8_t)0xff) && (addr[1] == (uint8_t)0xff);
274}
275
276int is_mcast(uint8_t *addr)
277{
278 return *addr & 0x01;
279}
280
281MODULE_LICENSE("GPL");
282
283MODULE_AUTHOR(DRIVER_AUTHOR);
284MODULE_DESCRIPTION(DRIVER_DESC);
285MODULE_SUPPORTED_DEVICE(DRIVER_DEVICE);
286#ifdef REVISION_VERSION
287MODULE_VERSION(SOURCE_VERSION "-" REVISION_VERSION);
288#else
289MODULE_VERSION(SOURCE_VERSION);
290#endif