1 /* 2 * Copyright (C) 2007-2011 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 "translation-table.h" 24 #include "soft-interface.h" 25 #include "hard-interface.h" 26 #include "send.h" 27 #include "hash.h" 28 #include "originator.h" 29 #include "routing.h" 30 31 #include <linux/crc16.h> 32 33 static void _tt_global_del(struct bat_priv *bat_priv, 34 struct tt_global_entry *tt_global_entry, 35 const char *message); 36 static void tt_purge(struct work_struct *work); 37 38 /* returns 1 if they are the same mac addr */ 39 static int compare_ltt(const struct hlist_node *node, const void *data2) 40 { 41 const void *data1 = container_of(node, struct tt_local_entry, 42 hash_entry); 43 44 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); 45 } 46 47 /* returns 1 if they are the same mac addr */ 48 static int compare_gtt(const struct hlist_node *node, const void *data2) 49 { 50 const void *data1 = container_of(node, struct tt_global_entry, 51 hash_entry); 52 53 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); 54 } 55 56 static void tt_start_timer(struct bat_priv *bat_priv) 57 { 58 INIT_DELAYED_WORK(&bat_priv->tt_work, tt_purge); 59 queue_delayed_work(bat_event_workqueue, &bat_priv->tt_work, 60 msecs_to_jiffies(5000)); 61 } 62 63 static struct tt_local_entry *tt_local_hash_find(struct bat_priv *bat_priv, 64 const void *data) 65 { 66 struct hashtable_t *hash = bat_priv->tt_local_hash; 67 struct hlist_head *head; 68 struct hlist_node *node; 69 struct tt_local_entry *tt_local_entry, *tt_local_entry_tmp = NULL; 70 int index; 71 72 if (!hash) 73 return NULL; 74 75 index = choose_orig(data, hash->size); 76 head = &hash->table[index]; 77 78 rcu_read_lock(); 79 hlist_for_each_entry_rcu(tt_local_entry, node, head, hash_entry) { 80 if (!compare_eth(tt_local_entry, data)) 81 continue; 82 83 if (!atomic_inc_not_zero(&tt_local_entry->refcount)) 84 continue; 85 86 tt_local_entry_tmp = tt_local_entry; 87 break; 88 } 89 rcu_read_unlock(); 90 91 return tt_local_entry_tmp; 92 } 93 94 static struct tt_global_entry *tt_global_hash_find(struct bat_priv *bat_priv, 95 const void *data) 96 { 97 struct hashtable_t *hash = bat_priv->tt_global_hash; 98 struct hlist_head *head; 99 struct hlist_node *node; 100 struct tt_global_entry *tt_global_entry; 101 struct tt_global_entry *tt_global_entry_tmp = NULL; 102 int index; 103 104 if (!hash) 105 return NULL; 106 107 index = choose_orig(data, hash->size); 108 head = &hash->table[index]; 109 110 rcu_read_lock(); 111 hlist_for_each_entry_rcu(tt_global_entry, node, head, hash_entry) { 112 if (!compare_eth(tt_global_entry, data)) 113 continue; 114 115 if (!atomic_inc_not_zero(&tt_global_entry->refcount)) 116 continue; 117 118 tt_global_entry_tmp = tt_global_entry; 119 break; 120 } 121 rcu_read_unlock(); 122 123 return tt_global_entry_tmp; 124 } 125 126 static bool is_out_of_time(unsigned long starting_time, unsigned long timeout) 127 { 128 unsigned long deadline; 129 deadline = starting_time + msecs_to_jiffies(timeout); 130 131 return time_after(jiffies, deadline); 132 } 133 134 static void tt_local_entry_free_ref(struct tt_local_entry *tt_local_entry) 135 { 136 if (atomic_dec_and_test(&tt_local_entry->refcount)) 137 kfree_rcu(tt_local_entry, rcu); 138 } 139 140 static void tt_global_entry_free_ref(struct tt_global_entry *tt_global_entry) 141 { 142 if (atomic_dec_and_test(&tt_global_entry->refcount)) 143 kfree_rcu(tt_global_entry, rcu); 144 } 145 146 static void tt_local_event(struct bat_priv *bat_priv, const uint8_t *addr, 147 uint8_t flags) 148 { 149 struct tt_change_node *tt_change_node; 150 151 tt_change_node = kmalloc(sizeof(*tt_change_node), GFP_ATOMIC); 152 153 if (!tt_change_node) 154 return; 155 156 tt_change_node->change.flags = flags; 157 memcpy(tt_change_node->change.addr, addr, ETH_ALEN); 158 159 spin_lock_bh(&bat_priv->tt_changes_list_lock); 160 /* track the change in the OGMinterval list */ 161 list_add_tail(&tt_change_node->list, &bat_priv->tt_changes_list); 162 atomic_inc(&bat_priv->tt_local_changes); 163 spin_unlock_bh(&bat_priv->tt_changes_list_lock); 164 165 atomic_set(&bat_priv->tt_ogm_append_cnt, 0); 166 } 167 168 int tt_len(int changes_num) 169 { 170 return changes_num * sizeof(struct tt_change); 171 } 172 173 static int tt_local_init(struct bat_priv *bat_priv) 174 { 175 if (bat_priv->tt_local_hash) 176 return 1; 177 178 bat_priv->tt_local_hash = hash_new(1024); 179 180 if (!bat_priv->tt_local_hash) 181 return 0; 182 183 return 1; 184 } 185 186 void tt_local_add(struct net_device *soft_iface, const uint8_t *addr) 187 { 188 struct bat_priv *bat_priv = netdev_priv(soft_iface); 189 struct tt_local_entry *tt_local_entry = NULL; 190 struct tt_global_entry *tt_global_entry = NULL; 191 192 tt_local_entry = tt_local_hash_find(bat_priv, addr); 193 194 if (tt_local_entry) { 195 tt_local_entry->last_seen = jiffies; 196 goto out; 197 } 198 199 tt_local_entry = kmalloc(sizeof(*tt_local_entry), GFP_ATOMIC); 200 if (!tt_local_entry) 201 goto out; 202 203 bat_dbg(DBG_TT, bat_priv, 204 "Creating new local tt entry: %pM (ttvn: %d)\n", addr, 205 (uint8_t)atomic_read(&bat_priv->ttvn)); 206 207 memcpy(tt_local_entry->addr, addr, ETH_ALEN); 208 tt_local_entry->last_seen = jiffies; 209 tt_local_entry->flags = NO_FLAGS; 210 atomic_set(&tt_local_entry->refcount, 2); 211 212 /* the batman interface mac address should never be purged */ 213 if (compare_eth(addr, soft_iface->dev_addr)) 214 tt_local_entry->flags |= TT_CLIENT_NOPURGE; 215 216 tt_local_event(bat_priv, addr, tt_local_entry->flags); 217 218 /* The local entry has to be marked as NEW to avoid to send it in 219 * a full table response going out before the next ttvn increment 220 * (consistency check) */ 221 tt_local_entry->flags |= TT_CLIENT_NEW; 222 223 hash_add(bat_priv->tt_local_hash, compare_ltt, choose_orig, 224 tt_local_entry, &tt_local_entry->hash_entry); 225 226 /* remove address from global hash if present */ 227 tt_global_entry = tt_global_hash_find(bat_priv, addr); 228 229 /* Check whether it is a roaming! */ 230 if (tt_global_entry) { 231 /* This node is probably going to update its tt table */ 232 tt_global_entry->orig_node->tt_poss_change = true; 233 /* The global entry has to be marked as PENDING and has to be 234 * kept for consistency purpose */ 235 tt_global_entry->flags |= TT_CLIENT_PENDING; 236 send_roam_adv(bat_priv, tt_global_entry->addr, 237 tt_global_entry->orig_node); 238 } 239 out: 240 if (tt_local_entry) 241 tt_local_entry_free_ref(tt_local_entry); 242 if (tt_global_entry) 243 tt_global_entry_free_ref(tt_global_entry); 244 } 245 246 int tt_changes_fill_buffer(struct bat_priv *bat_priv, 247 unsigned char *buff, int buff_len) 248 { 249 int count = 0, tot_changes = 0; 250 struct tt_change_node *entry, *safe; 251 252 if (buff_len > 0) 253 tot_changes = buff_len / tt_len(1); 254 255 spin_lock_bh(&bat_priv->tt_changes_list_lock); 256 atomic_set(&bat_priv->tt_local_changes, 0); 257 258 list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, 259 list) { 260 if (count < tot_changes) { 261 memcpy(buff + tt_len(count), 262 &entry->change, sizeof(struct tt_change)); 263 count++; 264 } 265 list_del(&entry->list); 266 kfree(entry); 267 } 268 spin_unlock_bh(&bat_priv->tt_changes_list_lock); 269 270 /* Keep the buffer for possible tt_request */ 271 spin_lock_bh(&bat_priv->tt_buff_lock); 272 kfree(bat_priv->tt_buff); 273 bat_priv->tt_buff_len = 0; 274 bat_priv->tt_buff = NULL; 275 /* We check whether this new OGM has no changes due to size 276 * problems */ 277 if (buff_len > 0) { 278 /** 279 * if kmalloc() fails we will reply with the full table 280 * instead of providing the diff 281 */ 282 bat_priv->tt_buff = kmalloc(buff_len, GFP_ATOMIC); 283 if (bat_priv->tt_buff) { 284 memcpy(bat_priv->tt_buff, buff, buff_len); 285 bat_priv->tt_buff_len = buff_len; 286 } 287 } 288 spin_unlock_bh(&bat_priv->tt_buff_lock); 289 290 return tot_changes; 291 } 292 293 int tt_local_seq_print_text(struct seq_file *seq, void *offset) 294 { 295 struct net_device *net_dev = (struct net_device *)seq->private; 296 struct bat_priv *bat_priv = netdev_priv(net_dev); 297 struct hashtable_t *hash = bat_priv->tt_local_hash; 298 struct tt_local_entry *tt_local_entry; 299 struct hard_iface *primary_if; 300 struct hlist_node *node; 301 struct hlist_head *head; 302 size_t buf_size, pos; 303 char *buff; 304 int i, ret = 0; 305 306 primary_if = primary_if_get_selected(bat_priv); 307 if (!primary_if) { 308 ret = seq_printf(seq, "BATMAN mesh %s disabled - " 309 "please specify interfaces to enable it\n", 310 net_dev->name); 311 goto out; 312 } 313 314 if (primary_if->if_status != IF_ACTIVE) { 315 ret = seq_printf(seq, "BATMAN mesh %s disabled - " 316 "primary interface not active\n", 317 net_dev->name); 318 goto out; 319 } 320 321 seq_printf(seq, "Locally retrieved addresses (from %s) " 322 "announced via TT (TTVN: %u):\n", 323 net_dev->name, (uint8_t)atomic_read(&bat_priv->ttvn)); 324 325 buf_size = 1; 326 /* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */ 327 for (i = 0; i < hash->size; i++) { 328 head = &hash->table[i]; 329 330 rcu_read_lock(); 331 __hlist_for_each_rcu(node, head) 332 buf_size += 21; 333 rcu_read_unlock(); 334 } 335 336 buff = kmalloc(buf_size, GFP_ATOMIC); 337 if (!buff) { 338 ret = -ENOMEM; 339 goto out; 340 } 341 342 buff[0] = '\0'; 343 pos = 0; 344 345 for (i = 0; i < hash->size; i++) { 346 head = &hash->table[i]; 347 348 rcu_read_lock(); 349 hlist_for_each_entry_rcu(tt_local_entry, node, 350 head, hash_entry) { 351 pos += snprintf(buff + pos, 22, " * %pM\n", 352 tt_local_entry->addr); 353 } 354 rcu_read_unlock(); 355 } 356 357 seq_printf(seq, "%s", buff); 358 kfree(buff); 359 out: 360 if (primary_if) 361 hardif_free_ref(primary_if); 362 return ret; 363 } 364 365 static void tt_local_set_pending(struct bat_priv *bat_priv, 366 struct tt_local_entry *tt_local_entry, 367 uint16_t flags) 368 { 369 tt_local_event(bat_priv, tt_local_entry->addr, 370 tt_local_entry->flags | flags); 371 372 /* The local client has to be merked as "pending to be removed" but has 373 * to be kept in the table in order to send it in an full tables 374 * response issued before the net ttvn increment (consistency check) */ 375 tt_local_entry->flags |= TT_CLIENT_PENDING; 376 } 377 378 void tt_local_remove(struct bat_priv *bat_priv, const uint8_t *addr, 379 const char *message, bool roaming) 380 { 381 struct tt_local_entry *tt_local_entry = NULL; 382 383 tt_local_entry = tt_local_hash_find(bat_priv, addr); 384 if (!tt_local_entry) 385 goto out; 386 387 tt_local_set_pending(bat_priv, tt_local_entry, TT_CLIENT_DEL | 388 (roaming ? TT_CLIENT_ROAM : NO_FLAGS)); 389 390 bat_dbg(DBG_TT, bat_priv, "Local tt entry (%pM) pending to be removed: " 391 "%s\n", tt_local_entry->addr, message); 392 out: 393 if (tt_local_entry) 394 tt_local_entry_free_ref(tt_local_entry); 395 } 396 397 static void tt_local_purge(struct bat_priv *bat_priv) 398 { 399 struct hashtable_t *hash = bat_priv->tt_local_hash; 400 struct tt_local_entry *tt_local_entry; 401 struct hlist_node *node, *node_tmp; 402 struct hlist_head *head; 403 spinlock_t *list_lock; /* protects write access to the hash lists */ 404 int i; 405 406 for (i = 0; i < hash->size; i++) { 407 head = &hash->table[i]; 408 list_lock = &hash->list_locks[i]; 409 410 spin_lock_bh(list_lock); 411 hlist_for_each_entry_safe(tt_local_entry, node, node_tmp, 412 head, hash_entry) { 413 if (tt_local_entry->flags & TT_CLIENT_NOPURGE) 414 continue; 415 416 /* entry already marked for deletion */ 417 if (tt_local_entry->flags & TT_CLIENT_PENDING) 418 continue; 419 420 if (!is_out_of_time(tt_local_entry->last_seen, 421 TT_LOCAL_TIMEOUT * 1000)) 422 continue; 423 424 tt_local_set_pending(bat_priv, tt_local_entry, 425 TT_CLIENT_DEL); 426 bat_dbg(DBG_TT, bat_priv, "Local tt entry (%pM) " 427 "pending to be removed: timed out\n", 428 tt_local_entry->addr); 429 } 430 spin_unlock_bh(list_lock); 431 } 432 433 } 434 435 static void tt_local_table_free(struct bat_priv *bat_priv) 436 { 437 struct hashtable_t *hash; 438 spinlock_t *list_lock; /* protects write access to the hash lists */ 439 struct tt_local_entry *tt_local_entry; 440 struct hlist_node *node, *node_tmp; 441 struct hlist_head *head; 442 int i; 443 444 if (!bat_priv->tt_local_hash) 445 return; 446 447 hash = bat_priv->tt_local_hash; 448 449 for (i = 0; i < hash->size; i++) { 450 head = &hash->table[i]; 451 list_lock = &hash->list_locks[i]; 452 453 spin_lock_bh(list_lock); 454 hlist_for_each_entry_safe(tt_local_entry, node, node_tmp, 455 head, hash_entry) { 456 hlist_del_rcu(node); 457 tt_local_entry_free_ref(tt_local_entry); 458 } 459 spin_unlock_bh(list_lock); 460 } 461 462 hash_destroy(hash); 463 464 bat_priv->tt_local_hash = NULL; 465 } 466 467 static int tt_global_init(struct bat_priv *bat_priv) 468 { 469 if (bat_priv->tt_global_hash) 470 return 1; 471 472 bat_priv->tt_global_hash = hash_new(1024); 473 474 if (!bat_priv->tt_global_hash) 475 return 0; 476 477 return 1; 478 } 479 480 static void tt_changes_list_free(struct bat_priv *bat_priv) 481 { 482 struct tt_change_node *entry, *safe; 483 484 spin_lock_bh(&bat_priv->tt_changes_list_lock); 485 486 list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, 487 list) { 488 list_del(&entry->list); 489 kfree(entry); 490 } 491 492 atomic_set(&bat_priv->tt_local_changes, 0); 493 spin_unlock_bh(&bat_priv->tt_changes_list_lock); 494 } 495 496 /* caller must hold orig_node refcount */ 497 int tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node, 498 const unsigned char *tt_addr, uint8_t ttvn, bool roaming) 499 { 500 struct tt_global_entry *tt_global_entry; 501 struct orig_node *orig_node_tmp; 502 int ret = 0; 503 504 tt_global_entry = tt_global_hash_find(bat_priv, tt_addr); 505 506 if (!tt_global_entry) { 507 tt_global_entry = 508 kmalloc(sizeof(*tt_global_entry), 509 GFP_ATOMIC); 510 if (!tt_global_entry) 511 goto out; 512 513 memcpy(tt_global_entry->addr, tt_addr, ETH_ALEN); 514 /* Assign the new orig_node */ 515 atomic_inc(&orig_node->refcount); 516 tt_global_entry->orig_node = orig_node; 517 tt_global_entry->ttvn = ttvn; 518 tt_global_entry->flags = NO_FLAGS; 519 tt_global_entry->roam_at = 0; 520 atomic_set(&tt_global_entry->refcount, 2); 521 522 hash_add(bat_priv->tt_global_hash, compare_gtt, 523 choose_orig, tt_global_entry, 524 &tt_global_entry->hash_entry); 525 atomic_inc(&orig_node->tt_size); 526 } else { 527 if (tt_global_entry->orig_node != orig_node) { 528 atomic_dec(&tt_global_entry->orig_node->tt_size); 529 orig_node_tmp = tt_global_entry->orig_node; 530 atomic_inc(&orig_node->refcount); 531 tt_global_entry->orig_node = orig_node; 532 orig_node_free_ref(orig_node_tmp); 533 atomic_inc(&orig_node->tt_size); 534 } 535 tt_global_entry->ttvn = ttvn; 536 tt_global_entry->flags = NO_FLAGS; 537 tt_global_entry->roam_at = 0; 538 } 539 540 bat_dbg(DBG_TT, bat_priv, 541 "Creating new global tt entry: %pM (via %pM)\n", 542 tt_global_entry->addr, orig_node->orig); 543 544 /* remove address from local hash if present */ 545 tt_local_remove(bat_priv, tt_global_entry->addr, 546 "global tt received", roaming); 547 ret = 1; 548 out: 549 if (tt_global_entry) 550 tt_global_entry_free_ref(tt_global_entry); 551 return ret; 552 } 553 554 int tt_global_seq_print_text(struct seq_file *seq, void *offset) 555 { 556 struct net_device *net_dev = (struct net_device *)seq->private; 557 struct bat_priv *bat_priv = netdev_priv(net_dev); 558 struct hashtable_t *hash = bat_priv->tt_global_hash; 559 struct tt_global_entry *tt_global_entry; 560 struct hard_iface *primary_if; 561 struct hlist_node *node; 562 struct hlist_head *head; 563 size_t buf_size, pos; 564 char *buff; 565 int i, ret = 0; 566 567 primary_if = primary_if_get_selected(bat_priv); 568 if (!primary_if) { 569 ret = seq_printf(seq, "BATMAN mesh %s disabled - please " 570 "specify interfaces to enable it\n", 571 net_dev->name); 572 goto out; 573 } 574 575 if (primary_if->if_status != IF_ACTIVE) { 576 ret = seq_printf(seq, "BATMAN mesh %s disabled - " 577 "primary interface not active\n", 578 net_dev->name); 579 goto out; 580 } 581 582 seq_printf(seq, 583 "Globally announced TT entries received via the mesh %s\n", 584 net_dev->name); 585 seq_printf(seq, " %-13s %s %-15s %s\n", 586 "Client", "(TTVN)", "Originator", "(Curr TTVN)"); 587 588 buf_size = 1; 589 /* Estimate length for: " * xx:xx:xx:xx:xx:xx (ttvn) via 590 * xx:xx:xx:xx:xx:xx (cur_ttvn)\n"*/ 591 for (i = 0; i < hash->size; i++) { 592 head = &hash->table[i]; 593 594 rcu_read_lock(); 595 __hlist_for_each_rcu(node, head) 596 buf_size += 59; 597 rcu_read_unlock(); 598 } 599 600 buff = kmalloc(buf_size, GFP_ATOMIC); 601 if (!buff) { 602 ret = -ENOMEM; 603 goto out; 604 } 605 606 buff[0] = '\0'; 607 pos = 0; 608 609 for (i = 0; i < hash->size; i++) { 610 head = &hash->table[i]; 611 612 rcu_read_lock(); 613 hlist_for_each_entry_rcu(tt_global_entry, node, 614 head, hash_entry) { 615 pos += snprintf(buff + pos, 61, 616 " * %pM (%3u) via %pM (%3u)\n", 617 tt_global_entry->addr, 618 tt_global_entry->ttvn, 619 tt_global_entry->orig_node->orig, 620 (uint8_t) atomic_read( 621 &tt_global_entry->orig_node-> 622 last_ttvn)); 623 } 624 rcu_read_unlock(); 625 } 626 627 seq_printf(seq, "%s", buff); 628 kfree(buff); 629 out: 630 if (primary_if) 631 hardif_free_ref(primary_if); 632 return ret; 633 } 634 635 static void _tt_global_del(struct bat_priv *bat_priv, 636 struct tt_global_entry *tt_global_entry, 637 const char *message) 638 { 639 if (!tt_global_entry) 640 goto out; 641 642 bat_dbg(DBG_TT, bat_priv, 643 "Deleting global tt entry %pM (via %pM): %s\n", 644 tt_global_entry->addr, tt_global_entry->orig_node->orig, 645 message); 646 647 atomic_dec(&tt_global_entry->orig_node->tt_size); 648 649 hash_remove(bat_priv->tt_global_hash, compare_gtt, choose_orig, 650 tt_global_entry->addr); 651 out: 652 if (tt_global_entry) 653 tt_global_entry_free_ref(tt_global_entry); 654 } 655 656 void tt_global_del(struct bat_priv *bat_priv, 657 struct orig_node *orig_node, const unsigned char *addr, 658 const char *message, bool roaming) 659 { 660 struct tt_global_entry *tt_global_entry = NULL; 661 662 tt_global_entry = tt_global_hash_find(bat_priv, addr); 663 if (!tt_global_entry) 664 goto out; 665 666 if (tt_global_entry->orig_node == orig_node) { 667 if (roaming) { 668 tt_global_entry->flags |= TT_CLIENT_ROAM; 669 tt_global_entry->roam_at = jiffies; 670 goto out; 671 } 672 _tt_global_del(bat_priv, tt_global_entry, message); 673 } 674 out: 675 if (tt_global_entry) 676 tt_global_entry_free_ref(tt_global_entry); 677 } 678 679 void tt_global_del_orig(struct bat_priv *bat_priv, 680 struct orig_node *orig_node, const char *message) 681 { 682 struct tt_global_entry *tt_global_entry; 683 int i; 684 struct hashtable_t *hash = bat_priv->tt_global_hash; 685 struct hlist_node *node, *safe; 686 struct hlist_head *head; 687 spinlock_t *list_lock; /* protects write access to the hash lists */ 688 689 for (i = 0; i < hash->size; i++) { 690 head = &hash->table[i]; 691 list_lock = &hash->list_locks[i]; 692 693 spin_lock_bh(list_lock); 694 hlist_for_each_entry_safe(tt_global_entry, node, safe, 695 head, hash_entry) { 696 if (tt_global_entry->orig_node == orig_node) { 697 bat_dbg(DBG_TT, bat_priv, 698 "Deleting global tt entry %pM " 699 "(via %pM): originator time out\n", 700 tt_global_entry->addr, 701 tt_global_entry->orig_node->orig); 702 hlist_del_rcu(node); 703 tt_global_entry_free_ref(tt_global_entry); 704 } 705 } 706 spin_unlock_bh(list_lock); 707 } 708 atomic_set(&orig_node->tt_size, 0); 709 } 710 711 static void tt_global_roam_purge(struct bat_priv *bat_priv) 712 { 713 struct hashtable_t *hash = bat_priv->tt_global_hash; 714 struct tt_global_entry *tt_global_entry; 715 struct hlist_node *node, *node_tmp; 716 struct hlist_head *head; 717 spinlock_t *list_lock; /* protects write access to the hash lists */ 718 int i; 719 720 for (i = 0; i < hash->size; i++) { 721 head = &hash->table[i]; 722 list_lock = &hash->list_locks[i]; 723 724 spin_lock_bh(list_lock); 725 hlist_for_each_entry_safe(tt_global_entry, node, node_tmp, 726 head, hash_entry) { 727 if (!(tt_global_entry->flags & TT_CLIENT_ROAM)) 728 continue; 729 if (!is_out_of_time(tt_global_entry->roam_at, 730 TT_CLIENT_ROAM_TIMEOUT * 1000)) 731 continue; 732 733 bat_dbg(DBG_TT, bat_priv, "Deleting global " 734 "tt entry (%pM): Roaming timeout\n", 735 tt_global_entry->addr); 736 atomic_dec(&tt_global_entry->orig_node->tt_size); 737 hlist_del_rcu(node); 738 tt_global_entry_free_ref(tt_global_entry); 739 } 740 spin_unlock_bh(list_lock); 741 } 742 743 } 744 745 static void tt_global_table_free(struct bat_priv *bat_priv) 746 { 747 struct hashtable_t *hash; 748 spinlock_t *list_lock; /* protects write access to the hash lists */ 749 struct tt_global_entry *tt_global_entry; 750 struct hlist_node *node, *node_tmp; 751 struct hlist_head *head; 752 int i; 753 754 if (!bat_priv->tt_global_hash) 755 return; 756 757 hash = bat_priv->tt_global_hash; 758 759 for (i = 0; i < hash->size; i++) { 760 head = &hash->table[i]; 761 list_lock = &hash->list_locks[i]; 762 763 spin_lock_bh(list_lock); 764 hlist_for_each_entry_safe(tt_global_entry, node, node_tmp, 765 head, hash_entry) { 766 hlist_del_rcu(node); 767 tt_global_entry_free_ref(tt_global_entry); 768 } 769 spin_unlock_bh(list_lock); 770 } 771 772 hash_destroy(hash); 773 774 bat_priv->tt_global_hash = NULL; 775 } 776 777 struct orig_node *transtable_search(struct bat_priv *bat_priv, 778 const uint8_t *addr) 779 { 780 struct tt_global_entry *tt_global_entry; 781 struct orig_node *orig_node = NULL; 782 783 tt_global_entry = tt_global_hash_find(bat_priv, addr); 784 785 if (!tt_global_entry) 786 goto out; 787 788 if (!atomic_inc_not_zero(&tt_global_entry->orig_node->refcount)) 789 goto free_tt; 790 791 /* A global client marked as PENDING has already moved from that 792 * originator */ 793 if (tt_global_entry->flags & TT_CLIENT_PENDING) 794 goto free_tt; 795 796 orig_node = tt_global_entry->orig_node; 797 798 free_tt: 799 tt_global_entry_free_ref(tt_global_entry); 800 out: 801 return orig_node; 802 } 803 804 /* Calculates the checksum of the local table of a given orig_node */ 805 uint16_t tt_global_crc(struct bat_priv *bat_priv, struct orig_node *orig_node) 806 { 807 uint16_t total = 0, total_one; 808 struct hashtable_t *hash = bat_priv->tt_global_hash; 809 struct tt_global_entry *tt_global_entry; 810 struct hlist_node *node; 811 struct hlist_head *head; 812 int i, j; 813 814 for (i = 0; i < hash->size; i++) { 815 head = &hash->table[i]; 816 817 rcu_read_lock(); 818 hlist_for_each_entry_rcu(tt_global_entry, node, 819 head, hash_entry) { 820 if (compare_eth(tt_global_entry->orig_node, 821 orig_node)) { 822 /* Roaming clients are in the global table for 823 * consistency only. They don't have to be 824 * taken into account while computing the 825 * global crc */ 826 if (tt_global_entry->flags & TT_CLIENT_ROAM) 827 continue; 828 total_one = 0; 829 for (j = 0; j < ETH_ALEN; j++) 830 total_one = crc16_byte(total_one, 831 tt_global_entry->addr[j]); 832 total ^= total_one; 833 } 834 } 835 rcu_read_unlock(); 836 } 837 838 return total; 839 } 840 841 /* Calculates the checksum of the local table */ 842 uint16_t tt_local_crc(struct bat_priv *bat_priv) 843 { 844 uint16_t total = 0, total_one; 845 struct hashtable_t *hash = bat_priv->tt_local_hash; 846 struct tt_local_entry *tt_local_entry; 847 struct hlist_node *node; 848 struct hlist_head *head; 849 int i, j; 850 851 for (i = 0; i < hash->size; i++) { 852 head = &hash->table[i]; 853 854 rcu_read_lock(); 855 hlist_for_each_entry_rcu(tt_local_entry, node, 856 head, hash_entry) { 857 /* not yet committed clients have not to be taken into 858 * account while computing the CRC */ 859 if (tt_local_entry->flags & TT_CLIENT_NEW) 860 continue; 861 total_one = 0; 862 for (j = 0; j < ETH_ALEN; j++) 863 total_one = crc16_byte(total_one, 864 tt_local_entry->addr[j]); 865 total ^= total_one; 866 } 867 rcu_read_unlock(); 868 } 869 870 return total; 871 } 872 873 static void tt_req_list_free(struct bat_priv *bat_priv) 874 { 875 struct tt_req_node *node, *safe; 876 877 spin_lock_bh(&bat_priv->tt_req_list_lock); 878 879 list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { 880 list_del(&node->list); 881 kfree(node); 882 } 883 884 spin_unlock_bh(&bat_priv->tt_req_list_lock); 885 } 886 887 void tt_save_orig_buffer(struct bat_priv *bat_priv, struct orig_node *orig_node, 888 const unsigned char *tt_buff, uint8_t tt_num_changes) 889 { 890 uint16_t tt_buff_len = tt_len(tt_num_changes); 891 892 /* Replace the old buffer only if I received something in the 893 * last OGM (the OGM could carry no changes) */ 894 spin_lock_bh(&orig_node->tt_buff_lock); 895 if (tt_buff_len > 0) { 896 kfree(orig_node->tt_buff); 897 orig_node->tt_buff_len = 0; 898 orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC); 899 if (orig_node->tt_buff) { 900 memcpy(orig_node->tt_buff, tt_buff, tt_buff_len); 901 orig_node->tt_buff_len = tt_buff_len; 902 } 903 } 904 spin_unlock_bh(&orig_node->tt_buff_lock); 905 } 906 907 static void tt_req_purge(struct bat_priv *bat_priv) 908 { 909 struct tt_req_node *node, *safe; 910 911 spin_lock_bh(&bat_priv->tt_req_list_lock); 912 list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { 913 if (is_out_of_time(node->issued_at, 914 TT_REQUEST_TIMEOUT * 1000)) { 915 list_del(&node->list); 916 kfree(node); 917 } 918 } 919 spin_unlock_bh(&bat_priv->tt_req_list_lock); 920 } 921 922 /* returns the pointer to the new tt_req_node struct if no request 923 * has already been issued for this orig_node, NULL otherwise */ 924 static struct tt_req_node *new_tt_req_node(struct bat_priv *bat_priv, 925 struct orig_node *orig_node) 926 { 927 struct tt_req_node *tt_req_node_tmp, *tt_req_node = NULL; 928 929 spin_lock_bh(&bat_priv->tt_req_list_lock); 930 list_for_each_entry(tt_req_node_tmp, &bat_priv->tt_req_list, list) { 931 if (compare_eth(tt_req_node_tmp, orig_node) && 932 !is_out_of_time(tt_req_node_tmp->issued_at, 933 TT_REQUEST_TIMEOUT * 1000)) 934 goto unlock; 935 } 936 937 tt_req_node = kmalloc(sizeof(*tt_req_node), GFP_ATOMIC); 938 if (!tt_req_node) 939 goto unlock; 940 941 memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN); 942 tt_req_node->issued_at = jiffies; 943 944 list_add(&tt_req_node->list, &bat_priv->tt_req_list); 945 unlock: 946 spin_unlock_bh(&bat_priv->tt_req_list_lock); 947 return tt_req_node; 948 } 949 950 /* data_ptr is useless here, but has to be kept to respect the prototype */ 951 static int tt_local_valid_entry(const void *entry_ptr, const void *data_ptr) 952 { 953 const struct tt_local_entry *tt_local_entry = entry_ptr; 954 955 if (tt_local_entry->flags & TT_CLIENT_NEW) 956 return 0; 957 return 1; 958 } 959 960 static int tt_global_valid_entry(const void *entry_ptr, const void *data_ptr) 961 { 962 const struct tt_global_entry *tt_global_entry = entry_ptr; 963 const struct orig_node *orig_node = data_ptr; 964 965 if (tt_global_entry->flags & TT_CLIENT_ROAM) 966 return 0; 967 968 return (tt_global_entry->orig_node == orig_node); 969 } 970 971 static struct sk_buff *tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, 972 struct hashtable_t *hash, 973 struct hard_iface *primary_if, 974 int (*valid_cb)(const void *, 975 const void *), 976 void *cb_data) 977 { 978 struct tt_local_entry *tt_local_entry; 979 struct tt_query_packet *tt_response; 980 struct tt_change *tt_change; 981 struct hlist_node *node; 982 struct hlist_head *head; 983 struct sk_buff *skb = NULL; 984 uint16_t tt_tot, tt_count; 985 ssize_t tt_query_size = sizeof(struct tt_query_packet); 986 int i; 987 988 if (tt_query_size + tt_len > primary_if->soft_iface->mtu) { 989 tt_len = primary_if->soft_iface->mtu - tt_query_size; 990 tt_len -= tt_len % sizeof(struct tt_change); 991 } 992 tt_tot = tt_len / sizeof(struct tt_change); 993 994 skb = dev_alloc_skb(tt_query_size + tt_len + ETH_HLEN); 995 if (!skb) 996 goto out; 997 998 skb_reserve(skb, ETH_HLEN); 999 tt_response = (struct tt_query_packet *)skb_put(skb, 1000 tt_query_size + tt_len); 1001 tt_response->ttvn = ttvn; 1002 tt_response->tt_data = htons(tt_tot); 1003 1004 tt_change = (struct tt_change *)(skb->data + tt_query_size); 1005 tt_count = 0; 1006 1007 rcu_read_lock(); 1008 for (i = 0; i < hash->size; i++) { 1009 head = &hash->table[i]; 1010 1011 hlist_for_each_entry_rcu(tt_local_entry, node, 1012 head, hash_entry) { 1013 if (tt_count == tt_tot) 1014 break; 1015 1016 if ((valid_cb) && (!valid_cb(tt_local_entry, cb_data))) 1017 continue; 1018 1019 memcpy(tt_change->addr, tt_local_entry->addr, ETH_ALEN); 1020 tt_change->flags = NO_FLAGS; 1021 1022 tt_count++; 1023 tt_change++; 1024 } 1025 } 1026 rcu_read_unlock(); 1027 1028 out: 1029 return skb; 1030 } 1031 1032 int send_tt_request(struct bat_priv *bat_priv, struct orig_node *dst_orig_node, 1033 uint8_t ttvn, uint16_t tt_crc, bool full_table) 1034 { 1035 struct sk_buff *skb = NULL; 1036 struct tt_query_packet *tt_request; 1037 struct neigh_node *neigh_node = NULL; 1038 struct hard_iface *primary_if; 1039 struct tt_req_node *tt_req_node = NULL; 1040 int ret = 1; 1041 1042 primary_if = primary_if_get_selected(bat_priv); 1043 if (!primary_if) 1044 goto out; 1045 1046 /* The new tt_req will be issued only if I'm not waiting for a 1047 * reply from the same orig_node yet */ 1048 tt_req_node = new_tt_req_node(bat_priv, dst_orig_node); 1049 if (!tt_req_node) 1050 goto out; 1051 1052 skb = dev_alloc_skb(sizeof(struct tt_query_packet) + ETH_HLEN); 1053 if (!skb) 1054 goto out; 1055 1056 skb_reserve(skb, ETH_HLEN); 1057 1058 tt_request = (struct tt_query_packet *)skb_put(skb, 1059 sizeof(struct tt_query_packet)); 1060 1061 tt_request->packet_type = BAT_TT_QUERY; 1062 tt_request->version = COMPAT_VERSION; 1063 memcpy(tt_request->src, primary_if->net_dev->dev_addr, ETH_ALEN); 1064 memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN); 1065 tt_request->ttl = TTL; 1066 tt_request->ttvn = ttvn; 1067 tt_request->tt_data = tt_crc; 1068 tt_request->flags = TT_REQUEST; 1069 1070 if (full_table) 1071 tt_request->flags |= TT_FULL_TABLE; 1072 1073 neigh_node = orig_node_get_router(dst_orig_node); 1074 if (!neigh_node) 1075 goto out; 1076 1077 bat_dbg(DBG_TT, bat_priv, "Sending TT_REQUEST to %pM via %pM " 1078 "[%c]\n", dst_orig_node->orig, neigh_node->addr, 1079 (full_table ? 'F' : '.')); 1080 1081 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 1082 ret = 0; 1083 1084 out: 1085 if (neigh_node) 1086 neigh_node_free_ref(neigh_node); 1087 if (primary_if) 1088 hardif_free_ref(primary_if); 1089 if (ret) 1090 kfree_skb(skb); 1091 if (ret && tt_req_node) { 1092 spin_lock_bh(&bat_priv->tt_req_list_lock); 1093 list_del(&tt_req_node->list); 1094 spin_unlock_bh(&bat_priv->tt_req_list_lock); 1095 kfree(tt_req_node); 1096 } 1097 return ret; 1098 } 1099 1100 static bool send_other_tt_response(struct bat_priv *bat_priv, 1101 struct tt_query_packet *tt_request) 1102 { 1103 struct orig_node *req_dst_orig_node = NULL, *res_dst_orig_node = NULL; 1104 struct neigh_node *neigh_node = NULL; 1105 struct hard_iface *primary_if = NULL; 1106 uint8_t orig_ttvn, req_ttvn, ttvn; 1107 int ret = false; 1108 unsigned char *tt_buff; 1109 bool full_table; 1110 uint16_t tt_len, tt_tot; 1111 struct sk_buff *skb = NULL; 1112 struct tt_query_packet *tt_response; 1113 1114 bat_dbg(DBG_TT, bat_priv, 1115 "Received TT_REQUEST from %pM for " 1116 "ttvn: %u (%pM) [%c]\n", tt_request->src, 1117 tt_request->ttvn, tt_request->dst, 1118 (tt_request->flags & TT_FULL_TABLE ? 'F' : '.')); 1119 1120 /* Let's get the orig node of the REAL destination */ 1121 req_dst_orig_node = get_orig_node(bat_priv, tt_request->dst); 1122 if (!req_dst_orig_node) 1123 goto out; 1124 1125 res_dst_orig_node = get_orig_node(bat_priv, tt_request->src); 1126 if (!res_dst_orig_node) 1127 goto out; 1128 1129 neigh_node = orig_node_get_router(res_dst_orig_node); 1130 if (!neigh_node) 1131 goto out; 1132 1133 primary_if = primary_if_get_selected(bat_priv); 1134 if (!primary_if) 1135 goto out; 1136 1137 orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn); 1138 req_ttvn = tt_request->ttvn; 1139 1140 /* I have not the requested data */ 1141 if (orig_ttvn != req_ttvn || 1142 tt_request->tt_data != req_dst_orig_node->tt_crc) 1143 goto out; 1144 1145 /* If it has explicitly been requested the full table */ 1146 if (tt_request->flags & TT_FULL_TABLE || 1147 !req_dst_orig_node->tt_buff) 1148 full_table = true; 1149 else 1150 full_table = false; 1151 1152 /* In this version, fragmentation is not implemented, then 1153 * I'll send only one packet with as much TT entries as I can */ 1154 if (!full_table) { 1155 spin_lock_bh(&req_dst_orig_node->tt_buff_lock); 1156 tt_len = req_dst_orig_node->tt_buff_len; 1157 tt_tot = tt_len / sizeof(struct tt_change); 1158 1159 skb = dev_alloc_skb(sizeof(struct tt_query_packet) + 1160 tt_len + ETH_HLEN); 1161 if (!skb) 1162 goto unlock; 1163 1164 skb_reserve(skb, ETH_HLEN); 1165 tt_response = (struct tt_query_packet *)skb_put(skb, 1166 sizeof(struct tt_query_packet) + tt_len); 1167 tt_response->ttvn = req_ttvn; 1168 tt_response->tt_data = htons(tt_tot); 1169 1170 tt_buff = skb->data + sizeof(struct tt_query_packet); 1171 /* Copy the last orig_node's OGM buffer */ 1172 memcpy(tt_buff, req_dst_orig_node->tt_buff, 1173 req_dst_orig_node->tt_buff_len); 1174 1175 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); 1176 } else { 1177 tt_len = (uint16_t)atomic_read(&req_dst_orig_node->tt_size) * 1178 sizeof(struct tt_change); 1179 ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn); 1180 1181 skb = tt_response_fill_table(tt_len, ttvn, 1182 bat_priv->tt_global_hash, 1183 primary_if, tt_global_valid_entry, 1184 req_dst_orig_node); 1185 if (!skb) 1186 goto out; 1187 1188 tt_response = (struct tt_query_packet *)skb->data; 1189 } 1190 1191 tt_response->packet_type = BAT_TT_QUERY; 1192 tt_response->version = COMPAT_VERSION; 1193 tt_response->ttl = TTL; 1194 memcpy(tt_response->src, req_dst_orig_node->orig, ETH_ALEN); 1195 memcpy(tt_response->dst, tt_request->src, ETH_ALEN); 1196 tt_response->flags = TT_RESPONSE; 1197 1198 if (full_table) 1199 tt_response->flags |= TT_FULL_TABLE; 1200 1201 bat_dbg(DBG_TT, bat_priv, 1202 "Sending TT_RESPONSE %pM via %pM for %pM (ttvn: %u)\n", 1203 res_dst_orig_node->orig, neigh_node->addr, 1204 req_dst_orig_node->orig, req_ttvn); 1205 1206 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 1207 ret = true; 1208 goto out; 1209 1210 unlock: 1211 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); 1212 1213 out: 1214 if (res_dst_orig_node) 1215 orig_node_free_ref(res_dst_orig_node); 1216 if (req_dst_orig_node) 1217 orig_node_free_ref(req_dst_orig_node); 1218 if (neigh_node) 1219 neigh_node_free_ref(neigh_node); 1220 if (primary_if) 1221 hardif_free_ref(primary_if); 1222 if (!ret) 1223 kfree_skb(skb); 1224 return ret; 1225 1226 } 1227 static bool send_my_tt_response(struct bat_priv *bat_priv, 1228 struct tt_query_packet *tt_request) 1229 { 1230 struct orig_node *orig_node = NULL; 1231 struct neigh_node *neigh_node = NULL; 1232 struct hard_iface *primary_if = NULL; 1233 uint8_t my_ttvn, req_ttvn, ttvn; 1234 int ret = false; 1235 unsigned char *tt_buff; 1236 bool full_table; 1237 uint16_t tt_len, tt_tot; 1238 struct sk_buff *skb = NULL; 1239 struct tt_query_packet *tt_response; 1240 1241 bat_dbg(DBG_TT, bat_priv, 1242 "Received TT_REQUEST from %pM for " 1243 "ttvn: %u (me) [%c]\n", tt_request->src, 1244 tt_request->ttvn, 1245 (tt_request->flags & TT_FULL_TABLE ? 'F' : '.')); 1246 1247 1248 my_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); 1249 req_ttvn = tt_request->ttvn; 1250 1251 orig_node = get_orig_node(bat_priv, tt_request->src); 1252 if (!orig_node) 1253 goto out; 1254 1255 neigh_node = orig_node_get_router(orig_node); 1256 if (!neigh_node) 1257 goto out; 1258 1259 primary_if = primary_if_get_selected(bat_priv); 1260 if (!primary_if) 1261 goto out; 1262 1263 /* If the full table has been explicitly requested or the gap 1264 * is too big send the whole local translation table */ 1265 if (tt_request->flags & TT_FULL_TABLE || my_ttvn != req_ttvn || 1266 !bat_priv->tt_buff) 1267 full_table = true; 1268 else 1269 full_table = false; 1270 1271 /* In this version, fragmentation is not implemented, then 1272 * I'll send only one packet with as much TT entries as I can */ 1273 if (!full_table) { 1274 spin_lock_bh(&bat_priv->tt_buff_lock); 1275 tt_len = bat_priv->tt_buff_len; 1276 tt_tot = tt_len / sizeof(struct tt_change); 1277 1278 skb = dev_alloc_skb(sizeof(struct tt_query_packet) + 1279 tt_len + ETH_HLEN); 1280 if (!skb) 1281 goto unlock; 1282 1283 skb_reserve(skb, ETH_HLEN); 1284 tt_response = (struct tt_query_packet *)skb_put(skb, 1285 sizeof(struct tt_query_packet) + tt_len); 1286 tt_response->ttvn = req_ttvn; 1287 tt_response->tt_data = htons(tt_tot); 1288 1289 tt_buff = skb->data + sizeof(struct tt_query_packet); 1290 memcpy(tt_buff, bat_priv->tt_buff, 1291 bat_priv->tt_buff_len); 1292 spin_unlock_bh(&bat_priv->tt_buff_lock); 1293 } else { 1294 tt_len = (uint16_t)atomic_read(&bat_priv->num_local_tt) * 1295 sizeof(struct tt_change); 1296 ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); 1297 1298 skb = tt_response_fill_table(tt_len, ttvn, 1299 bat_priv->tt_local_hash, 1300 primary_if, tt_local_valid_entry, 1301 NULL); 1302 if (!skb) 1303 goto out; 1304 1305 tt_response = (struct tt_query_packet *)skb->data; 1306 } 1307 1308 tt_response->packet_type = BAT_TT_QUERY; 1309 tt_response->version = COMPAT_VERSION; 1310 tt_response->ttl = TTL; 1311 memcpy(tt_response->src, primary_if->net_dev->dev_addr, ETH_ALEN); 1312 memcpy(tt_response->dst, tt_request->src, ETH_ALEN); 1313 tt_response->flags = TT_RESPONSE; 1314 1315 if (full_table) 1316 tt_response->flags |= TT_FULL_TABLE; 1317 1318 bat_dbg(DBG_TT, bat_priv, 1319 "Sending TT_RESPONSE to %pM via %pM [%c]\n", 1320 orig_node->orig, neigh_node->addr, 1321 (tt_response->flags & TT_FULL_TABLE ? 'F' : '.')); 1322 1323 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 1324 ret = true; 1325 goto out; 1326 1327 unlock: 1328 spin_unlock_bh(&bat_priv->tt_buff_lock); 1329 out: 1330 if (orig_node) 1331 orig_node_free_ref(orig_node); 1332 if (neigh_node) 1333 neigh_node_free_ref(neigh_node); 1334 if (primary_if) 1335 hardif_free_ref(primary_if); 1336 if (!ret) 1337 kfree_skb(skb); 1338 /* This packet was for me, so it doesn't need to be re-routed */ 1339 return true; 1340 } 1341 1342 bool send_tt_response(struct bat_priv *bat_priv, 1343 struct tt_query_packet *tt_request) 1344 { 1345 if (is_my_mac(tt_request->dst)) 1346 return send_my_tt_response(bat_priv, tt_request); 1347 else 1348 return send_other_tt_response(bat_priv, tt_request); 1349 } 1350 1351 static void _tt_update_changes(struct bat_priv *bat_priv, 1352 struct orig_node *orig_node, 1353 struct tt_change *tt_change, 1354 uint16_t tt_num_changes, uint8_t ttvn) 1355 { 1356 int i; 1357 1358 for (i = 0; i < tt_num_changes; i++) { 1359 if ((tt_change + i)->flags & TT_CLIENT_DEL) 1360 tt_global_del(bat_priv, orig_node, 1361 (tt_change + i)->addr, 1362 "tt removed by changes", 1363 (tt_change + i)->flags & TT_CLIENT_ROAM); 1364 else 1365 if (!tt_global_add(bat_priv, orig_node, 1366 (tt_change + i)->addr, ttvn, false)) 1367 /* In case of problem while storing a 1368 * global_entry, we stop the updating 1369 * procedure without committing the 1370 * ttvn change. This will avoid to send 1371 * corrupted data on tt_request 1372 */ 1373 return; 1374 } 1375 } 1376 1377 static void tt_fill_gtable(struct bat_priv *bat_priv, 1378 struct tt_query_packet *tt_response) 1379 { 1380 struct orig_node *orig_node = NULL; 1381 1382 orig_node = orig_hash_find(bat_priv, tt_response->src); 1383 if (!orig_node) 1384 goto out; 1385 1386 /* Purge the old table first.. */ 1387 tt_global_del_orig(bat_priv, orig_node, "Received full table"); 1388 1389 _tt_update_changes(bat_priv, orig_node, 1390 (struct tt_change *)(tt_response + 1), 1391 tt_response->tt_data, tt_response->ttvn); 1392 1393 spin_lock_bh(&orig_node->tt_buff_lock); 1394 kfree(orig_node->tt_buff); 1395 orig_node->tt_buff_len = 0; 1396 orig_node->tt_buff = NULL; 1397 spin_unlock_bh(&orig_node->tt_buff_lock); 1398 1399 atomic_set(&orig_node->last_ttvn, tt_response->ttvn); 1400 1401 out: 1402 if (orig_node) 1403 orig_node_free_ref(orig_node); 1404 } 1405 1406 void tt_update_changes(struct bat_priv *bat_priv, struct orig_node *orig_node, 1407 uint16_t tt_num_changes, uint8_t ttvn, 1408 struct tt_change *tt_change) 1409 { 1410 _tt_update_changes(bat_priv, orig_node, tt_change, tt_num_changes, 1411 ttvn); 1412 1413 tt_save_orig_buffer(bat_priv, orig_node, (unsigned char *)tt_change, 1414 tt_num_changes); 1415 atomic_set(&orig_node->last_ttvn, ttvn); 1416 } 1417 1418 bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr) 1419 { 1420 struct tt_local_entry *tt_local_entry = NULL; 1421 bool ret = false; 1422 1423 tt_local_entry = tt_local_hash_find(bat_priv, addr); 1424 if (!tt_local_entry) 1425 goto out; 1426 /* Check if the client has been logically deleted (but is kept for 1427 * consistency purpose) */ 1428 if (tt_local_entry->flags & TT_CLIENT_PENDING) 1429 goto out; 1430 ret = true; 1431 out: 1432 if (tt_local_entry) 1433 tt_local_entry_free_ref(tt_local_entry); 1434 return ret; 1435 } 1436 1437 void handle_tt_response(struct bat_priv *bat_priv, 1438 struct tt_query_packet *tt_response) 1439 { 1440 struct tt_req_node *node, *safe; 1441 struct orig_node *orig_node = NULL; 1442 1443 bat_dbg(DBG_TT, bat_priv, "Received TT_RESPONSE from %pM for " 1444 "ttvn %d t_size: %d [%c]\n", 1445 tt_response->src, tt_response->ttvn, 1446 tt_response->tt_data, 1447 (tt_response->flags & TT_FULL_TABLE ? 'F' : '.')); 1448 1449 orig_node = orig_hash_find(bat_priv, tt_response->src); 1450 if (!orig_node) 1451 goto out; 1452 1453 if (tt_response->flags & TT_FULL_TABLE) 1454 tt_fill_gtable(bat_priv, tt_response); 1455 else 1456 tt_update_changes(bat_priv, orig_node, tt_response->tt_data, 1457 tt_response->ttvn, 1458 (struct tt_change *)(tt_response + 1)); 1459 1460 /* Delete the tt_req_node from pending tt_requests list */ 1461 spin_lock_bh(&bat_priv->tt_req_list_lock); 1462 list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { 1463 if (!compare_eth(node->addr, tt_response->src)) 1464 continue; 1465 list_del(&node->list); 1466 kfree(node); 1467 } 1468 spin_unlock_bh(&bat_priv->tt_req_list_lock); 1469 1470 /* Recalculate the CRC for this orig_node and store it */ 1471 orig_node->tt_crc = tt_global_crc(bat_priv, orig_node); 1472 /* Roaming phase is over: tables are in sync again. I can 1473 * unset the flag */ 1474 orig_node->tt_poss_change = false; 1475 out: 1476 if (orig_node) 1477 orig_node_free_ref(orig_node); 1478 } 1479 1480 int tt_init(struct bat_priv *bat_priv) 1481 { 1482 if (!tt_local_init(bat_priv)) 1483 return 0; 1484 1485 if (!tt_global_init(bat_priv)) 1486 return 0; 1487 1488 tt_start_timer(bat_priv); 1489 1490 return 1; 1491 } 1492 1493 static void tt_roam_list_free(struct bat_priv *bat_priv) 1494 { 1495 struct tt_roam_node *node, *safe; 1496 1497 spin_lock_bh(&bat_priv->tt_roam_list_lock); 1498 1499 list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) { 1500 list_del(&node->list); 1501 kfree(node); 1502 } 1503 1504 spin_unlock_bh(&bat_priv->tt_roam_list_lock); 1505 } 1506 1507 static void tt_roam_purge(struct bat_priv *bat_priv) 1508 { 1509 struct tt_roam_node *node, *safe; 1510 1511 spin_lock_bh(&bat_priv->tt_roam_list_lock); 1512 list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) { 1513 if (!is_out_of_time(node->first_time, 1514 ROAMING_MAX_TIME * 1000)) 1515 continue; 1516 1517 list_del(&node->list); 1518 kfree(node); 1519 } 1520 spin_unlock_bh(&bat_priv->tt_roam_list_lock); 1521 } 1522 1523 /* This function checks whether the client already reached the 1524 * maximum number of possible roaming phases. In this case the ROAMING_ADV 1525 * will not be sent. 1526 * 1527 * returns true if the ROAMING_ADV can be sent, false otherwise */ 1528 static bool tt_check_roam_count(struct bat_priv *bat_priv, 1529 uint8_t *client) 1530 { 1531 struct tt_roam_node *tt_roam_node; 1532 bool ret = false; 1533 1534 spin_lock_bh(&bat_priv->tt_roam_list_lock); 1535 /* The new tt_req will be issued only if I'm not waiting for a 1536 * reply from the same orig_node yet */ 1537 list_for_each_entry(tt_roam_node, &bat_priv->tt_roam_list, list) { 1538 if (!compare_eth(tt_roam_node->addr, client)) 1539 continue; 1540 1541 if (is_out_of_time(tt_roam_node->first_time, 1542 ROAMING_MAX_TIME * 1000)) 1543 continue; 1544 1545 if (!atomic_dec_not_zero(&tt_roam_node->counter)) 1546 /* Sorry, you roamed too many times! */ 1547 goto unlock; 1548 ret = true; 1549 break; 1550 } 1551 1552 if (!ret) { 1553 tt_roam_node = kmalloc(sizeof(*tt_roam_node), GFP_ATOMIC); 1554 if (!tt_roam_node) 1555 goto unlock; 1556 1557 tt_roam_node->first_time = jiffies; 1558 atomic_set(&tt_roam_node->counter, ROAMING_MAX_COUNT - 1); 1559 memcpy(tt_roam_node->addr, client, ETH_ALEN); 1560 1561 list_add(&tt_roam_node->list, &bat_priv->tt_roam_list); 1562 ret = true; 1563 } 1564 1565 unlock: 1566 spin_unlock_bh(&bat_priv->tt_roam_list_lock); 1567 return ret; 1568 } 1569 1570 void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, 1571 struct orig_node *orig_node) 1572 { 1573 struct neigh_node *neigh_node = NULL; 1574 struct sk_buff *skb = NULL; 1575 struct roam_adv_packet *roam_adv_packet; 1576 int ret = 1; 1577 struct hard_iface *primary_if; 1578 1579 /* before going on we have to check whether the client has 1580 * already roamed to us too many times */ 1581 if (!tt_check_roam_count(bat_priv, client)) 1582 goto out; 1583 1584 skb = dev_alloc_skb(sizeof(struct roam_adv_packet) + ETH_HLEN); 1585 if (!skb) 1586 goto out; 1587 1588 skb_reserve(skb, ETH_HLEN); 1589 1590 roam_adv_packet = (struct roam_adv_packet *)skb_put(skb, 1591 sizeof(struct roam_adv_packet)); 1592 1593 roam_adv_packet->packet_type = BAT_ROAM_ADV; 1594 roam_adv_packet->version = COMPAT_VERSION; 1595 roam_adv_packet->ttl = TTL; 1596 primary_if = primary_if_get_selected(bat_priv); 1597 if (!primary_if) 1598 goto out; 1599 memcpy(roam_adv_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN); 1600 hardif_free_ref(primary_if); 1601 memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN); 1602 memcpy(roam_adv_packet->client, client, ETH_ALEN); 1603 1604 neigh_node = orig_node_get_router(orig_node); 1605 if (!neigh_node) 1606 goto out; 1607 1608 bat_dbg(DBG_TT, bat_priv, 1609 "Sending ROAMING_ADV to %pM (client %pM) via %pM\n", 1610 orig_node->orig, client, neigh_node->addr); 1611 1612 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 1613 ret = 0; 1614 1615 out: 1616 if (neigh_node) 1617 neigh_node_free_ref(neigh_node); 1618 if (ret) 1619 kfree_skb(skb); 1620 return; 1621 } 1622 1623 static void tt_purge(struct work_struct *work) 1624 { 1625 struct delayed_work *delayed_work = 1626 container_of(work, struct delayed_work, work); 1627 struct bat_priv *bat_priv = 1628 container_of(delayed_work, struct bat_priv, tt_work); 1629 1630 tt_local_purge(bat_priv); 1631 tt_global_roam_purge(bat_priv); 1632 tt_req_purge(bat_priv); 1633 tt_roam_purge(bat_priv); 1634 1635 tt_start_timer(bat_priv); 1636 } 1637 1638 void tt_free(struct bat_priv *bat_priv) 1639 { 1640 cancel_delayed_work_sync(&bat_priv->tt_work); 1641 1642 tt_local_table_free(bat_priv); 1643 tt_global_table_free(bat_priv); 1644 tt_req_list_free(bat_priv); 1645 tt_changes_list_free(bat_priv); 1646 tt_roam_list_free(bat_priv); 1647 1648 kfree(bat_priv->tt_buff); 1649 } 1650 1651 /* This function will reset the specified flags from all the entries in 1652 * the given hash table and will increment num_local_tt for each involved 1653 * entry */ 1654 static void tt_local_reset_flags(struct bat_priv *bat_priv, uint16_t flags) 1655 { 1656 int i; 1657 struct hashtable_t *hash = bat_priv->tt_local_hash; 1658 struct hlist_head *head; 1659 struct hlist_node *node; 1660 struct tt_local_entry *tt_local_entry; 1661 1662 if (!hash) 1663 return; 1664 1665 for (i = 0; i < hash->size; i++) { 1666 head = &hash->table[i]; 1667 1668 rcu_read_lock(); 1669 hlist_for_each_entry_rcu(tt_local_entry, node, 1670 head, hash_entry) { 1671 tt_local_entry->flags &= ~flags; 1672 atomic_inc(&bat_priv->num_local_tt); 1673 } 1674 rcu_read_unlock(); 1675 } 1676 1677 } 1678 1679 /* Purge out all the tt local entries marked with TT_CLIENT_PENDING */ 1680 static void tt_local_purge_pending_clients(struct bat_priv *bat_priv) 1681 { 1682 struct hashtable_t *hash = bat_priv->tt_local_hash; 1683 struct tt_local_entry *tt_local_entry; 1684 struct hlist_node *node, *node_tmp; 1685 struct hlist_head *head; 1686 spinlock_t *list_lock; /* protects write access to the hash lists */ 1687 int i; 1688 1689 if (!hash) 1690 return; 1691 1692 for (i = 0; i < hash->size; i++) { 1693 head = &hash->table[i]; 1694 list_lock = &hash->list_locks[i]; 1695 1696 spin_lock_bh(list_lock); 1697 hlist_for_each_entry_safe(tt_local_entry, node, node_tmp, 1698 head, hash_entry) { 1699 if (!(tt_local_entry->flags & TT_CLIENT_PENDING)) 1700 continue; 1701 1702 bat_dbg(DBG_TT, bat_priv, "Deleting local tt entry " 1703 "(%pM): pending\n", tt_local_entry->addr); 1704 1705 atomic_dec(&bat_priv->num_local_tt); 1706 hlist_del_rcu(node); 1707 tt_local_entry_free_ref(tt_local_entry); 1708 } 1709 spin_unlock_bh(list_lock); 1710 } 1711 1712 } 1713 1714 void tt_commit_changes(struct bat_priv *bat_priv) 1715 { 1716 tt_local_reset_flags(bat_priv, TT_CLIENT_NEW); 1717 tt_local_purge_pending_clients(bat_priv); 1718 1719 /* Increment the TTVN only once per OGM interval */ 1720 atomic_inc(&bat_priv->ttvn); 1721 bat_priv->tt_poss_change = false; 1722 } 1723