1/* 2 * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 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 "bat_sysfs.h" 24#include "bat_debugfs.h" 25#include "routing.h" 26#include "send.h" 27#include "originator.h" 28#include "soft-interface.h" 29#include "icmp_socket.h" 30#include "translation-table.h" 31#include "hard-interface.h" 32#include "types.h" 33#include "vis.h" 34#include "hash.h" 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 45atomic_t bcast_queue_left; 46atomic_t batman_queue_left; 47 48int16_t num_hna; 49 50struct net_device *soft_device; 51 52unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 53atomic_t module_state; 54 55static struct packet_type batman_adv_packet_type __read_mostly = { 56 .type = __constant_htons(ETH_P_BATMAN), 57 .func = batman_skb_recv, 58}; 59 60struct workqueue_struct *bat_event_workqueue; 61 62static int __init batman_init(void) 63{ 64 int retval; 65 66 INIT_LIST_HEAD(&if_list); 67 INIT_HLIST_HEAD(&forw_bat_list); 68 INIT_HLIST_HEAD(&forw_bcast_list); 69 70 atomic_set(&module_state, MODULE_INACTIVE); 71 72 atomic_set(&bcast_queue_left, BCAST_QUEUE_LEN); 73 atomic_set(&batman_queue_left, BATMAN_QUEUE_LEN); 74 75 /* the name should not be longer than 10 chars - see 76 * http://lwn.net/Articles/23634/ */ 77 bat_event_workqueue = create_singlethread_workqueue("bat_events"); 78 79 if (!bat_event_workqueue) 80 return -ENOMEM; 81 82 bat_socket_init(); 83 debugfs_init(); 84 85 /* initialize layer 2 interface */ 86 soft_device = alloc_netdev(sizeof(struct bat_priv) , "bat%d", 87 interface_setup); 88 89 if (!soft_device) { 90 pr_err("Unable to allocate the batman interface\n"); 91 goto end; 92 } 93 94 retval = register_netdev(soft_device); 95 96 if (retval < 0) { 97 pr_err("Unable to register the batman interface: %i\n", retval); 98 goto free_soft_device; 99 } 100 101 retval = sysfs_add_meshif(soft_device); 102 103 if (retval < 0) 104 goto unreg_soft_device; 105 106 retval = debugfs_add_meshif(soft_device); 107 108 if (retval < 0) 109 goto unreg_sysfs; 110 111 register_netdevice_notifier(&hard_if_notifier); 112 dev_add_pack(&batman_adv_packet_type); 113 114 pr_info("B.A.T.M.A.N. advanced %s%s (compatibility version %i) " 115 "loaded\n", SOURCE_VERSION, REVISION_VERSION_STR, 116 COMPAT_VERSION); 117 118 return 0; 119 120unreg_sysfs: 121 sysfs_del_meshif(soft_device); 122unreg_soft_device: 123 unregister_netdev(soft_device); 124 soft_device = NULL; 125 return -ENOMEM; 126 127free_soft_device: 128 free_netdev(soft_device); 129 soft_device = NULL; 130end: 131 return -ENOMEM; 132} 133 134static void __exit batman_exit(void) 135{ 136 deactivate_module(); 137 138 debugfs_destroy(); 139 unregister_netdevice_notifier(&hard_if_notifier); 140 hardif_remove_interfaces(); 141 142 if (soft_device) { 143 debugfs_del_meshif(soft_device); 144 sysfs_del_meshif(soft_device); 145 unregister_netdev(soft_device); 146 soft_device = NULL; 147 } 148 149 dev_remove_pack(&batman_adv_packet_type); 150 151 destroy_workqueue(bat_event_workqueue); 152 bat_event_workqueue = NULL; 153} 154 155/* activates the module, 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 (vis_init() < 1) 170 goto err; 171 172 update_min_mtu(); 173 atomic_set(&module_state, MODULE_ACTIVE); 174 goto end; 175 176err: 177 pr_err("Unable to allocate memory for mesh information structures: " 178 "out of mem ?\n"); 179 deactivate_module(); 180end: 181 return; 182} 183 184/* shuts down the whole module.*/ 185void deactivate_module(void) 186{ 187 atomic_set(&module_state, MODULE_DEACTIVATING); 188 189 purge_outstanding_packets(NULL); 190 flush_workqueue(bat_event_workqueue); 191 192 vis_quit(); 193 194 /* TODO: unregister BATMAN pack */ 195 196 originator_free(); 197 198 hna_local_free(); 199 hna_global_free(); 200 201 synchronize_net(); 202 203 synchronize_rcu(); 204 atomic_set(&module_state, MODULE_INACTIVE); 205} 206 207void inc_module_count(void) 208{ 209 try_module_get(THIS_MODULE); 210} 211 212void dec_module_count(void) 213{ 214 module_put(THIS_MODULE); 215} 216 217int addr_to_string(char *buff, uint8_t *addr) 218{ 219 return sprintf(buff, "%pM", addr); 220} 221 222/* returns 1 if they are the same originator */ 223 224int compare_orig(void *data1, void *data2) 225{ 226 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); 227} 228 229/* hashfunction to choose an entry in a hash table of given size */ 230/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ 231int choose_orig(void *data, int32_t size) 232{ 233 unsigned char *key = data; 234 uint32_t hash = 0; 235 size_t i; 236 237 for (i = 0; i < 6; i++) { 238 hash += key[i]; 239 hash += (hash << 10); 240 hash ^= (hash >> 6); 241 } 242 243 hash += (hash << 3); 244 hash ^= (hash >> 11); 245 hash += (hash << 15); 246 247 return hash % size; 248} 249 250int is_my_mac(uint8_t *addr) 251{ 252 struct batman_if *batman_if; 253 254 rcu_read_lock(); 255 list_for_each_entry_rcu(batman_if, &if_list, list) { 256 if (batman_if->if_status != IF_ACTIVE) 257 continue; 258 259 if (compare_orig(batman_if->net_dev->dev_addr, addr)) { 260 rcu_read_unlock(); 261 return 1; 262 } 263 } 264 rcu_read_unlock(); 265 return 0; 266 267} 268 269int is_bcast(uint8_t *addr) 270{ 271 return (addr[0] == (uint8_t)0xff) && (addr[1] == (uint8_t)0xff); 272} 273 274int is_mcast(uint8_t *addr) 275{ 276 return *addr & 0x01; 277} 278 279module_init(batman_init); 280module_exit(batman_exit); 281 282MODULE_LICENSE("GPL"); 283 284MODULE_AUTHOR(DRIVER_AUTHOR); 285MODULE_DESCRIPTION(DRIVER_DESC); 286MODULE_SUPPORTED_DEVICE(DRIVER_DEVICE); 287#ifdef REVISION_VERSION 288MODULE_VERSION(SOURCE_VERSION "-" REVISION_VERSION); 289#else 290MODULE_VERSION(SOURCE_VERSION); 291#endif 292