1 /* 2 * Copyright (C) 2007-2012 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 "gateway_client.h" 33 #include "vis.h" 34 #include "hash.h" 35 #include "bat_algo.h" 36 37 38 /* List manipulations on hardif_list have to be rtnl_lock()'ed, 39 * list traversals just rcu-locked */ 40 struct list_head hardif_list; 41 char bat_routing_algo[20] = "BATMAN IV"; 42 static struct hlist_head bat_algo_list; 43 44 unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 45 46 struct workqueue_struct *bat_event_workqueue; 47 48 static int __init batman_init(void) 49 { 50 INIT_LIST_HEAD(&hardif_list); 51 INIT_HLIST_HEAD(&bat_algo_list); 52 53 bat_iv_init(); 54 55 /* the name should not be longer than 10 chars - see 56 * http://lwn.net/Articles/23634/ */ 57 bat_event_workqueue = create_singlethread_workqueue("bat_events"); 58 59 if (!bat_event_workqueue) 60 return -ENOMEM; 61 62 bat_socket_init(); 63 debugfs_init(); 64 65 register_netdevice_notifier(&hard_if_notifier); 66 67 pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n", 68 SOURCE_VERSION, COMPAT_VERSION); 69 70 return 0; 71 } 72 73 static void __exit batman_exit(void) 74 { 75 debugfs_destroy(); 76 unregister_netdevice_notifier(&hard_if_notifier); 77 hardif_remove_interfaces(); 78 79 flush_workqueue(bat_event_workqueue); 80 destroy_workqueue(bat_event_workqueue); 81 bat_event_workqueue = NULL; 82 83 rcu_barrier(); 84 } 85 86 int mesh_init(struct net_device *soft_iface) 87 { 88 struct bat_priv *bat_priv = netdev_priv(soft_iface); 89 90 spin_lock_init(&bat_priv->forw_bat_list_lock); 91 spin_lock_init(&bat_priv->forw_bcast_list_lock); 92 spin_lock_init(&bat_priv->tt_changes_list_lock); 93 spin_lock_init(&bat_priv->tt_req_list_lock); 94 spin_lock_init(&bat_priv->tt_roam_list_lock); 95 spin_lock_init(&bat_priv->tt_buff_lock); 96 spin_lock_init(&bat_priv->gw_list_lock); 97 spin_lock_init(&bat_priv->vis_hash_lock); 98 spin_lock_init(&bat_priv->vis_list_lock); 99 spin_lock_init(&bat_priv->softif_neigh_lock); 100 spin_lock_init(&bat_priv->softif_neigh_vid_lock); 101 102 INIT_HLIST_HEAD(&bat_priv->forw_bat_list); 103 INIT_HLIST_HEAD(&bat_priv->forw_bcast_list); 104 INIT_HLIST_HEAD(&bat_priv->gw_list); 105 INIT_HLIST_HEAD(&bat_priv->softif_neigh_vids); 106 INIT_LIST_HEAD(&bat_priv->tt_changes_list); 107 INIT_LIST_HEAD(&bat_priv->tt_req_list); 108 INIT_LIST_HEAD(&bat_priv->tt_roam_list); 109 110 if (originator_init(bat_priv) < 1) 111 goto err; 112 113 if (tt_init(bat_priv) < 1) 114 goto err; 115 116 tt_local_add(soft_iface, soft_iface->dev_addr, NULL_IFINDEX); 117 118 if (vis_init(bat_priv) < 1) 119 goto err; 120 121 atomic_set(&bat_priv->gw_reselect, 0); 122 atomic_set(&bat_priv->mesh_state, MESH_ACTIVE); 123 goto end; 124 125 err: 126 mesh_free(soft_iface); 127 return -1; 128 129 end: 130 return 0; 131 } 132 133 void mesh_free(struct net_device *soft_iface) 134 { 135 struct bat_priv *bat_priv = netdev_priv(soft_iface); 136 137 atomic_set(&bat_priv->mesh_state, MESH_DEACTIVATING); 138 139 purge_outstanding_packets(bat_priv, NULL); 140 141 vis_quit(bat_priv); 142 143 gw_node_purge(bat_priv); 144 originator_free(bat_priv); 145 146 tt_free(bat_priv); 147 148 softif_neigh_purge(bat_priv); 149 150 atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); 151 } 152 153 void inc_module_count(void) 154 { 155 try_module_get(THIS_MODULE); 156 } 157 158 void dec_module_count(void) 159 { 160 module_put(THIS_MODULE); 161 } 162 163 int is_my_mac(const uint8_t *addr) 164 { 165 const struct hard_iface *hard_iface; 166 167 rcu_read_lock(); 168 list_for_each_entry_rcu(hard_iface, &hardif_list, list) { 169 if (hard_iface->if_status != IF_ACTIVE) 170 continue; 171 172 if (compare_eth(hard_iface->net_dev->dev_addr, addr)) { 173 rcu_read_unlock(); 174 return 1; 175 } 176 } 177 rcu_read_unlock(); 178 return 0; 179 } 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 algorithm: %s\n", 205 bat_algo_ops->name); 206 goto out; 207 } 208 209 /* all algorithms must implement all ops (for now) */ 210 if (!bat_algo_ops->bat_ogm_init || 211 !bat_algo_ops->bat_ogm_init_primary || 212 !bat_algo_ops->bat_ogm_update_mac || 213 !bat_algo_ops->bat_ogm_schedule || 214 !bat_algo_ops->bat_ogm_emit || 215 !bat_algo_ops->bat_ogm_receive) { 216 pr_info("Routing algo '%s' does not implement required ops\n", 217 bat_algo_ops->name); 218 goto out; 219 } 220 221 INIT_HLIST_NODE(&bat_algo_ops->list); 222 hlist_add_head(&bat_algo_ops->list, &bat_algo_list); 223 ret = 0; 224 225 out: 226 return ret; 227 } 228 229 int bat_algo_select(struct bat_priv *bat_priv, char *name) 230 { 231 struct bat_algo_ops *bat_algo_ops; 232 int ret = -1; 233 234 bat_algo_ops = bat_algo_get(name); 235 if (!bat_algo_ops) 236 goto out; 237 238 bat_priv->bat_algo_ops = bat_algo_ops; 239 ret = 0; 240 241 out: 242 return ret; 243 } 244 245 int bat_algo_seq_print_text(struct seq_file *seq, void *offset) 246 { 247 struct bat_algo_ops *bat_algo_ops; 248 struct hlist_node *node; 249 250 seq_printf(seq, "Available routing algorithms:\n"); 251 252 hlist_for_each_entry(bat_algo_ops, node, &bat_algo_list, list) { 253 seq_printf(seq, "%s\n", bat_algo_ops->name); 254 } 255 256 return 0; 257 } 258 259 static int param_set_ra(const char *val, const struct kernel_param *kp) 260 { 261 struct bat_algo_ops *bat_algo_ops; 262 263 bat_algo_ops = bat_algo_get((char *)val); 264 if (!bat_algo_ops) { 265 pr_err("Routing algorithm '%s' is not supported\n", val); 266 return -EINVAL; 267 } 268 269 return param_set_copystring(val, kp); 270 } 271 272 static const struct kernel_param_ops param_ops_ra = { 273 .set = param_set_ra, 274 .get = param_get_string, 275 }; 276 277 static struct kparam_string __param_string_ra = { 278 .maxlen = sizeof(bat_routing_algo), 279 .string = bat_routing_algo, 280 }; 281 282 module_param_cb(routing_algo, ¶m_ops_ra, &__param_string_ra, 0644); 283 module_init(batman_init); 284 module_exit(batman_exit); 285 286 MODULE_LICENSE("GPL"); 287 288 MODULE_AUTHOR(DRIVER_AUTHOR); 289 MODULE_DESCRIPTION(DRIVER_DESC); 290 MODULE_SUPPORTED_DEVICE(DRIVER_DEVICE); 291 MODULE_VERSION(SOURCE_VERSION); 292