1 /* 2 * Copyright (C) 2009-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 /* increase the reference counter for this originator */ 23 24 #include "main.h" 25 #include "originator.h" 26 #include "hash.h" 27 #include "translation-table.h" 28 #include "routing.h" 29 #include "gateway_client.h" 30 #include "hard-interface.h" 31 #include "unicast.h" 32 #include "soft-interface.h" 33 34 static void purge_orig(struct work_struct *work); 35 36 static void start_purge_timer(struct bat_priv *bat_priv) 37 { 38 INIT_DELAYED_WORK(&bat_priv->orig_work, purge_orig); 39 queue_delayed_work(bat_event_workqueue, &bat_priv->orig_work, 1 * HZ); 40 } 41 42 int originator_init(struct bat_priv *bat_priv) 43 { 44 if (bat_priv->orig_hash) 45 return 1; 46 47 spin_lock_bh(&bat_priv->orig_hash_lock); 48 bat_priv->orig_hash = hash_new(1024); 49 50 if (!bat_priv->orig_hash) 51 goto err; 52 53 spin_unlock_bh(&bat_priv->orig_hash_lock); 54 start_purge_timer(bat_priv); 55 return 1; 56 57 err: 58 spin_unlock_bh(&bat_priv->orig_hash_lock); 59 return 0; 60 } 61 62 struct neigh_node * 63 create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, 64 uint8_t *neigh, struct batman_if *if_incoming) 65 { 66 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 67 struct neigh_node *neigh_node; 68 69 bat_dbg(DBG_BATMAN, bat_priv, 70 "Creating new last-hop neighbor of originator\n"); 71 72 neigh_node = kzalloc(sizeof(struct neigh_node), GFP_ATOMIC); 73 if (!neigh_node) 74 return NULL; 75 76 INIT_LIST_HEAD(&neigh_node->list); 77 78 memcpy(neigh_node->addr, neigh, ETH_ALEN); 79 neigh_node->orig_node = orig_neigh_node; 80 neigh_node->if_incoming = if_incoming; 81 82 list_add_tail(&neigh_node->list, &orig_node->neigh_list); 83 return neigh_node; 84 } 85 86 static void free_orig_node(void *data, void *arg) 87 { 88 struct list_head *list_pos, *list_pos_tmp; 89 struct neigh_node *neigh_node; 90 struct orig_node *orig_node = (struct orig_node *)data; 91 struct bat_priv *bat_priv = (struct bat_priv *)arg; 92 93 /* for all neighbors towards this originator ... */ 94 list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { 95 neigh_node = list_entry(list_pos, struct neigh_node, list); 96 97 list_del(list_pos); 98 kfree(neigh_node); 99 } 100 101 frag_list_free(&orig_node->frag_list); 102 hna_global_del_orig(bat_priv, orig_node, "originator timed out"); 103 104 kfree(orig_node->bcast_own); 105 kfree(orig_node->bcast_own_sum); 106 kfree(orig_node); 107 } 108 109 void originator_free(struct bat_priv *bat_priv) 110 { 111 if (!bat_priv->orig_hash) 112 return; 113 114 cancel_delayed_work_sync(&bat_priv->orig_work); 115 116 spin_lock_bh(&bat_priv->orig_hash_lock); 117 hash_delete(bat_priv->orig_hash, free_orig_node, bat_priv); 118 bat_priv->orig_hash = NULL; 119 spin_unlock_bh(&bat_priv->orig_hash_lock); 120 } 121 122 /* this function finds or creates an originator entry for the given 123 * address if it does not exits */ 124 struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr) 125 { 126 struct orig_node *orig_node; 127 int size; 128 int hash_added; 129 130 orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, 131 compare_orig, choose_orig, 132 addr)); 133 134 if (orig_node) 135 return orig_node; 136 137 bat_dbg(DBG_BATMAN, bat_priv, 138 "Creating new originator: %pM\n", addr); 139 140 orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC); 141 if (!orig_node) 142 return NULL; 143 144 INIT_LIST_HEAD(&orig_node->neigh_list); 145 146 memcpy(orig_node->orig, addr, ETH_ALEN); 147 orig_node->router = NULL; 148 orig_node->hna_buff = NULL; 149 orig_node->bcast_seqno_reset = jiffies - 1 150 - msecs_to_jiffies(RESET_PROTECTION_MS); 151 orig_node->batman_seqno_reset = jiffies - 1 152 - msecs_to_jiffies(RESET_PROTECTION_MS); 153 154 size = bat_priv->num_ifaces * sizeof(unsigned long) * NUM_WORDS; 155 156 orig_node->bcast_own = kzalloc(size, GFP_ATOMIC); 157 if (!orig_node->bcast_own) 158 goto free_orig_node; 159 160 size = bat_priv->num_ifaces * sizeof(uint8_t); 161 orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC); 162 163 INIT_LIST_HEAD(&orig_node->frag_list); 164 orig_node->last_frag_packet = 0; 165 166 if (!orig_node->bcast_own_sum) 167 goto free_bcast_own; 168 169 hash_added = hash_add(bat_priv->orig_hash, compare_orig, choose_orig, 170 orig_node); 171 if (hash_added < 0) 172 goto free_bcast_own_sum; 173 174 return orig_node; 175 free_bcast_own_sum: 176 kfree(orig_node->bcast_own_sum); 177 free_bcast_own: 178 kfree(orig_node->bcast_own); 179 free_orig_node: 180 kfree(orig_node); 181 return NULL; 182 } 183 184 static bool purge_orig_neighbors(struct bat_priv *bat_priv, 185 struct orig_node *orig_node, 186 struct neigh_node **best_neigh_node) 187 { 188 struct list_head *list_pos, *list_pos_tmp; 189 struct neigh_node *neigh_node; 190 bool neigh_purged = false; 191 192 *best_neigh_node = NULL; 193 194 /* for all neighbors towards this originator ... */ 195 list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { 196 neigh_node = list_entry(list_pos, struct neigh_node, list); 197 198 if ((time_after(jiffies, 199 neigh_node->last_valid + PURGE_TIMEOUT * HZ)) || 200 (neigh_node->if_incoming->if_status == IF_INACTIVE) || 201 (neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED)) { 202 203 if (neigh_node->if_incoming->if_status == 204 IF_TO_BE_REMOVED) 205 bat_dbg(DBG_BATMAN, bat_priv, 206 "neighbor purge: originator %pM, " 207 "neighbor: %pM, iface: %s\n", 208 orig_node->orig, neigh_node->addr, 209 neigh_node->if_incoming->net_dev->name); 210 else 211 bat_dbg(DBG_BATMAN, bat_priv, 212 "neighbor timeout: originator %pM, " 213 "neighbor: %pM, last_valid: %lu\n", 214 orig_node->orig, neigh_node->addr, 215 (neigh_node->last_valid / HZ)); 216 217 neigh_purged = true; 218 list_del(list_pos); 219 kfree(neigh_node); 220 } else { 221 if ((!*best_neigh_node) || 222 (neigh_node->tq_avg > (*best_neigh_node)->tq_avg)) 223 *best_neigh_node = neigh_node; 224 } 225 } 226 return neigh_purged; 227 } 228 229 static bool purge_orig_node(struct bat_priv *bat_priv, 230 struct orig_node *orig_node) 231 { 232 struct neigh_node *best_neigh_node; 233 234 if (time_after(jiffies, 235 orig_node->last_valid + 2 * PURGE_TIMEOUT * HZ)) { 236 237 bat_dbg(DBG_BATMAN, bat_priv, 238 "Originator timeout: originator %pM, last_valid %lu\n", 239 orig_node->orig, (orig_node->last_valid / HZ)); 240 return true; 241 } else { 242 if (purge_orig_neighbors(bat_priv, orig_node, 243 &best_neigh_node)) { 244 update_routes(bat_priv, orig_node, 245 best_neigh_node, 246 orig_node->hna_buff, 247 orig_node->hna_buff_len); 248 /* update bonding candidates, we could have lost 249 * some candidates. */ 250 update_bonding_candidates(orig_node); 251 } 252 } 253 254 return false; 255 } 256 257 static void _purge_orig(struct bat_priv *bat_priv) 258 { 259 struct hashtable_t *hash = bat_priv->orig_hash; 260 struct hlist_node *walk, *safe; 261 struct hlist_head *head; 262 struct element_t *bucket; 263 struct orig_node *orig_node; 264 int i; 265 266 if (!hash) 267 return; 268 269 spin_lock_bh(&bat_priv->orig_hash_lock); 270 271 /* for all origins... */ 272 for (i = 0; i < hash->size; i++) { 273 head = &hash->table[i]; 274 275 hlist_for_each_entry_safe(bucket, walk, safe, head, hlist) { 276 orig_node = bucket->data; 277 278 if (purge_orig_node(bat_priv, orig_node)) { 279 if (orig_node->gw_flags) 280 gw_node_delete(bat_priv, orig_node); 281 hlist_del(walk); 282 kfree(bucket); 283 free_orig_node(orig_node, bat_priv); 284 } 285 286 if (time_after(jiffies, orig_node->last_frag_packet + 287 msecs_to_jiffies(FRAG_TIMEOUT))) 288 frag_list_free(&orig_node->frag_list); 289 } 290 } 291 292 spin_unlock_bh(&bat_priv->orig_hash_lock); 293 294 gw_node_purge(bat_priv); 295 gw_election(bat_priv); 296 297 softif_neigh_purge(bat_priv); 298 } 299 300 static void purge_orig(struct work_struct *work) 301 { 302 struct delayed_work *delayed_work = 303 container_of(work, struct delayed_work, work); 304 struct bat_priv *bat_priv = 305 container_of(delayed_work, struct bat_priv, orig_work); 306 307 _purge_orig(bat_priv); 308 start_purge_timer(bat_priv); 309 } 310 311 void purge_orig_ref(struct bat_priv *bat_priv) 312 { 313 _purge_orig(bat_priv); 314 } 315 316 int orig_seq_print_text(struct seq_file *seq, void *offset) 317 { 318 struct net_device *net_dev = (struct net_device *)seq->private; 319 struct bat_priv *bat_priv = netdev_priv(net_dev); 320 struct hashtable_t *hash = bat_priv->orig_hash; 321 struct hlist_node *walk; 322 struct hlist_head *head; 323 struct element_t *bucket; 324 struct orig_node *orig_node; 325 struct neigh_node *neigh_node; 326 int batman_count = 0; 327 int last_seen_secs; 328 int last_seen_msecs; 329 int i; 330 331 if ((!bat_priv->primary_if) || 332 (bat_priv->primary_if->if_status != IF_ACTIVE)) { 333 if (!bat_priv->primary_if) 334 return seq_printf(seq, "BATMAN mesh %s disabled - " 335 "please specify interfaces to enable it\n", 336 net_dev->name); 337 338 return seq_printf(seq, "BATMAN mesh %s " 339 "disabled - primary interface not active\n", 340 net_dev->name); 341 } 342 343 seq_printf(seq, "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n", 344 SOURCE_VERSION, REVISION_VERSION_STR, 345 bat_priv->primary_if->net_dev->name, 346 bat_priv->primary_if->net_dev->dev_addr, net_dev->name); 347 seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n", 348 "Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop", 349 "outgoingIF", "Potential nexthops"); 350 351 spin_lock_bh(&bat_priv->orig_hash_lock); 352 353 for (i = 0; i < hash->size; i++) { 354 head = &hash->table[i]; 355 356 hlist_for_each_entry(bucket, walk, head, hlist) { 357 orig_node = bucket->data; 358 359 if (!orig_node->router) 360 continue; 361 362 if (orig_node->router->tq_avg == 0) 363 continue; 364 365 last_seen_secs = jiffies_to_msecs(jiffies - 366 orig_node->last_valid) / 1000; 367 last_seen_msecs = jiffies_to_msecs(jiffies - 368 orig_node->last_valid) % 1000; 369 370 neigh_node = orig_node->router; 371 seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:", 372 orig_node->orig, last_seen_secs, 373 last_seen_msecs, neigh_node->tq_avg, 374 neigh_node->addr, 375 neigh_node->if_incoming->net_dev->name); 376 377 list_for_each_entry(neigh_node, &orig_node->neigh_list, 378 list) { 379 seq_printf(seq, " %pM (%3i)", neigh_node->addr, 380 neigh_node->tq_avg); 381 } 382 383 seq_printf(seq, "\n"); 384 batman_count++; 385 } 386 } 387 388 spin_unlock_bh(&bat_priv->orig_hash_lock); 389 390 if ((batman_count == 0)) 391 seq_printf(seq, "No batman nodes in range ...\n"); 392 393 return 0; 394 } 395 396 static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) 397 { 398 void *data_ptr; 399 400 data_ptr = kmalloc(max_if_num * sizeof(unsigned long) * NUM_WORDS, 401 GFP_ATOMIC); 402 if (!data_ptr) { 403 pr_err("Can't resize orig: out of memory\n"); 404 return -1; 405 } 406 407 memcpy(data_ptr, orig_node->bcast_own, 408 (max_if_num - 1) * sizeof(unsigned long) * NUM_WORDS); 409 kfree(orig_node->bcast_own); 410 orig_node->bcast_own = data_ptr; 411 412 data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); 413 if (!data_ptr) { 414 pr_err("Can't resize orig: out of memory\n"); 415 return -1; 416 } 417 418 memcpy(data_ptr, orig_node->bcast_own_sum, 419 (max_if_num - 1) * sizeof(uint8_t)); 420 kfree(orig_node->bcast_own_sum); 421 orig_node->bcast_own_sum = data_ptr; 422 423 return 0; 424 } 425 426 int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) 427 { 428 struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); 429 struct hashtable_t *hash = bat_priv->orig_hash; 430 struct hlist_node *walk; 431 struct hlist_head *head; 432 struct element_t *bucket; 433 struct orig_node *orig_node; 434 int i; 435 436 /* resize all orig nodes because orig_node->bcast_own(_sum) depend on 437 * if_num */ 438 spin_lock_bh(&bat_priv->orig_hash_lock); 439 440 for (i = 0; i < hash->size; i++) { 441 head = &hash->table[i]; 442 443 hlist_for_each_entry(bucket, walk, head, hlist) { 444 orig_node = bucket->data; 445 446 if (orig_node_add_if(orig_node, max_if_num) == -1) 447 goto err; 448 } 449 } 450 451 spin_unlock_bh(&bat_priv->orig_hash_lock); 452 return 0; 453 454 err: 455 spin_unlock_bh(&bat_priv->orig_hash_lock); 456 return -ENOMEM; 457 } 458 459 static int orig_node_del_if(struct orig_node *orig_node, 460 int max_if_num, int del_if_num) 461 { 462 void *data_ptr = NULL; 463 int chunk_size; 464 465 /* last interface was removed */ 466 if (max_if_num == 0) 467 goto free_bcast_own; 468 469 chunk_size = sizeof(unsigned long) * NUM_WORDS; 470 data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC); 471 if (!data_ptr) { 472 pr_err("Can't resize orig: out of memory\n"); 473 return -1; 474 } 475 476 /* copy first part */ 477 memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size); 478 479 /* copy second part */ 480 memcpy(data_ptr + del_if_num * chunk_size, 481 orig_node->bcast_own + ((del_if_num + 1) * chunk_size), 482 (max_if_num - del_if_num) * chunk_size); 483 484 free_bcast_own: 485 kfree(orig_node->bcast_own); 486 orig_node->bcast_own = data_ptr; 487 488 if (max_if_num == 0) 489 goto free_own_sum; 490 491 data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); 492 if (!data_ptr) { 493 pr_err("Can't resize orig: out of memory\n"); 494 return -1; 495 } 496 497 memcpy(data_ptr, orig_node->bcast_own_sum, 498 del_if_num * sizeof(uint8_t)); 499 500 memcpy(data_ptr + del_if_num * sizeof(uint8_t), 501 orig_node->bcast_own_sum + ((del_if_num + 1) * sizeof(uint8_t)), 502 (max_if_num - del_if_num) * sizeof(uint8_t)); 503 504 free_own_sum: 505 kfree(orig_node->bcast_own_sum); 506 orig_node->bcast_own_sum = data_ptr; 507 508 return 0; 509 } 510 511 int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) 512 { 513 struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); 514 struct hashtable_t *hash = bat_priv->orig_hash; 515 struct hlist_node *walk; 516 struct hlist_head *head; 517 struct element_t *bucket; 518 struct batman_if *batman_if_tmp; 519 struct orig_node *orig_node; 520 int i, ret; 521 522 /* resize all orig nodes because orig_node->bcast_own(_sum) depend on 523 * if_num */ 524 spin_lock_bh(&bat_priv->orig_hash_lock); 525 526 for (i = 0; i < hash->size; i++) { 527 head = &hash->table[i]; 528 529 hlist_for_each_entry(bucket, walk, head, hlist) { 530 orig_node = bucket->data; 531 532 ret = orig_node_del_if(orig_node, max_if_num, 533 batman_if->if_num); 534 535 if (ret == -1) 536 goto err; 537 } 538 } 539 540 /* renumber remaining batman interfaces _inside_ of orig_hash_lock */ 541 rcu_read_lock(); 542 list_for_each_entry_rcu(batman_if_tmp, &if_list, list) { 543 if (batman_if_tmp->if_status == IF_NOT_IN_USE) 544 continue; 545 546 if (batman_if == batman_if_tmp) 547 continue; 548 549 if (batman_if->soft_iface != batman_if_tmp->soft_iface) 550 continue; 551 552 if (batman_if_tmp->if_num > batman_if->if_num) 553 batman_if_tmp->if_num--; 554 } 555 rcu_read_unlock(); 556 557 batman_if->if_num = -1; 558 spin_unlock_bh(&bat_priv->orig_hash_lock); 559 return 0; 560 561 err: 562 spin_unlock_bh(&bat_priv->orig_hash_lock); 563 return -ENOMEM; 564 } 565