1 /* Copyright (C) 2007-2013 B.A.T.M.A.N. contributors: 2 * 3 * Marek Lindner, Simon Wunderlich, Antonio Quartulli 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of version 2 of the GNU General Public 7 * License as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * 02110-1301, USA 18 */ 19 20 #include "main.h" 21 #include "translation-table.h" 22 #include "soft-interface.h" 23 #include "hard-interface.h" 24 #include "send.h" 25 #include "hash.h" 26 #include "originator.h" 27 #include "routing.h" 28 #include "bridge_loop_avoidance.h" 29 30 #include <linux/crc16.h> 31 32 /* hash class keys */ 33 static struct lock_class_key batadv_tt_local_hash_lock_class_key; 34 static struct lock_class_key batadv_tt_global_hash_lock_class_key; 35 36 static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, 37 struct batadv_orig_node *orig_node); 38 static void batadv_tt_purge(struct work_struct *work); 39 static void 40 batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry); 41 static void batadv_tt_global_del(struct batadv_priv *bat_priv, 42 struct batadv_orig_node *orig_node, 43 const unsigned char *addr, 44 const char *message, bool roaming); 45 46 /* returns 1 if they are the same mac addr */ 47 static int batadv_compare_tt(const struct hlist_node *node, const void *data2) 48 { 49 const void *data1 = container_of(node, struct batadv_tt_common_entry, 50 hash_entry); 51 52 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); 53 } 54 55 static struct batadv_tt_common_entry * 56 batadv_tt_hash_find(struct batadv_hashtable *hash, const void *data) 57 { 58 struct hlist_head *head; 59 struct batadv_tt_common_entry *tt_common_entry; 60 struct batadv_tt_common_entry *tt_common_entry_tmp = NULL; 61 uint32_t index; 62 63 if (!hash) 64 return NULL; 65 66 index = batadv_choose_orig(data, hash->size); 67 head = &hash->table[index]; 68 69 rcu_read_lock(); 70 hlist_for_each_entry_rcu(tt_common_entry, head, hash_entry) { 71 if (!batadv_compare_eth(tt_common_entry, data)) 72 continue; 73 74 if (!atomic_inc_not_zero(&tt_common_entry->refcount)) 75 continue; 76 77 tt_common_entry_tmp = tt_common_entry; 78 break; 79 } 80 rcu_read_unlock(); 81 82 return tt_common_entry_tmp; 83 } 84 85 static struct batadv_tt_local_entry * 86 batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const void *data) 87 { 88 struct batadv_tt_common_entry *tt_common_entry; 89 struct batadv_tt_local_entry *tt_local_entry = NULL; 90 91 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, data); 92 if (tt_common_entry) 93 tt_local_entry = container_of(tt_common_entry, 94 struct batadv_tt_local_entry, 95 common); 96 return tt_local_entry; 97 } 98 99 static struct batadv_tt_global_entry * 100 batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const void *data) 101 { 102 struct batadv_tt_common_entry *tt_common_entry; 103 struct batadv_tt_global_entry *tt_global_entry = NULL; 104 105 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, data); 106 if (tt_common_entry) 107 tt_global_entry = container_of(tt_common_entry, 108 struct batadv_tt_global_entry, 109 common); 110 return tt_global_entry; 111 } 112 113 static void 114 batadv_tt_local_entry_free_ref(struct batadv_tt_local_entry *tt_local_entry) 115 { 116 if (atomic_dec_and_test(&tt_local_entry->common.refcount)) 117 kfree_rcu(tt_local_entry, common.rcu); 118 } 119 120 static void batadv_tt_global_entry_free_rcu(struct rcu_head *rcu) 121 { 122 struct batadv_tt_common_entry *tt_common_entry; 123 struct batadv_tt_global_entry *tt_global_entry; 124 125 tt_common_entry = container_of(rcu, struct batadv_tt_common_entry, rcu); 126 tt_global_entry = container_of(tt_common_entry, 127 struct batadv_tt_global_entry, common); 128 129 kfree(tt_global_entry); 130 } 131 132 static void 133 batadv_tt_global_entry_free_ref(struct batadv_tt_global_entry *tt_global_entry) 134 { 135 if (atomic_dec_and_test(&tt_global_entry->common.refcount)) { 136 batadv_tt_global_del_orig_list(tt_global_entry); 137 call_rcu(&tt_global_entry->common.rcu, 138 batadv_tt_global_entry_free_rcu); 139 } 140 } 141 142 static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu) 143 { 144 struct batadv_tt_orig_list_entry *orig_entry; 145 146 orig_entry = container_of(rcu, struct batadv_tt_orig_list_entry, rcu); 147 148 /* We are in an rcu callback here, therefore we cannot use 149 * batadv_orig_node_free_ref() and its call_rcu(): 150 * An rcu_barrier() wouldn't wait for that to finish 151 */ 152 batadv_orig_node_free_ref_now(orig_entry->orig_node); 153 kfree(orig_entry); 154 } 155 156 static void 157 batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry) 158 { 159 if (!atomic_dec_and_test(&orig_entry->refcount)) 160 return; 161 /* to avoid race conditions, immediately decrease the tt counter */ 162 atomic_dec(&orig_entry->orig_node->tt_size); 163 call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu); 164 } 165 166 /** 167 * batadv_tt_local_event - store a local TT event (ADD/DEL) 168 * @bat_priv: the bat priv with all the soft interface information 169 * @tt_local_entry: the TT entry involved in the event 170 * @event_flags: flags to store in the event structure 171 */ 172 static void batadv_tt_local_event(struct batadv_priv *bat_priv, 173 struct batadv_tt_local_entry *tt_local_entry, 174 uint8_t event_flags) 175 { 176 struct batadv_tt_change_node *tt_change_node, *entry, *safe; 177 struct batadv_tt_common_entry *common = &tt_local_entry->common; 178 uint8_t flags = common->flags | event_flags; 179 bool event_removed = false; 180 bool del_op_requested, del_op_entry; 181 182 tt_change_node = kmalloc(sizeof(*tt_change_node), GFP_ATOMIC); 183 184 if (!tt_change_node) 185 return; 186 187 tt_change_node->change.flags = flags; 188 memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN); 189 190 del_op_requested = flags & BATADV_TT_CLIENT_DEL; 191 192 /* check for ADD+DEL or DEL+ADD events */ 193 spin_lock_bh(&bat_priv->tt.changes_list_lock); 194 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, 195 list) { 196 if (!batadv_compare_eth(entry->change.addr, common->addr)) 197 continue; 198 199 /* DEL+ADD in the same orig interval have no effect and can be 200 * removed to avoid silly behaviour on the receiver side. The 201 * other way around (ADD+DEL) can happen in case of roaming of 202 * a client still in the NEW state. Roaming of NEW clients is 203 * now possible due to automatically recognition of "temporary" 204 * clients 205 */ 206 del_op_entry = entry->change.flags & BATADV_TT_CLIENT_DEL; 207 if (!del_op_requested && del_op_entry) 208 goto del; 209 if (del_op_requested && !del_op_entry) 210 goto del; 211 continue; 212 del: 213 list_del(&entry->list); 214 kfree(entry); 215 kfree(tt_change_node); 216 event_removed = true; 217 goto unlock; 218 } 219 220 /* track the change in the OGMinterval list */ 221 list_add_tail(&tt_change_node->list, &bat_priv->tt.changes_list); 222 223 unlock: 224 spin_unlock_bh(&bat_priv->tt.changes_list_lock); 225 226 if (event_removed) 227 atomic_dec(&bat_priv->tt.local_changes); 228 else 229 atomic_inc(&bat_priv->tt.local_changes); 230 } 231 232 int batadv_tt_len(int changes_num) 233 { 234 return changes_num * sizeof(struct batadv_tt_change); 235 } 236 237 static int batadv_tt_local_init(struct batadv_priv *bat_priv) 238 { 239 if (bat_priv->tt.local_hash) 240 return 0; 241 242 bat_priv->tt.local_hash = batadv_hash_new(1024); 243 244 if (!bat_priv->tt.local_hash) 245 return -ENOMEM; 246 247 batadv_hash_set_lock_class(bat_priv->tt.local_hash, 248 &batadv_tt_local_hash_lock_class_key); 249 250 return 0; 251 } 252 253 static void batadv_tt_global_free(struct batadv_priv *bat_priv, 254 struct batadv_tt_global_entry *tt_global, 255 const char *message) 256 { 257 batadv_dbg(BATADV_DBG_TT, bat_priv, 258 "Deleting global tt entry %pM: %s\n", 259 tt_global->common.addr, message); 260 261 batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt, 262 batadv_choose_orig, tt_global->common.addr); 263 batadv_tt_global_entry_free_ref(tt_global); 264 } 265 266 void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, 267 int ifindex) 268 { 269 struct batadv_priv *bat_priv = netdev_priv(soft_iface); 270 struct batadv_tt_local_entry *tt_local; 271 struct batadv_tt_global_entry *tt_global; 272 struct hlist_head *head; 273 struct batadv_tt_orig_list_entry *orig_entry; 274 int hash_added; 275 bool roamed_back = false; 276 277 tt_local = batadv_tt_local_hash_find(bat_priv, addr); 278 tt_global = batadv_tt_global_hash_find(bat_priv, addr); 279 280 if (tt_local) { 281 tt_local->last_seen = jiffies; 282 if (tt_local->common.flags & BATADV_TT_CLIENT_PENDING) { 283 batadv_dbg(BATADV_DBG_TT, bat_priv, 284 "Re-adding pending client %pM\n", addr); 285 /* whatever the reason why the PENDING flag was set, 286 * this is a client which was enqueued to be removed in 287 * this orig_interval. Since it popped up again, the 288 * flag can be reset like it was never enqueued 289 */ 290 tt_local->common.flags &= ~BATADV_TT_CLIENT_PENDING; 291 goto add_event; 292 } 293 294 if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) { 295 batadv_dbg(BATADV_DBG_TT, bat_priv, 296 "Roaming client %pM came back to its original location\n", 297 addr); 298 /* the ROAM flag is set because this client roamed away 299 * and the node got a roaming_advertisement message. Now 300 * that the client popped up again at its original 301 * location such flag can be unset 302 */ 303 tt_local->common.flags &= ~BATADV_TT_CLIENT_ROAM; 304 roamed_back = true; 305 } 306 goto check_roaming; 307 } 308 309 tt_local = kmalloc(sizeof(*tt_local), GFP_ATOMIC); 310 if (!tt_local) 311 goto out; 312 313 batadv_dbg(BATADV_DBG_TT, bat_priv, 314 "Creating new local tt entry: %pM (ttvn: %d)\n", addr, 315 (uint8_t)atomic_read(&bat_priv->tt.vn)); 316 317 memcpy(tt_local->common.addr, addr, ETH_ALEN); 318 /* The local entry has to be marked as NEW to avoid to send it in 319 * a full table response going out before the next ttvn increment 320 * (consistency check) 321 */ 322 tt_local->common.flags = BATADV_TT_CLIENT_NEW; 323 if (batadv_is_wifi_iface(ifindex)) 324 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI; 325 atomic_set(&tt_local->common.refcount, 2); 326 tt_local->last_seen = jiffies; 327 tt_local->common.added_at = tt_local->last_seen; 328 329 /* the batman interface mac address should never be purged */ 330 if (batadv_compare_eth(addr, soft_iface->dev_addr)) 331 tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE; 332 333 hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt, 334 batadv_choose_orig, &tt_local->common, 335 &tt_local->common.hash_entry); 336 337 if (unlikely(hash_added != 0)) { 338 /* remove the reference for the hash */ 339 batadv_tt_local_entry_free_ref(tt_local); 340 goto out; 341 } 342 343 add_event: 344 batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS); 345 346 check_roaming: 347 /* Check whether it is a roaming, but don't do anything if the roaming 348 * process has already been handled 349 */ 350 if (tt_global && !(tt_global->common.flags & BATADV_TT_CLIENT_ROAM)) { 351 /* These node are probably going to update their tt table */ 352 head = &tt_global->orig_list; 353 rcu_read_lock(); 354 hlist_for_each_entry_rcu(orig_entry, head, list) { 355 batadv_send_roam_adv(bat_priv, tt_global->common.addr, 356 orig_entry->orig_node); 357 } 358 rcu_read_unlock(); 359 if (roamed_back) { 360 batadv_tt_global_free(bat_priv, tt_global, 361 "Roaming canceled"); 362 tt_global = NULL; 363 } else { 364 /* The global entry has to be marked as ROAMING and 365 * has to be kept for consistency purpose 366 */ 367 tt_global->common.flags |= BATADV_TT_CLIENT_ROAM; 368 tt_global->roam_at = jiffies; 369 } 370 } 371 372 out: 373 if (tt_local) 374 batadv_tt_local_entry_free_ref(tt_local); 375 if (tt_global) 376 batadv_tt_global_entry_free_ref(tt_global); 377 } 378 379 static void batadv_tt_realloc_packet_buff(unsigned char **packet_buff, 380 int *packet_buff_len, 381 int min_packet_len, 382 int new_packet_len) 383 { 384 unsigned char *new_buff; 385 386 new_buff = kmalloc(new_packet_len, GFP_ATOMIC); 387 388 /* keep old buffer if kmalloc should fail */ 389 if (new_buff) { 390 memcpy(new_buff, *packet_buff, min_packet_len); 391 kfree(*packet_buff); 392 *packet_buff = new_buff; 393 *packet_buff_len = new_packet_len; 394 } 395 } 396 397 static void batadv_tt_prepare_packet_buff(struct batadv_priv *bat_priv, 398 unsigned char **packet_buff, 399 int *packet_buff_len, 400 int min_packet_len) 401 { 402 int req_len; 403 404 req_len = min_packet_len; 405 req_len += batadv_tt_len(atomic_read(&bat_priv->tt.local_changes)); 406 407 /* if we have too many changes for one packet don't send any 408 * and wait for the tt table request which will be fragmented 409 */ 410 if (req_len > bat_priv->soft_iface->mtu) 411 req_len = min_packet_len; 412 413 batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len, 414 min_packet_len, req_len); 415 } 416 417 static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv, 418 unsigned char **packet_buff, 419 int *packet_buff_len, 420 int min_packet_len) 421 { 422 struct batadv_tt_change_node *entry, *safe; 423 int count = 0, tot_changes = 0, new_len; 424 unsigned char *tt_buff; 425 426 batadv_tt_prepare_packet_buff(bat_priv, packet_buff, 427 packet_buff_len, min_packet_len); 428 429 new_len = *packet_buff_len - min_packet_len; 430 tt_buff = *packet_buff + min_packet_len; 431 432 if (new_len > 0) 433 tot_changes = new_len / batadv_tt_len(1); 434 435 spin_lock_bh(&bat_priv->tt.changes_list_lock); 436 atomic_set(&bat_priv->tt.local_changes, 0); 437 438 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, 439 list) { 440 if (count < tot_changes) { 441 memcpy(tt_buff + batadv_tt_len(count), 442 &entry->change, sizeof(struct batadv_tt_change)); 443 count++; 444 } 445 list_del(&entry->list); 446 kfree(entry); 447 } 448 spin_unlock_bh(&bat_priv->tt.changes_list_lock); 449 450 /* Keep the buffer for possible tt_request */ 451 spin_lock_bh(&bat_priv->tt.last_changeset_lock); 452 kfree(bat_priv->tt.last_changeset); 453 bat_priv->tt.last_changeset_len = 0; 454 bat_priv->tt.last_changeset = NULL; 455 /* check whether this new OGM has no changes due to size problems */ 456 if (new_len > 0) { 457 /* if kmalloc() fails we will reply with the full table 458 * instead of providing the diff 459 */ 460 bat_priv->tt.last_changeset = kmalloc(new_len, GFP_ATOMIC); 461 if (bat_priv->tt.last_changeset) { 462 memcpy(bat_priv->tt.last_changeset, tt_buff, new_len); 463 bat_priv->tt.last_changeset_len = new_len; 464 } 465 } 466 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); 467 468 return count; 469 } 470 471 int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) 472 { 473 struct net_device *net_dev = (struct net_device *)seq->private; 474 struct batadv_priv *bat_priv = netdev_priv(net_dev); 475 struct batadv_hashtable *hash = bat_priv->tt.local_hash; 476 struct batadv_tt_common_entry *tt_common_entry; 477 struct batadv_tt_local_entry *tt_local; 478 struct batadv_hard_iface *primary_if; 479 struct hlist_head *head; 480 uint32_t i; 481 int last_seen_secs; 482 int last_seen_msecs; 483 unsigned long last_seen_jiffies; 484 bool no_purge; 485 uint16_t np_flag = BATADV_TT_CLIENT_NOPURGE; 486 487 primary_if = batadv_seq_print_text_primary_if_get(seq); 488 if (!primary_if) 489 goto out; 490 491 seq_printf(seq, 492 "Locally retrieved addresses (from %s) announced via TT (TTVN: %u CRC: %#.4x):\n", 493 net_dev->name, (uint8_t)atomic_read(&bat_priv->tt.vn), 494 bat_priv->tt.local_crc); 495 seq_printf(seq, " %-13s %-7s %-10s\n", "Client", "Flags", 496 "Last seen"); 497 498 for (i = 0; i < hash->size; i++) { 499 head = &hash->table[i]; 500 501 rcu_read_lock(); 502 hlist_for_each_entry_rcu(tt_common_entry, 503 head, hash_entry) { 504 tt_local = container_of(tt_common_entry, 505 struct batadv_tt_local_entry, 506 common); 507 last_seen_jiffies = jiffies - tt_local->last_seen; 508 last_seen_msecs = jiffies_to_msecs(last_seen_jiffies); 509 last_seen_secs = last_seen_msecs / 1000; 510 last_seen_msecs = last_seen_msecs % 1000; 511 512 no_purge = tt_common_entry->flags & np_flag; 513 514 seq_printf(seq, " * %pM [%c%c%c%c%c] %3u.%03u\n", 515 tt_common_entry->addr, 516 (tt_common_entry->flags & 517 BATADV_TT_CLIENT_ROAM ? 'R' : '.'), 518 no_purge ? 'P' : '.', 519 (tt_common_entry->flags & 520 BATADV_TT_CLIENT_NEW ? 'N' : '.'), 521 (tt_common_entry->flags & 522 BATADV_TT_CLIENT_PENDING ? 'X' : '.'), 523 (tt_common_entry->flags & 524 BATADV_TT_CLIENT_WIFI ? 'W' : '.'), 525 no_purge ? 0 : last_seen_secs, 526 no_purge ? 0 : last_seen_msecs); 527 } 528 rcu_read_unlock(); 529 } 530 out: 531 if (primary_if) 532 batadv_hardif_free_ref(primary_if); 533 return 0; 534 } 535 536 static void 537 batadv_tt_local_set_pending(struct batadv_priv *bat_priv, 538 struct batadv_tt_local_entry *tt_local_entry, 539 uint16_t flags, const char *message) 540 { 541 batadv_tt_local_event(bat_priv, tt_local_entry, flags); 542 543 /* The local client has to be marked as "pending to be removed" but has 544 * to be kept in the table in order to send it in a full table 545 * response issued before the net ttvn increment (consistency check) 546 */ 547 tt_local_entry->common.flags |= BATADV_TT_CLIENT_PENDING; 548 549 batadv_dbg(BATADV_DBG_TT, bat_priv, 550 "Local tt entry (%pM) pending to be removed: %s\n", 551 tt_local_entry->common.addr, message); 552 } 553 554 /** 555 * batadv_tt_local_remove - logically remove an entry from the local table 556 * @bat_priv: the bat priv with all the soft interface information 557 * @addr: the MAC address of the client to remove 558 * @message: message to append to the log on deletion 559 * @roaming: true if the deletion is due to a roaming event 560 * 561 * Returns the flags assigned to the local entry before being deleted 562 */ 563 uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, 564 const uint8_t *addr, const char *message, 565 bool roaming) 566 { 567 struct batadv_tt_local_entry *tt_local_entry; 568 uint16_t flags, curr_flags = BATADV_NO_FLAGS; 569 570 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); 571 if (!tt_local_entry) 572 goto out; 573 574 curr_flags = tt_local_entry->common.flags; 575 576 flags = BATADV_TT_CLIENT_DEL; 577 /* if this global entry addition is due to a roaming, the node has to 578 * mark the local entry as "roamed" in order to correctly reroute 579 * packets later 580 */ 581 if (roaming) { 582 flags |= BATADV_TT_CLIENT_ROAM; 583 /* mark the local client as ROAMed */ 584 tt_local_entry->common.flags |= BATADV_TT_CLIENT_ROAM; 585 } 586 587 if (!(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) { 588 batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, 589 message); 590 goto out; 591 } 592 /* if this client has been added right now, it is possible to 593 * immediately purge it 594 */ 595 batadv_tt_local_event(bat_priv, tt_local_entry, BATADV_TT_CLIENT_DEL); 596 hlist_del_rcu(&tt_local_entry->common.hash_entry); 597 batadv_tt_local_entry_free_ref(tt_local_entry); 598 599 out: 600 if (tt_local_entry) 601 batadv_tt_local_entry_free_ref(tt_local_entry); 602 603 return curr_flags; 604 } 605 606 static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv, 607 struct hlist_head *head) 608 { 609 struct batadv_tt_local_entry *tt_local_entry; 610 struct batadv_tt_common_entry *tt_common_entry; 611 struct hlist_node *node_tmp; 612 613 hlist_for_each_entry_safe(tt_common_entry, node_tmp, head, 614 hash_entry) { 615 tt_local_entry = container_of(tt_common_entry, 616 struct batadv_tt_local_entry, 617 common); 618 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_NOPURGE) 619 continue; 620 621 /* entry already marked for deletion */ 622 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) 623 continue; 624 625 if (!batadv_has_timed_out(tt_local_entry->last_seen, 626 BATADV_TT_LOCAL_TIMEOUT)) 627 continue; 628 629 batadv_tt_local_set_pending(bat_priv, tt_local_entry, 630 BATADV_TT_CLIENT_DEL, "timed out"); 631 } 632 } 633 634 static void batadv_tt_local_purge(struct batadv_priv *bat_priv) 635 { 636 struct batadv_hashtable *hash = bat_priv->tt.local_hash; 637 struct hlist_head *head; 638 spinlock_t *list_lock; /* protects write access to the hash lists */ 639 uint32_t i; 640 641 for (i = 0; i < hash->size; i++) { 642 head = &hash->table[i]; 643 list_lock = &hash->list_locks[i]; 644 645 spin_lock_bh(list_lock); 646 batadv_tt_local_purge_list(bat_priv, head); 647 spin_unlock_bh(list_lock); 648 } 649 } 650 651 static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) 652 { 653 struct batadv_hashtable *hash; 654 spinlock_t *list_lock; /* protects write access to the hash lists */ 655 struct batadv_tt_common_entry *tt_common_entry; 656 struct batadv_tt_local_entry *tt_local; 657 struct hlist_node *node_tmp; 658 struct hlist_head *head; 659 uint32_t i; 660 661 if (!bat_priv->tt.local_hash) 662 return; 663 664 hash = bat_priv->tt.local_hash; 665 666 for (i = 0; i < hash->size; i++) { 667 head = &hash->table[i]; 668 list_lock = &hash->list_locks[i]; 669 670 spin_lock_bh(list_lock); 671 hlist_for_each_entry_safe(tt_common_entry, node_tmp, 672 head, hash_entry) { 673 hlist_del_rcu(&tt_common_entry->hash_entry); 674 tt_local = container_of(tt_common_entry, 675 struct batadv_tt_local_entry, 676 common); 677 batadv_tt_local_entry_free_ref(tt_local); 678 } 679 spin_unlock_bh(list_lock); 680 } 681 682 batadv_hash_destroy(hash); 683 684 bat_priv->tt.local_hash = NULL; 685 } 686 687 static int batadv_tt_global_init(struct batadv_priv *bat_priv) 688 { 689 if (bat_priv->tt.global_hash) 690 return 0; 691 692 bat_priv->tt.global_hash = batadv_hash_new(1024); 693 694 if (!bat_priv->tt.global_hash) 695 return -ENOMEM; 696 697 batadv_hash_set_lock_class(bat_priv->tt.global_hash, 698 &batadv_tt_global_hash_lock_class_key); 699 700 return 0; 701 } 702 703 static void batadv_tt_changes_list_free(struct batadv_priv *bat_priv) 704 { 705 struct batadv_tt_change_node *entry, *safe; 706 707 spin_lock_bh(&bat_priv->tt.changes_list_lock); 708 709 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, 710 list) { 711 list_del(&entry->list); 712 kfree(entry); 713 } 714 715 atomic_set(&bat_priv->tt.local_changes, 0); 716 spin_unlock_bh(&bat_priv->tt.changes_list_lock); 717 } 718 719 /* retrieves the orig_tt_list_entry belonging to orig_node from the 720 * batadv_tt_global_entry list 721 * 722 * returns it with an increased refcounter, NULL if not found 723 */ 724 static struct batadv_tt_orig_list_entry * 725 batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry, 726 const struct batadv_orig_node *orig_node) 727 { 728 struct batadv_tt_orig_list_entry *tmp_orig_entry, *orig_entry = NULL; 729 const struct hlist_head *head; 730 731 rcu_read_lock(); 732 head = &entry->orig_list; 733 hlist_for_each_entry_rcu(tmp_orig_entry, head, list) { 734 if (tmp_orig_entry->orig_node != orig_node) 735 continue; 736 if (!atomic_inc_not_zero(&tmp_orig_entry->refcount)) 737 continue; 738 739 orig_entry = tmp_orig_entry; 740 break; 741 } 742 rcu_read_unlock(); 743 744 return orig_entry; 745 } 746 747 /* find out if an orig_node is already in the list of a tt_global_entry. 748 * returns true if found, false otherwise 749 */ 750 static bool 751 batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry, 752 const struct batadv_orig_node *orig_node) 753 { 754 struct batadv_tt_orig_list_entry *orig_entry; 755 bool found = false; 756 757 orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node); 758 if (orig_entry) { 759 found = true; 760 batadv_tt_orig_list_entry_free_ref(orig_entry); 761 } 762 763 return found; 764 } 765 766 static void 767 batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, 768 struct batadv_orig_node *orig_node, int ttvn) 769 { 770 struct batadv_tt_orig_list_entry *orig_entry; 771 772 orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node); 773 if (orig_entry) { 774 /* refresh the ttvn: the current value could be a bogus one that 775 * was added during a "temporary client detection" 776 */ 777 orig_entry->ttvn = ttvn; 778 goto out; 779 } 780 781 orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC); 782 if (!orig_entry) 783 goto out; 784 785 INIT_HLIST_NODE(&orig_entry->list); 786 atomic_inc(&orig_node->refcount); 787 atomic_inc(&orig_node->tt_size); 788 orig_entry->orig_node = orig_node; 789 orig_entry->ttvn = ttvn; 790 atomic_set(&orig_entry->refcount, 2); 791 792 spin_lock_bh(&tt_global->list_lock); 793 hlist_add_head_rcu(&orig_entry->list, 794 &tt_global->orig_list); 795 spin_unlock_bh(&tt_global->list_lock); 796 out: 797 if (orig_entry) 798 batadv_tt_orig_list_entry_free_ref(orig_entry); 799 } 800 801 /** 802 * batadv_tt_global_add - add a new TT global entry or update an existing one 803 * @bat_priv: the bat priv with all the soft interface information 804 * @orig_node: the originator announcing the client 805 * @tt_addr: the mac address of the non-mesh client 806 * @flags: TT flags that have to be set for this non-mesh client 807 * @ttvn: the tt version number ever announcing this non-mesh client 808 * 809 * Add a new TT global entry for the given originator. If the entry already 810 * exists add a new reference to the given originator (a global entry can have 811 * references to multiple originators) and adjust the flags attribute to reflect 812 * the function argument. 813 * If a TT local entry exists for this non-mesh client remove it. 814 * 815 * The caller must hold orig_node refcount. 816 */ 817 int batadv_tt_global_add(struct batadv_priv *bat_priv, 818 struct batadv_orig_node *orig_node, 819 const unsigned char *tt_addr, uint16_t flags, 820 uint8_t ttvn) 821 { 822 struct batadv_tt_global_entry *tt_global_entry; 823 struct batadv_tt_local_entry *tt_local_entry; 824 int ret = 0; 825 int hash_added; 826 struct batadv_tt_common_entry *common; 827 uint16_t local_flags; 828 829 tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr); 830 tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr); 831 832 /* if the node already has a local client for this entry, it has to wait 833 * for a roaming advertisement instead of manually messing up the global 834 * table 835 */ 836 if ((flags & BATADV_TT_CLIENT_TEMP) && tt_local_entry && 837 !(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) 838 goto out; 839 840 if (!tt_global_entry) { 841 tt_global_entry = kzalloc(sizeof(*tt_global_entry), GFP_ATOMIC); 842 if (!tt_global_entry) 843 goto out; 844 845 common = &tt_global_entry->common; 846 memcpy(common->addr, tt_addr, ETH_ALEN); 847 848 common->flags = flags; 849 tt_global_entry->roam_at = 0; 850 /* node must store current time in case of roaming. This is 851 * needed to purge this entry out on timeout (if nobody claims 852 * it) 853 */ 854 if (flags & BATADV_TT_CLIENT_ROAM) 855 tt_global_entry->roam_at = jiffies; 856 atomic_set(&common->refcount, 2); 857 common->added_at = jiffies; 858 859 INIT_HLIST_HEAD(&tt_global_entry->orig_list); 860 spin_lock_init(&tt_global_entry->list_lock); 861 862 hash_added = batadv_hash_add(bat_priv->tt.global_hash, 863 batadv_compare_tt, 864 batadv_choose_orig, common, 865 &common->hash_entry); 866 867 if (unlikely(hash_added != 0)) { 868 /* remove the reference for the hash */ 869 batadv_tt_global_entry_free_ref(tt_global_entry); 870 goto out_remove; 871 } 872 } else { 873 common = &tt_global_entry->common; 874 /* If there is already a global entry, we can use this one for 875 * our processing. 876 * But if we are trying to add a temporary client then here are 877 * two options at this point: 878 * 1) the global client is not a temporary client: the global 879 * client has to be left as it is, temporary information 880 * should never override any already known client state 881 * 2) the global client is a temporary client: purge the 882 * originator list and add the new one orig_entry 883 */ 884 if (flags & BATADV_TT_CLIENT_TEMP) { 885 if (!(common->flags & BATADV_TT_CLIENT_TEMP)) 886 goto out; 887 if (batadv_tt_global_entry_has_orig(tt_global_entry, 888 orig_node)) 889 goto out_remove; 890 batadv_tt_global_del_orig_list(tt_global_entry); 891 goto add_orig_entry; 892 } 893 894 /* if the client was temporary added before receiving the first 895 * OGM announcing it, we have to clear the TEMP flag 896 */ 897 common->flags &= ~BATADV_TT_CLIENT_TEMP; 898 899 /* the change can carry possible "attribute" flags like the 900 * TT_CLIENT_WIFI, therefore they have to be copied in the 901 * client entry 902 */ 903 tt_global_entry->common.flags |= flags; 904 905 /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only 906 * one originator left in the list and we previously received a 907 * delete + roaming change for this originator. 908 * 909 * We should first delete the old originator before adding the 910 * new one. 911 */ 912 if (common->flags & BATADV_TT_CLIENT_ROAM) { 913 batadv_tt_global_del_orig_list(tt_global_entry); 914 common->flags &= ~BATADV_TT_CLIENT_ROAM; 915 tt_global_entry->roam_at = 0; 916 } 917 } 918 add_orig_entry: 919 /* add the new orig_entry (if needed) or update it */ 920 batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn); 921 922 batadv_dbg(BATADV_DBG_TT, bat_priv, 923 "Creating new global tt entry: %pM (via %pM)\n", 924 common->addr, orig_node->orig); 925 ret = 1; 926 927 out_remove: 928 929 /* remove address from local hash if present */ 930 local_flags = batadv_tt_local_remove(bat_priv, tt_addr, 931 "global tt received", 932 flags & BATADV_TT_CLIENT_ROAM); 933 tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI; 934 935 if (!(flags & BATADV_TT_CLIENT_ROAM)) 936 /* this is a normal global add. Therefore the client is not in a 937 * roaming state anymore. 938 */ 939 tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM; 940 941 out: 942 if (tt_global_entry) 943 batadv_tt_global_entry_free_ref(tt_global_entry); 944 if (tt_local_entry) 945 batadv_tt_local_entry_free_ref(tt_local_entry); 946 return ret; 947 } 948 949 /* batadv_transtable_best_orig - Get best originator list entry from tt entry 950 * @tt_global_entry: global translation table entry to be analyzed 951 * 952 * This functon assumes the caller holds rcu_read_lock(). 953 * Returns best originator list entry or NULL on errors. 954 */ 955 static struct batadv_tt_orig_list_entry * 956 batadv_transtable_best_orig(struct batadv_tt_global_entry *tt_global_entry) 957 { 958 struct batadv_neigh_node *router = NULL; 959 struct hlist_head *head; 960 struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL; 961 int best_tq = 0; 962 963 head = &tt_global_entry->orig_list; 964 hlist_for_each_entry_rcu(orig_entry, head, list) { 965 router = batadv_orig_node_get_router(orig_entry->orig_node); 966 if (!router) 967 continue; 968 969 if (router->tq_avg > best_tq) { 970 best_entry = orig_entry; 971 best_tq = router->tq_avg; 972 } 973 974 batadv_neigh_node_free_ref(router); 975 } 976 977 return best_entry; 978 } 979 980 /* batadv_tt_global_print_entry - print all orig nodes who announce the address 981 * for this global entry 982 * @tt_global_entry: global translation table entry to be printed 983 * @seq: debugfs table seq_file struct 984 * 985 * This functon assumes the caller holds rcu_read_lock(). 986 */ 987 static void 988 batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry, 989 struct seq_file *seq) 990 { 991 struct hlist_head *head; 992 struct batadv_tt_orig_list_entry *orig_entry, *best_entry; 993 struct batadv_tt_common_entry *tt_common_entry; 994 uint16_t flags; 995 uint8_t last_ttvn; 996 997 tt_common_entry = &tt_global_entry->common; 998 flags = tt_common_entry->flags; 999 1000 best_entry = batadv_transtable_best_orig(tt_global_entry); 1001 if (best_entry) { 1002 last_ttvn = atomic_read(&best_entry->orig_node->last_ttvn); 1003 seq_printf(seq, 1004 " %c %pM (%3u) via %pM (%3u) (%#.4x) [%c%c%c]\n", 1005 '*', tt_global_entry->common.addr, 1006 best_entry->ttvn, best_entry->orig_node->orig, 1007 last_ttvn, best_entry->orig_node->tt_crc, 1008 (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'), 1009 (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'), 1010 (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.')); 1011 } 1012 1013 head = &tt_global_entry->orig_list; 1014 1015 hlist_for_each_entry_rcu(orig_entry, head, list) { 1016 if (best_entry == orig_entry) 1017 continue; 1018 1019 last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn); 1020 seq_printf(seq, " %c %pM (%3u) via %pM (%3u) [%c%c%c]\n", 1021 '+', tt_global_entry->common.addr, 1022 orig_entry->ttvn, orig_entry->orig_node->orig, 1023 last_ttvn, 1024 (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'), 1025 (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'), 1026 (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.')); 1027 } 1028 } 1029 1030 int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset) 1031 { 1032 struct net_device *net_dev = (struct net_device *)seq->private; 1033 struct batadv_priv *bat_priv = netdev_priv(net_dev); 1034 struct batadv_hashtable *hash = bat_priv->tt.global_hash; 1035 struct batadv_tt_common_entry *tt_common_entry; 1036 struct batadv_tt_global_entry *tt_global; 1037 struct batadv_hard_iface *primary_if; 1038 struct hlist_head *head; 1039 uint32_t i; 1040 1041 primary_if = batadv_seq_print_text_primary_if_get(seq); 1042 if (!primary_if) 1043 goto out; 1044 1045 seq_printf(seq, 1046 "Globally announced TT entries received via the mesh %s\n", 1047 net_dev->name); 1048 seq_printf(seq, " %-13s %s %-15s %s (%-6s) %s\n", 1049 "Client", "(TTVN)", "Originator", "(Curr TTVN)", "CRC", 1050 "Flags"); 1051 1052 for (i = 0; i < hash->size; i++) { 1053 head = &hash->table[i]; 1054 1055 rcu_read_lock(); 1056 hlist_for_each_entry_rcu(tt_common_entry, 1057 head, hash_entry) { 1058 tt_global = container_of(tt_common_entry, 1059 struct batadv_tt_global_entry, 1060 common); 1061 batadv_tt_global_print_entry(tt_global, seq); 1062 } 1063 rcu_read_unlock(); 1064 } 1065 out: 1066 if (primary_if) 1067 batadv_hardif_free_ref(primary_if); 1068 return 0; 1069 } 1070 1071 /* deletes the orig list of a tt_global_entry */ 1072 static void 1073 batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry) 1074 { 1075 struct hlist_head *head; 1076 struct hlist_node *safe; 1077 struct batadv_tt_orig_list_entry *orig_entry; 1078 1079 spin_lock_bh(&tt_global_entry->list_lock); 1080 head = &tt_global_entry->orig_list; 1081 hlist_for_each_entry_safe(orig_entry, safe, head, list) { 1082 hlist_del_rcu(&orig_entry->list); 1083 batadv_tt_orig_list_entry_free_ref(orig_entry); 1084 } 1085 spin_unlock_bh(&tt_global_entry->list_lock); 1086 } 1087 1088 static void 1089 batadv_tt_global_del_orig_entry(struct batadv_priv *bat_priv, 1090 struct batadv_tt_global_entry *tt_global_entry, 1091 struct batadv_orig_node *orig_node, 1092 const char *message) 1093 { 1094 struct hlist_head *head; 1095 struct hlist_node *safe; 1096 struct batadv_tt_orig_list_entry *orig_entry; 1097 1098 spin_lock_bh(&tt_global_entry->list_lock); 1099 head = &tt_global_entry->orig_list; 1100 hlist_for_each_entry_safe(orig_entry, safe, head, list) { 1101 if (orig_entry->orig_node == orig_node) { 1102 batadv_dbg(BATADV_DBG_TT, bat_priv, 1103 "Deleting %pM from global tt entry %pM: %s\n", 1104 orig_node->orig, 1105 tt_global_entry->common.addr, message); 1106 hlist_del_rcu(&orig_entry->list); 1107 batadv_tt_orig_list_entry_free_ref(orig_entry); 1108 } 1109 } 1110 spin_unlock_bh(&tt_global_entry->list_lock); 1111 } 1112 1113 /* If the client is to be deleted, we check if it is the last origantor entry 1114 * within tt_global entry. If yes, we set the BATADV_TT_CLIENT_ROAM flag and the 1115 * timer, otherwise we simply remove the originator scheduled for deletion. 1116 */ 1117 static void 1118 batadv_tt_global_del_roaming(struct batadv_priv *bat_priv, 1119 struct batadv_tt_global_entry *tt_global_entry, 1120 struct batadv_orig_node *orig_node, 1121 const char *message) 1122 { 1123 bool last_entry = true; 1124 struct hlist_head *head; 1125 struct batadv_tt_orig_list_entry *orig_entry; 1126 1127 /* no local entry exists, case 1: 1128 * Check if this is the last one or if other entries exist. 1129 */ 1130 1131 rcu_read_lock(); 1132 head = &tt_global_entry->orig_list; 1133 hlist_for_each_entry_rcu(orig_entry, head, list) { 1134 if (orig_entry->orig_node != orig_node) { 1135 last_entry = false; 1136 break; 1137 } 1138 } 1139 rcu_read_unlock(); 1140 1141 if (last_entry) { 1142 /* its the last one, mark for roaming. */ 1143 tt_global_entry->common.flags |= BATADV_TT_CLIENT_ROAM; 1144 tt_global_entry->roam_at = jiffies; 1145 } else 1146 /* there is another entry, we can simply delete this 1147 * one and can still use the other one. 1148 */ 1149 batadv_tt_global_del_orig_entry(bat_priv, tt_global_entry, 1150 orig_node, message); 1151 } 1152 1153 1154 1155 static void batadv_tt_global_del(struct batadv_priv *bat_priv, 1156 struct batadv_orig_node *orig_node, 1157 const unsigned char *addr, 1158 const char *message, bool roaming) 1159 { 1160 struct batadv_tt_global_entry *tt_global_entry; 1161 struct batadv_tt_local_entry *local_entry = NULL; 1162 1163 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); 1164 if (!tt_global_entry) 1165 goto out; 1166 1167 if (!roaming) { 1168 batadv_tt_global_del_orig_entry(bat_priv, tt_global_entry, 1169 orig_node, message); 1170 1171 if (hlist_empty(&tt_global_entry->orig_list)) 1172 batadv_tt_global_free(bat_priv, tt_global_entry, 1173 message); 1174 1175 goto out; 1176 } 1177 1178 /* if we are deleting a global entry due to a roam 1179 * event, there are two possibilities: 1180 * 1) the client roamed from node A to node B => if there 1181 * is only one originator left for this client, we mark 1182 * it with BATADV_TT_CLIENT_ROAM, we start a timer and we 1183 * wait for node B to claim it. In case of timeout 1184 * the entry is purged. 1185 * 1186 * If there are other originators left, we directly delete 1187 * the originator. 1188 * 2) the client roamed to us => we can directly delete 1189 * the global entry, since it is useless now. 1190 */ 1191 local_entry = batadv_tt_local_hash_find(bat_priv, 1192 tt_global_entry->common.addr); 1193 if (local_entry) { 1194 /* local entry exists, case 2: client roamed to us. */ 1195 batadv_tt_global_del_orig_list(tt_global_entry); 1196 batadv_tt_global_free(bat_priv, tt_global_entry, message); 1197 } else 1198 /* no local entry exists, case 1: check for roaming */ 1199 batadv_tt_global_del_roaming(bat_priv, tt_global_entry, 1200 orig_node, message); 1201 1202 1203 out: 1204 if (tt_global_entry) 1205 batadv_tt_global_entry_free_ref(tt_global_entry); 1206 if (local_entry) 1207 batadv_tt_local_entry_free_ref(local_entry); 1208 } 1209 1210 void batadv_tt_global_del_orig(struct batadv_priv *bat_priv, 1211 struct batadv_orig_node *orig_node, 1212 const char *message) 1213 { 1214 struct batadv_tt_global_entry *tt_global; 1215 struct batadv_tt_common_entry *tt_common_entry; 1216 uint32_t i; 1217 struct batadv_hashtable *hash = bat_priv->tt.global_hash; 1218 struct hlist_node *safe; 1219 struct hlist_head *head; 1220 spinlock_t *list_lock; /* protects write access to the hash lists */ 1221 1222 if (!hash) 1223 return; 1224 1225 for (i = 0; i < hash->size; i++) { 1226 head = &hash->table[i]; 1227 list_lock = &hash->list_locks[i]; 1228 1229 spin_lock_bh(list_lock); 1230 hlist_for_each_entry_safe(tt_common_entry, safe, 1231 head, hash_entry) { 1232 tt_global = container_of(tt_common_entry, 1233 struct batadv_tt_global_entry, 1234 common); 1235 1236 batadv_tt_global_del_orig_entry(bat_priv, tt_global, 1237 orig_node, message); 1238 1239 if (hlist_empty(&tt_global->orig_list)) { 1240 batadv_dbg(BATADV_DBG_TT, bat_priv, 1241 "Deleting global tt entry %pM: %s\n", 1242 tt_global->common.addr, message); 1243 hlist_del_rcu(&tt_common_entry->hash_entry); 1244 batadv_tt_global_entry_free_ref(tt_global); 1245 } 1246 } 1247 spin_unlock_bh(list_lock); 1248 } 1249 orig_node->tt_initialised = false; 1250 } 1251 1252 static bool batadv_tt_global_to_purge(struct batadv_tt_global_entry *tt_global, 1253 char **msg) 1254 { 1255 bool purge = false; 1256 unsigned long roam_timeout = BATADV_TT_CLIENT_ROAM_TIMEOUT; 1257 unsigned long temp_timeout = BATADV_TT_CLIENT_TEMP_TIMEOUT; 1258 1259 if ((tt_global->common.flags & BATADV_TT_CLIENT_ROAM) && 1260 batadv_has_timed_out(tt_global->roam_at, roam_timeout)) { 1261 purge = true; 1262 *msg = "Roaming timeout\n"; 1263 } 1264 1265 if ((tt_global->common.flags & BATADV_TT_CLIENT_TEMP) && 1266 batadv_has_timed_out(tt_global->common.added_at, temp_timeout)) { 1267 purge = true; 1268 *msg = "Temporary client timeout\n"; 1269 } 1270 1271 return purge; 1272 } 1273 1274 static void batadv_tt_global_purge(struct batadv_priv *bat_priv) 1275 { 1276 struct batadv_hashtable *hash = bat_priv->tt.global_hash; 1277 struct hlist_head *head; 1278 struct hlist_node *node_tmp; 1279 spinlock_t *list_lock; /* protects write access to the hash lists */ 1280 uint32_t i; 1281 char *msg = NULL; 1282 struct batadv_tt_common_entry *tt_common; 1283 struct batadv_tt_global_entry *tt_global; 1284 1285 for (i = 0; i < hash->size; i++) { 1286 head = &hash->table[i]; 1287 list_lock = &hash->list_locks[i]; 1288 1289 spin_lock_bh(list_lock); 1290 hlist_for_each_entry_safe(tt_common, node_tmp, head, 1291 hash_entry) { 1292 tt_global = container_of(tt_common, 1293 struct batadv_tt_global_entry, 1294 common); 1295 1296 if (!batadv_tt_global_to_purge(tt_global, &msg)) 1297 continue; 1298 1299 batadv_dbg(BATADV_DBG_TT, bat_priv, 1300 "Deleting global tt entry (%pM): %s\n", 1301 tt_global->common.addr, msg); 1302 1303 hlist_del_rcu(&tt_common->hash_entry); 1304 1305 batadv_tt_global_entry_free_ref(tt_global); 1306 } 1307 spin_unlock_bh(list_lock); 1308 } 1309 } 1310 1311 static void batadv_tt_global_table_free(struct batadv_priv *bat_priv) 1312 { 1313 struct batadv_hashtable *hash; 1314 spinlock_t *list_lock; /* protects write access to the hash lists */ 1315 struct batadv_tt_common_entry *tt_common_entry; 1316 struct batadv_tt_global_entry *tt_global; 1317 struct hlist_node *node_tmp; 1318 struct hlist_head *head; 1319 uint32_t i; 1320 1321 if (!bat_priv->tt.global_hash) 1322 return; 1323 1324 hash = bat_priv->tt.global_hash; 1325 1326 for (i = 0; i < hash->size; i++) { 1327 head = &hash->table[i]; 1328 list_lock = &hash->list_locks[i]; 1329 1330 spin_lock_bh(list_lock); 1331 hlist_for_each_entry_safe(tt_common_entry, node_tmp, 1332 head, hash_entry) { 1333 hlist_del_rcu(&tt_common_entry->hash_entry); 1334 tt_global = container_of(tt_common_entry, 1335 struct batadv_tt_global_entry, 1336 common); 1337 batadv_tt_global_entry_free_ref(tt_global); 1338 } 1339 spin_unlock_bh(list_lock); 1340 } 1341 1342 batadv_hash_destroy(hash); 1343 1344 bat_priv->tt.global_hash = NULL; 1345 } 1346 1347 static bool 1348 _batadv_is_ap_isolated(struct batadv_tt_local_entry *tt_local_entry, 1349 struct batadv_tt_global_entry *tt_global_entry) 1350 { 1351 bool ret = false; 1352 1353 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_WIFI && 1354 tt_global_entry->common.flags & BATADV_TT_CLIENT_WIFI) 1355 ret = true; 1356 1357 return ret; 1358 } 1359 1360 struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv, 1361 const uint8_t *src, 1362 const uint8_t *addr) 1363 { 1364 struct batadv_tt_local_entry *tt_local_entry = NULL; 1365 struct batadv_tt_global_entry *tt_global_entry = NULL; 1366 struct batadv_orig_node *orig_node = NULL; 1367 struct batadv_tt_orig_list_entry *best_entry; 1368 1369 if (src && atomic_read(&bat_priv->ap_isolation)) { 1370 tt_local_entry = batadv_tt_local_hash_find(bat_priv, src); 1371 if (!tt_local_entry || 1372 (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)) 1373 goto out; 1374 } 1375 1376 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); 1377 if (!tt_global_entry) 1378 goto out; 1379 1380 /* check whether the clients should not communicate due to AP 1381 * isolation 1382 */ 1383 if (tt_local_entry && 1384 _batadv_is_ap_isolated(tt_local_entry, tt_global_entry)) 1385 goto out; 1386 1387 rcu_read_lock(); 1388 best_entry = batadv_transtable_best_orig(tt_global_entry); 1389 /* found anything? */ 1390 if (best_entry) 1391 orig_node = best_entry->orig_node; 1392 if (orig_node && !atomic_inc_not_zero(&orig_node->refcount)) 1393 orig_node = NULL; 1394 rcu_read_unlock(); 1395 1396 out: 1397 if (tt_global_entry) 1398 batadv_tt_global_entry_free_ref(tt_global_entry); 1399 if (tt_local_entry) 1400 batadv_tt_local_entry_free_ref(tt_local_entry); 1401 1402 return orig_node; 1403 } 1404 1405 /* Calculates the checksum of the local table of a given orig_node */ 1406 static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv, 1407 struct batadv_orig_node *orig_node) 1408 { 1409 uint16_t total = 0, total_one; 1410 struct batadv_hashtable *hash = bat_priv->tt.global_hash; 1411 struct batadv_tt_common_entry *tt_common; 1412 struct batadv_tt_global_entry *tt_global; 1413 struct hlist_head *head; 1414 uint32_t i; 1415 int j; 1416 1417 for (i = 0; i < hash->size; i++) { 1418 head = &hash->table[i]; 1419 1420 rcu_read_lock(); 1421 hlist_for_each_entry_rcu(tt_common, head, hash_entry) { 1422 tt_global = container_of(tt_common, 1423 struct batadv_tt_global_entry, 1424 common); 1425 /* Roaming clients are in the global table for 1426 * consistency only. They don't have to be 1427 * taken into account while computing the 1428 * global crc 1429 */ 1430 if (tt_common->flags & BATADV_TT_CLIENT_ROAM) 1431 continue; 1432 /* Temporary clients have not been announced yet, so 1433 * they have to be skipped while computing the global 1434 * crc 1435 */ 1436 if (tt_common->flags & BATADV_TT_CLIENT_TEMP) 1437 continue; 1438 1439 /* find out if this global entry is announced by this 1440 * originator 1441 */ 1442 if (!batadv_tt_global_entry_has_orig(tt_global, 1443 orig_node)) 1444 continue; 1445 1446 total_one = 0; 1447 for (j = 0; j < ETH_ALEN; j++) 1448 total_one = crc16_byte(total_one, 1449 tt_common->addr[j]); 1450 total ^= total_one; 1451 } 1452 rcu_read_unlock(); 1453 } 1454 1455 return total; 1456 } 1457 1458 /* Calculates the checksum of the local table */ 1459 static uint16_t batadv_tt_local_crc(struct batadv_priv *bat_priv) 1460 { 1461 uint16_t total = 0, total_one; 1462 struct batadv_hashtable *hash = bat_priv->tt.local_hash; 1463 struct batadv_tt_common_entry *tt_common; 1464 struct hlist_head *head; 1465 uint32_t i; 1466 int j; 1467 1468 for (i = 0; i < hash->size; i++) { 1469 head = &hash->table[i]; 1470 1471 rcu_read_lock(); 1472 hlist_for_each_entry_rcu(tt_common, head, hash_entry) { 1473 /* not yet committed clients have not to be taken into 1474 * account while computing the CRC 1475 */ 1476 if (tt_common->flags & BATADV_TT_CLIENT_NEW) 1477 continue; 1478 total_one = 0; 1479 for (j = 0; j < ETH_ALEN; j++) 1480 total_one = crc16_byte(total_one, 1481 tt_common->addr[j]); 1482 total ^= total_one; 1483 } 1484 rcu_read_unlock(); 1485 } 1486 1487 return total; 1488 } 1489 1490 static void batadv_tt_req_list_free(struct batadv_priv *bat_priv) 1491 { 1492 struct batadv_tt_req_node *node, *safe; 1493 1494 spin_lock_bh(&bat_priv->tt.req_list_lock); 1495 1496 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { 1497 list_del(&node->list); 1498 kfree(node); 1499 } 1500 1501 spin_unlock_bh(&bat_priv->tt.req_list_lock); 1502 } 1503 1504 static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv, 1505 struct batadv_orig_node *orig_node, 1506 const unsigned char *tt_buff, 1507 uint8_t tt_num_changes) 1508 { 1509 uint16_t tt_buff_len = batadv_tt_len(tt_num_changes); 1510 1511 /* Replace the old buffer only if I received something in the 1512 * last OGM (the OGM could carry no changes) 1513 */ 1514 spin_lock_bh(&orig_node->tt_buff_lock); 1515 if (tt_buff_len > 0) { 1516 kfree(orig_node->tt_buff); 1517 orig_node->tt_buff_len = 0; 1518 orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC); 1519 if (orig_node->tt_buff) { 1520 memcpy(orig_node->tt_buff, tt_buff, tt_buff_len); 1521 orig_node->tt_buff_len = tt_buff_len; 1522 } 1523 } 1524 spin_unlock_bh(&orig_node->tt_buff_lock); 1525 } 1526 1527 static void batadv_tt_req_purge(struct batadv_priv *bat_priv) 1528 { 1529 struct batadv_tt_req_node *node, *safe; 1530 1531 spin_lock_bh(&bat_priv->tt.req_list_lock); 1532 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { 1533 if (batadv_has_timed_out(node->issued_at, 1534 BATADV_TT_REQUEST_TIMEOUT)) { 1535 list_del(&node->list); 1536 kfree(node); 1537 } 1538 } 1539 spin_unlock_bh(&bat_priv->tt.req_list_lock); 1540 } 1541 1542 /* returns the pointer to the new tt_req_node struct if no request 1543 * has already been issued for this orig_node, NULL otherwise 1544 */ 1545 static struct batadv_tt_req_node * 1546 batadv_new_tt_req_node(struct batadv_priv *bat_priv, 1547 struct batadv_orig_node *orig_node) 1548 { 1549 struct batadv_tt_req_node *tt_req_node_tmp, *tt_req_node = NULL; 1550 1551 spin_lock_bh(&bat_priv->tt.req_list_lock); 1552 list_for_each_entry(tt_req_node_tmp, &bat_priv->tt.req_list, list) { 1553 if (batadv_compare_eth(tt_req_node_tmp, orig_node) && 1554 !batadv_has_timed_out(tt_req_node_tmp->issued_at, 1555 BATADV_TT_REQUEST_TIMEOUT)) 1556 goto unlock; 1557 } 1558 1559 tt_req_node = kmalloc(sizeof(*tt_req_node), GFP_ATOMIC); 1560 if (!tt_req_node) 1561 goto unlock; 1562 1563 memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN); 1564 tt_req_node->issued_at = jiffies; 1565 1566 list_add(&tt_req_node->list, &bat_priv->tt.req_list); 1567 unlock: 1568 spin_unlock_bh(&bat_priv->tt.req_list_lock); 1569 return tt_req_node; 1570 } 1571 1572 /* data_ptr is useless here, but has to be kept to respect the prototype */ 1573 static int batadv_tt_local_valid_entry(const void *entry_ptr, 1574 const void *data_ptr) 1575 { 1576 const struct batadv_tt_common_entry *tt_common_entry = entry_ptr; 1577 1578 if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW) 1579 return 0; 1580 return 1; 1581 } 1582 1583 static int batadv_tt_global_valid(const void *entry_ptr, 1584 const void *data_ptr) 1585 { 1586 const struct batadv_tt_common_entry *tt_common_entry = entry_ptr; 1587 const struct batadv_tt_global_entry *tt_global_entry; 1588 const struct batadv_orig_node *orig_node = data_ptr; 1589 1590 if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM || 1591 tt_common_entry->flags & BATADV_TT_CLIENT_TEMP) 1592 return 0; 1593 1594 tt_global_entry = container_of(tt_common_entry, 1595 struct batadv_tt_global_entry, 1596 common); 1597 1598 return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node); 1599 } 1600 1601 static struct sk_buff * 1602 batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, 1603 struct batadv_hashtable *hash, 1604 struct batadv_priv *bat_priv, 1605 int (*valid_cb)(const void *, const void *), 1606 void *cb_data) 1607 { 1608 struct batadv_tt_common_entry *tt_common_entry; 1609 struct batadv_tt_query_packet *tt_response; 1610 struct batadv_tt_change *tt_change; 1611 struct hlist_head *head; 1612 struct sk_buff *skb = NULL; 1613 uint16_t tt_tot, tt_count; 1614 ssize_t tt_query_size = sizeof(struct batadv_tt_query_packet); 1615 uint32_t i; 1616 size_t len; 1617 1618 if (tt_query_size + tt_len > bat_priv->soft_iface->mtu) { 1619 tt_len = bat_priv->soft_iface->mtu - tt_query_size; 1620 tt_len -= tt_len % sizeof(struct batadv_tt_change); 1621 } 1622 tt_tot = tt_len / sizeof(struct batadv_tt_change); 1623 1624 len = tt_query_size + tt_len; 1625 skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN); 1626 if (!skb) 1627 goto out; 1628 1629 skb_reserve(skb, ETH_HLEN); 1630 tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len); 1631 tt_response->ttvn = ttvn; 1632 1633 tt_change = (struct batadv_tt_change *)(skb->data + tt_query_size); 1634 tt_count = 0; 1635 1636 rcu_read_lock(); 1637 for (i = 0; i < hash->size; i++) { 1638 head = &hash->table[i]; 1639 1640 hlist_for_each_entry_rcu(tt_common_entry, 1641 head, hash_entry) { 1642 if (tt_count == tt_tot) 1643 break; 1644 1645 if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data))) 1646 continue; 1647 1648 memcpy(tt_change->addr, tt_common_entry->addr, 1649 ETH_ALEN); 1650 tt_change->flags = tt_common_entry->flags; 1651 1652 tt_count++; 1653 tt_change++; 1654 } 1655 } 1656 rcu_read_unlock(); 1657 1658 /* store in the message the number of entries we have successfully 1659 * copied 1660 */ 1661 tt_response->tt_data = htons(tt_count); 1662 1663 out: 1664 return skb; 1665 } 1666 1667 static int batadv_send_tt_request(struct batadv_priv *bat_priv, 1668 struct batadv_orig_node *dst_orig_node, 1669 uint8_t ttvn, uint16_t tt_crc, 1670 bool full_table) 1671 { 1672 struct sk_buff *skb = NULL; 1673 struct batadv_tt_query_packet *tt_request; 1674 struct batadv_hard_iface *primary_if; 1675 struct batadv_tt_req_node *tt_req_node = NULL; 1676 int ret = 1; 1677 size_t tt_req_len; 1678 1679 primary_if = batadv_primary_if_get_selected(bat_priv); 1680 if (!primary_if) 1681 goto out; 1682 1683 /* The new tt_req will be issued only if I'm not waiting for a 1684 * reply from the same orig_node yet 1685 */ 1686 tt_req_node = batadv_new_tt_req_node(bat_priv, dst_orig_node); 1687 if (!tt_req_node) 1688 goto out; 1689 1690 skb = netdev_alloc_skb_ip_align(NULL, sizeof(*tt_request) + ETH_HLEN); 1691 if (!skb) 1692 goto out; 1693 1694 skb_reserve(skb, ETH_HLEN); 1695 1696 tt_req_len = sizeof(*tt_request); 1697 tt_request = (struct batadv_tt_query_packet *)skb_put(skb, tt_req_len); 1698 1699 tt_request->header.packet_type = BATADV_TT_QUERY; 1700 tt_request->header.version = BATADV_COMPAT_VERSION; 1701 memcpy(tt_request->src, primary_if->net_dev->dev_addr, ETH_ALEN); 1702 memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN); 1703 tt_request->header.ttl = BATADV_TTL; 1704 tt_request->ttvn = ttvn; 1705 tt_request->tt_data = htons(tt_crc); 1706 tt_request->flags = BATADV_TT_REQUEST; 1707 1708 if (full_table) 1709 tt_request->flags |= BATADV_TT_FULL_TABLE; 1710 1711 batadv_dbg(BATADV_DBG_TT, bat_priv, "Sending TT_REQUEST to %pM [%c]\n", 1712 dst_orig_node->orig, (full_table ? 'F' : '.')); 1713 1714 batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX); 1715 1716 if (batadv_send_skb_to_orig(skb, dst_orig_node, NULL) != NET_XMIT_DROP) 1717 ret = 0; 1718 1719 out: 1720 if (primary_if) 1721 batadv_hardif_free_ref(primary_if); 1722 if (ret) 1723 kfree_skb(skb); 1724 if (ret && tt_req_node) { 1725 spin_lock_bh(&bat_priv->tt.req_list_lock); 1726 list_del(&tt_req_node->list); 1727 spin_unlock_bh(&bat_priv->tt.req_list_lock); 1728 kfree(tt_req_node); 1729 } 1730 return ret; 1731 } 1732 1733 static bool 1734 batadv_send_other_tt_response(struct batadv_priv *bat_priv, 1735 struct batadv_tt_query_packet *tt_request) 1736 { 1737 struct batadv_orig_node *req_dst_orig_node; 1738 struct batadv_orig_node *res_dst_orig_node = NULL; 1739 uint8_t orig_ttvn, req_ttvn, ttvn; 1740 int res, ret = false; 1741 unsigned char *tt_buff; 1742 bool full_table; 1743 uint16_t tt_len, tt_tot; 1744 struct sk_buff *skb = NULL; 1745 struct batadv_tt_query_packet *tt_response; 1746 uint8_t *packet_pos; 1747 size_t len; 1748 1749 batadv_dbg(BATADV_DBG_TT, bat_priv, 1750 "Received TT_REQUEST from %pM for ttvn: %u (%pM) [%c]\n", 1751 tt_request->src, tt_request->ttvn, tt_request->dst, 1752 (tt_request->flags & BATADV_TT_FULL_TABLE ? 'F' : '.')); 1753 1754 /* Let's get the orig node of the REAL destination */ 1755 req_dst_orig_node = batadv_orig_hash_find(bat_priv, tt_request->dst); 1756 if (!req_dst_orig_node) 1757 goto out; 1758 1759 res_dst_orig_node = batadv_orig_hash_find(bat_priv, tt_request->src); 1760 if (!res_dst_orig_node) 1761 goto out; 1762 1763 orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn); 1764 req_ttvn = tt_request->ttvn; 1765 1766 /* I don't have the requested data */ 1767 if (orig_ttvn != req_ttvn || 1768 tt_request->tt_data != htons(req_dst_orig_node->tt_crc)) 1769 goto out; 1770 1771 /* If the full table has been explicitly requested */ 1772 if (tt_request->flags & BATADV_TT_FULL_TABLE || 1773 !req_dst_orig_node->tt_buff) 1774 full_table = true; 1775 else 1776 full_table = false; 1777 1778 /* In this version, fragmentation is not implemented, then 1779 * I'll send only one packet with as much TT entries as I can 1780 */ 1781 if (!full_table) { 1782 spin_lock_bh(&req_dst_orig_node->tt_buff_lock); 1783 tt_len = req_dst_orig_node->tt_buff_len; 1784 tt_tot = tt_len / sizeof(struct batadv_tt_change); 1785 1786 len = sizeof(*tt_response) + tt_len; 1787 skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN); 1788 if (!skb) 1789 goto unlock; 1790 1791 skb_reserve(skb, ETH_HLEN); 1792 packet_pos = skb_put(skb, len); 1793 tt_response = (struct batadv_tt_query_packet *)packet_pos; 1794 tt_response->ttvn = req_ttvn; 1795 tt_response->tt_data = htons(tt_tot); 1796 1797 tt_buff = skb->data + sizeof(*tt_response); 1798 /* Copy the last orig_node's OGM buffer */ 1799 memcpy(tt_buff, req_dst_orig_node->tt_buff, 1800 req_dst_orig_node->tt_buff_len); 1801 1802 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); 1803 } else { 1804 tt_len = (uint16_t)atomic_read(&req_dst_orig_node->tt_size); 1805 tt_len *= sizeof(struct batadv_tt_change); 1806 ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn); 1807 1808 skb = batadv_tt_response_fill_table(tt_len, ttvn, 1809 bat_priv->tt.global_hash, 1810 bat_priv, 1811 batadv_tt_global_valid, 1812 req_dst_orig_node); 1813 if (!skb) 1814 goto out; 1815 1816 tt_response = (struct batadv_tt_query_packet *)skb->data; 1817 } 1818 1819 tt_response->header.packet_type = BATADV_TT_QUERY; 1820 tt_response->header.version = BATADV_COMPAT_VERSION; 1821 tt_response->header.ttl = BATADV_TTL; 1822 memcpy(tt_response->src, req_dst_orig_node->orig, ETH_ALEN); 1823 memcpy(tt_response->dst, tt_request->src, ETH_ALEN); 1824 tt_response->flags = BATADV_TT_RESPONSE; 1825 1826 if (full_table) 1827 tt_response->flags |= BATADV_TT_FULL_TABLE; 1828 1829 batadv_dbg(BATADV_DBG_TT, bat_priv, 1830 "Sending TT_RESPONSE %pM for %pM (ttvn: %u)\n", 1831 res_dst_orig_node->orig, req_dst_orig_node->orig, req_ttvn); 1832 1833 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX); 1834 1835 res = batadv_send_skb_to_orig(skb, res_dst_orig_node, NULL); 1836 if (res != NET_XMIT_DROP) 1837 ret = true; 1838 1839 goto out; 1840 1841 unlock: 1842 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); 1843 1844 out: 1845 if (res_dst_orig_node) 1846 batadv_orig_node_free_ref(res_dst_orig_node); 1847 if (req_dst_orig_node) 1848 batadv_orig_node_free_ref(req_dst_orig_node); 1849 if (!ret) 1850 kfree_skb(skb); 1851 return ret; 1852 } 1853 1854 static bool 1855 batadv_send_my_tt_response(struct batadv_priv *bat_priv, 1856 struct batadv_tt_query_packet *tt_request) 1857 { 1858 struct batadv_orig_node *orig_node; 1859 struct batadv_hard_iface *primary_if = NULL; 1860 uint8_t my_ttvn, req_ttvn, ttvn; 1861 int ret = false; 1862 unsigned char *tt_buff; 1863 bool full_table; 1864 uint16_t tt_len, tt_tot; 1865 struct sk_buff *skb = NULL; 1866 struct batadv_tt_query_packet *tt_response; 1867 uint8_t *packet_pos; 1868 size_t len; 1869 1870 batadv_dbg(BATADV_DBG_TT, bat_priv, 1871 "Received TT_REQUEST from %pM for ttvn: %u (me) [%c]\n", 1872 tt_request->src, tt_request->ttvn, 1873 (tt_request->flags & BATADV_TT_FULL_TABLE ? 'F' : '.')); 1874 1875 1876 my_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); 1877 req_ttvn = tt_request->ttvn; 1878 1879 orig_node = batadv_orig_hash_find(bat_priv, tt_request->src); 1880 if (!orig_node) 1881 goto out; 1882 1883 primary_if = batadv_primary_if_get_selected(bat_priv); 1884 if (!primary_if) 1885 goto out; 1886 1887 /* If the full table has been explicitly requested or the gap 1888 * is too big send the whole local translation table 1889 */ 1890 if (tt_request->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn || 1891 !bat_priv->tt.last_changeset) 1892 full_table = true; 1893 else 1894 full_table = false; 1895 1896 /* In this version, fragmentation is not implemented, then 1897 * I'll send only one packet with as much TT entries as I can 1898 */ 1899 if (!full_table) { 1900 spin_lock_bh(&bat_priv->tt.last_changeset_lock); 1901 tt_len = bat_priv->tt.last_changeset_len; 1902 tt_tot = tt_len / sizeof(struct batadv_tt_change); 1903 1904 len = sizeof(*tt_response) + tt_len; 1905 skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN); 1906 if (!skb) 1907 goto unlock; 1908 1909 skb_reserve(skb, ETH_HLEN); 1910 packet_pos = skb_put(skb, len); 1911 tt_response = (struct batadv_tt_query_packet *)packet_pos; 1912 tt_response->ttvn = req_ttvn; 1913 tt_response->tt_data = htons(tt_tot); 1914 1915 tt_buff = skb->data + sizeof(*tt_response); 1916 memcpy(tt_buff, bat_priv->tt.last_changeset, 1917 bat_priv->tt.last_changeset_len); 1918 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); 1919 } else { 1920 tt_len = (uint16_t)atomic_read(&bat_priv->tt.local_entry_num); 1921 tt_len *= sizeof(struct batadv_tt_change); 1922 ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); 1923 1924 skb = batadv_tt_response_fill_table(tt_len, ttvn, 1925 bat_priv->tt.local_hash, 1926 bat_priv, 1927 batadv_tt_local_valid_entry, 1928 NULL); 1929 if (!skb) 1930 goto out; 1931 1932 tt_response = (struct batadv_tt_query_packet *)skb->data; 1933 } 1934 1935 tt_response->header.packet_type = BATADV_TT_QUERY; 1936 tt_response->header.version = BATADV_COMPAT_VERSION; 1937 tt_response->header.ttl = BATADV_TTL; 1938 memcpy(tt_response->src, primary_if->net_dev->dev_addr, ETH_ALEN); 1939 memcpy(tt_response->dst, tt_request->src, ETH_ALEN); 1940 tt_response->flags = BATADV_TT_RESPONSE; 1941 1942 if (full_table) 1943 tt_response->flags |= BATADV_TT_FULL_TABLE; 1944 1945 batadv_dbg(BATADV_DBG_TT, bat_priv, 1946 "Sending TT_RESPONSE to %pM [%c]\n", 1947 orig_node->orig, 1948 (tt_response->flags & BATADV_TT_FULL_TABLE ? 'F' : '.')); 1949 1950 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX); 1951 1952 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP) 1953 ret = true; 1954 goto out; 1955 1956 unlock: 1957 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); 1958 out: 1959 if (orig_node) 1960 batadv_orig_node_free_ref(orig_node); 1961 if (primary_if) 1962 batadv_hardif_free_ref(primary_if); 1963 if (!ret) 1964 kfree_skb(skb); 1965 /* This packet was for me, so it doesn't need to be re-routed */ 1966 return true; 1967 } 1968 1969 bool batadv_send_tt_response(struct batadv_priv *bat_priv, 1970 struct batadv_tt_query_packet *tt_request) 1971 { 1972 if (batadv_is_my_mac(bat_priv, tt_request->dst)) { 1973 /* don't answer backbone gws! */ 1974 if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_request->src)) 1975 return true; 1976 1977 return batadv_send_my_tt_response(bat_priv, tt_request); 1978 } else { 1979 return batadv_send_other_tt_response(bat_priv, tt_request); 1980 } 1981 } 1982 1983 static void _batadv_tt_update_changes(struct batadv_priv *bat_priv, 1984 struct batadv_orig_node *orig_node, 1985 struct batadv_tt_change *tt_change, 1986 uint16_t tt_num_changes, uint8_t ttvn) 1987 { 1988 int i; 1989 int roams; 1990 1991 for (i = 0; i < tt_num_changes; i++) { 1992 if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) { 1993 roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM; 1994 batadv_tt_global_del(bat_priv, orig_node, 1995 (tt_change + i)->addr, 1996 "tt removed by changes", 1997 roams); 1998 } else { 1999 if (!batadv_tt_global_add(bat_priv, orig_node, 2000 (tt_change + i)->addr, 2001 (tt_change + i)->flags, ttvn)) 2002 /* In case of problem while storing a 2003 * global_entry, we stop the updating 2004 * procedure without committing the 2005 * ttvn change. This will avoid to send 2006 * corrupted data on tt_request 2007 */ 2008 return; 2009 } 2010 } 2011 orig_node->tt_initialised = true; 2012 } 2013 2014 static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv, 2015 struct batadv_tt_query_packet *tt_response) 2016 { 2017 struct batadv_orig_node *orig_node; 2018 2019 orig_node = batadv_orig_hash_find(bat_priv, tt_response->src); 2020 if (!orig_node) 2021 goto out; 2022 2023 /* Purge the old table first.. */ 2024 batadv_tt_global_del_orig(bat_priv, orig_node, "Received full table"); 2025 2026 _batadv_tt_update_changes(bat_priv, orig_node, 2027 (struct batadv_tt_change *)(tt_response + 1), 2028 ntohs(tt_response->tt_data), 2029 tt_response->ttvn); 2030 2031 spin_lock_bh(&orig_node->tt_buff_lock); 2032 kfree(orig_node->tt_buff); 2033 orig_node->tt_buff_len = 0; 2034 orig_node->tt_buff = NULL; 2035 spin_unlock_bh(&orig_node->tt_buff_lock); 2036 2037 atomic_set(&orig_node->last_ttvn, tt_response->ttvn); 2038 2039 out: 2040 if (orig_node) 2041 batadv_orig_node_free_ref(orig_node); 2042 } 2043 2044 static void batadv_tt_update_changes(struct batadv_priv *bat_priv, 2045 struct batadv_orig_node *orig_node, 2046 uint16_t tt_num_changes, uint8_t ttvn, 2047 struct batadv_tt_change *tt_change) 2048 { 2049 _batadv_tt_update_changes(bat_priv, orig_node, tt_change, 2050 tt_num_changes, ttvn); 2051 2052 batadv_tt_save_orig_buffer(bat_priv, orig_node, 2053 (unsigned char *)tt_change, tt_num_changes); 2054 atomic_set(&orig_node->last_ttvn, ttvn); 2055 } 2056 2057 bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr) 2058 { 2059 struct batadv_tt_local_entry *tt_local_entry; 2060 bool ret = false; 2061 2062 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); 2063 if (!tt_local_entry) 2064 goto out; 2065 /* Check if the client has been logically deleted (but is kept for 2066 * consistency purpose) 2067 */ 2068 if ((tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) || 2069 (tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM)) 2070 goto out; 2071 ret = true; 2072 out: 2073 if (tt_local_entry) 2074 batadv_tt_local_entry_free_ref(tt_local_entry); 2075 return ret; 2076 } 2077 2078 void batadv_handle_tt_response(struct batadv_priv *bat_priv, 2079 struct batadv_tt_query_packet *tt_response) 2080 { 2081 struct batadv_tt_req_node *node, *safe; 2082 struct batadv_orig_node *orig_node = NULL; 2083 struct batadv_tt_change *tt_change; 2084 2085 batadv_dbg(BATADV_DBG_TT, bat_priv, 2086 "Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n", 2087 tt_response->src, tt_response->ttvn, 2088 ntohs(tt_response->tt_data), 2089 (tt_response->flags & BATADV_TT_FULL_TABLE ? 'F' : '.')); 2090 2091 /* we should have never asked a backbone gw */ 2092 if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_response->src)) 2093 goto out; 2094 2095 orig_node = batadv_orig_hash_find(bat_priv, tt_response->src); 2096 if (!orig_node) 2097 goto out; 2098 2099 if (tt_response->flags & BATADV_TT_FULL_TABLE) { 2100 batadv_tt_fill_gtable(bat_priv, tt_response); 2101 } else { 2102 tt_change = (struct batadv_tt_change *)(tt_response + 1); 2103 batadv_tt_update_changes(bat_priv, orig_node, 2104 ntohs(tt_response->tt_data), 2105 tt_response->ttvn, tt_change); 2106 } 2107 2108 /* Delete the tt_req_node from pending tt_requests list */ 2109 spin_lock_bh(&bat_priv->tt.req_list_lock); 2110 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { 2111 if (!batadv_compare_eth(node->addr, tt_response->src)) 2112 continue; 2113 list_del(&node->list); 2114 kfree(node); 2115 } 2116 spin_unlock_bh(&bat_priv->tt.req_list_lock); 2117 2118 /* Recalculate the CRC for this orig_node and store it */ 2119 orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node); 2120 out: 2121 if (orig_node) 2122 batadv_orig_node_free_ref(orig_node); 2123 } 2124 2125 int batadv_tt_init(struct batadv_priv *bat_priv) 2126 { 2127 int ret; 2128 2129 ret = batadv_tt_local_init(bat_priv); 2130 if (ret < 0) 2131 return ret; 2132 2133 ret = batadv_tt_global_init(bat_priv); 2134 if (ret < 0) 2135 return ret; 2136 2137 INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge); 2138 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work, 2139 msecs_to_jiffies(BATADV_TT_WORK_PERIOD)); 2140 2141 return 1; 2142 } 2143 2144 static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv) 2145 { 2146 struct batadv_tt_roam_node *node, *safe; 2147 2148 spin_lock_bh(&bat_priv->tt.roam_list_lock); 2149 2150 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { 2151 list_del(&node->list); 2152 kfree(node); 2153 } 2154 2155 spin_unlock_bh(&bat_priv->tt.roam_list_lock); 2156 } 2157 2158 static void batadv_tt_roam_purge(struct batadv_priv *bat_priv) 2159 { 2160 struct batadv_tt_roam_node *node, *safe; 2161 2162 spin_lock_bh(&bat_priv->tt.roam_list_lock); 2163 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { 2164 if (!batadv_has_timed_out(node->first_time, 2165 BATADV_ROAMING_MAX_TIME)) 2166 continue; 2167 2168 list_del(&node->list); 2169 kfree(node); 2170 } 2171 spin_unlock_bh(&bat_priv->tt.roam_list_lock); 2172 } 2173 2174 /* This function checks whether the client already reached the 2175 * maximum number of possible roaming phases. In this case the ROAMING_ADV 2176 * will not be sent. 2177 * 2178 * returns true if the ROAMING_ADV can be sent, false otherwise 2179 */ 2180 static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv, 2181 uint8_t *client) 2182 { 2183 struct batadv_tt_roam_node *tt_roam_node; 2184 bool ret = false; 2185 2186 spin_lock_bh(&bat_priv->tt.roam_list_lock); 2187 /* The new tt_req will be issued only if I'm not waiting for a 2188 * reply from the same orig_node yet 2189 */ 2190 list_for_each_entry(tt_roam_node, &bat_priv->tt.roam_list, list) { 2191 if (!batadv_compare_eth(tt_roam_node->addr, client)) 2192 continue; 2193 2194 if (batadv_has_timed_out(tt_roam_node->first_time, 2195 BATADV_ROAMING_MAX_TIME)) 2196 continue; 2197 2198 if (!batadv_atomic_dec_not_zero(&tt_roam_node->counter)) 2199 /* Sorry, you roamed too many times! */ 2200 goto unlock; 2201 ret = true; 2202 break; 2203 } 2204 2205 if (!ret) { 2206 tt_roam_node = kmalloc(sizeof(*tt_roam_node), GFP_ATOMIC); 2207 if (!tt_roam_node) 2208 goto unlock; 2209 2210 tt_roam_node->first_time = jiffies; 2211 atomic_set(&tt_roam_node->counter, 2212 BATADV_ROAMING_MAX_COUNT - 1); 2213 memcpy(tt_roam_node->addr, client, ETH_ALEN); 2214 2215 list_add(&tt_roam_node->list, &bat_priv->tt.roam_list); 2216 ret = true; 2217 } 2218 2219 unlock: 2220 spin_unlock_bh(&bat_priv->tt.roam_list_lock); 2221 return ret; 2222 } 2223 2224 static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, 2225 struct batadv_orig_node *orig_node) 2226 { 2227 struct sk_buff *skb = NULL; 2228 struct batadv_roam_adv_packet *roam_adv_packet; 2229 int ret = 1; 2230 struct batadv_hard_iface *primary_if; 2231 size_t len = sizeof(*roam_adv_packet); 2232 2233 /* before going on we have to check whether the client has 2234 * already roamed to us too many times 2235 */ 2236 if (!batadv_tt_check_roam_count(bat_priv, client)) 2237 goto out; 2238 2239 skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN); 2240 if (!skb) 2241 goto out; 2242 2243 skb_reserve(skb, ETH_HLEN); 2244 2245 roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len); 2246 2247 roam_adv_packet->header.packet_type = BATADV_ROAM_ADV; 2248 roam_adv_packet->header.version = BATADV_COMPAT_VERSION; 2249 roam_adv_packet->header.ttl = BATADV_TTL; 2250 roam_adv_packet->reserved = 0; 2251 primary_if = batadv_primary_if_get_selected(bat_priv); 2252 if (!primary_if) 2253 goto out; 2254 memcpy(roam_adv_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN); 2255 batadv_hardif_free_ref(primary_if); 2256 memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN); 2257 memcpy(roam_adv_packet->client, client, ETH_ALEN); 2258 2259 batadv_dbg(BATADV_DBG_TT, bat_priv, 2260 "Sending ROAMING_ADV to %pM (client %pM)\n", 2261 orig_node->orig, client); 2262 2263 batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX); 2264 2265 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP) 2266 ret = 0; 2267 2268 out: 2269 if (ret && skb) 2270 kfree_skb(skb); 2271 return; 2272 } 2273 2274 static void batadv_tt_purge(struct work_struct *work) 2275 { 2276 struct delayed_work *delayed_work; 2277 struct batadv_priv_tt *priv_tt; 2278 struct batadv_priv *bat_priv; 2279 2280 delayed_work = container_of(work, struct delayed_work, work); 2281 priv_tt = container_of(delayed_work, struct batadv_priv_tt, work); 2282 bat_priv = container_of(priv_tt, struct batadv_priv, tt); 2283 2284 batadv_tt_local_purge(bat_priv); 2285 batadv_tt_global_purge(bat_priv); 2286 batadv_tt_req_purge(bat_priv); 2287 batadv_tt_roam_purge(bat_priv); 2288 2289 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work, 2290 msecs_to_jiffies(BATADV_TT_WORK_PERIOD)); 2291 } 2292 2293 void batadv_tt_free(struct batadv_priv *bat_priv) 2294 { 2295 cancel_delayed_work_sync(&bat_priv->tt.work); 2296 2297 batadv_tt_local_table_free(bat_priv); 2298 batadv_tt_global_table_free(bat_priv); 2299 batadv_tt_req_list_free(bat_priv); 2300 batadv_tt_changes_list_free(bat_priv); 2301 batadv_tt_roam_list_free(bat_priv); 2302 2303 kfree(bat_priv->tt.last_changeset); 2304 } 2305 2306 /* This function will enable or disable the specified flags for all the entries 2307 * in the given hash table and returns the number of modified entries 2308 */ 2309 static uint16_t batadv_tt_set_flags(struct batadv_hashtable *hash, 2310 uint16_t flags, bool enable) 2311 { 2312 uint32_t i; 2313 uint16_t changed_num = 0; 2314 struct hlist_head *head; 2315 struct batadv_tt_common_entry *tt_common_entry; 2316 2317 if (!hash) 2318 goto out; 2319 2320 for (i = 0; i < hash->size; i++) { 2321 head = &hash->table[i]; 2322 2323 rcu_read_lock(); 2324 hlist_for_each_entry_rcu(tt_common_entry, 2325 head, hash_entry) { 2326 if (enable) { 2327 if ((tt_common_entry->flags & flags) == flags) 2328 continue; 2329 tt_common_entry->flags |= flags; 2330 } else { 2331 if (!(tt_common_entry->flags & flags)) 2332 continue; 2333 tt_common_entry->flags &= ~flags; 2334 } 2335 changed_num++; 2336 } 2337 rcu_read_unlock(); 2338 } 2339 out: 2340 return changed_num; 2341 } 2342 2343 /* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */ 2344 static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) 2345 { 2346 struct batadv_hashtable *hash = bat_priv->tt.local_hash; 2347 struct batadv_tt_common_entry *tt_common; 2348 struct batadv_tt_local_entry *tt_local; 2349 struct hlist_node *node_tmp; 2350 struct hlist_head *head; 2351 spinlock_t *list_lock; /* protects write access to the hash lists */ 2352 uint32_t i; 2353 2354 if (!hash) 2355 return; 2356 2357 for (i = 0; i < hash->size; i++) { 2358 head = &hash->table[i]; 2359 list_lock = &hash->list_locks[i]; 2360 2361 spin_lock_bh(list_lock); 2362 hlist_for_each_entry_safe(tt_common, node_tmp, head, 2363 hash_entry) { 2364 if (!(tt_common->flags & BATADV_TT_CLIENT_PENDING)) 2365 continue; 2366 2367 batadv_dbg(BATADV_DBG_TT, bat_priv, 2368 "Deleting local tt entry (%pM): pending\n", 2369 tt_common->addr); 2370 2371 atomic_dec(&bat_priv->tt.local_entry_num); 2372 hlist_del_rcu(&tt_common->hash_entry); 2373 tt_local = container_of(tt_common, 2374 struct batadv_tt_local_entry, 2375 common); 2376 batadv_tt_local_entry_free_ref(tt_local); 2377 } 2378 spin_unlock_bh(list_lock); 2379 } 2380 } 2381 2382 static int batadv_tt_commit_changes(struct batadv_priv *bat_priv, 2383 unsigned char **packet_buff, 2384 int *packet_buff_len, int packet_min_len) 2385 { 2386 uint16_t changed_num = 0; 2387 2388 if (atomic_read(&bat_priv->tt.local_changes) < 1) 2389 return -ENOENT; 2390 2391 changed_num = batadv_tt_set_flags(bat_priv->tt.local_hash, 2392 BATADV_TT_CLIENT_NEW, false); 2393 2394 /* all reset entries have to be counted as local entries */ 2395 atomic_add(changed_num, &bat_priv->tt.local_entry_num); 2396 batadv_tt_local_purge_pending_clients(bat_priv); 2397 bat_priv->tt.local_crc = batadv_tt_local_crc(bat_priv); 2398 2399 /* Increment the TTVN only once per OGM interval */ 2400 atomic_inc(&bat_priv->tt.vn); 2401 batadv_dbg(BATADV_DBG_TT, bat_priv, 2402 "Local changes committed, updating to ttvn %u\n", 2403 (uint8_t)atomic_read(&bat_priv->tt.vn)); 2404 2405 /* reset the sending counter */ 2406 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); 2407 2408 return batadv_tt_changes_fill_buff(bat_priv, packet_buff, 2409 packet_buff_len, packet_min_len); 2410 } 2411 2412 /* when calling this function (hard_iface == primary_if) has to be true */ 2413 int batadv_tt_append_diff(struct batadv_priv *bat_priv, 2414 unsigned char **packet_buff, int *packet_buff_len, 2415 int packet_min_len) 2416 { 2417 int tt_num_changes; 2418 2419 /* if at least one change happened */ 2420 tt_num_changes = batadv_tt_commit_changes(bat_priv, packet_buff, 2421 packet_buff_len, 2422 packet_min_len); 2423 2424 /* if the changes have been sent often enough */ 2425 if ((tt_num_changes < 0) && 2426 (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))) { 2427 batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len, 2428 packet_min_len, packet_min_len); 2429 tt_num_changes = 0; 2430 } 2431 2432 return tt_num_changes; 2433 } 2434 2435 bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src, 2436 uint8_t *dst) 2437 { 2438 struct batadv_tt_local_entry *tt_local_entry = NULL; 2439 struct batadv_tt_global_entry *tt_global_entry = NULL; 2440 bool ret = false; 2441 2442 if (!atomic_read(&bat_priv->ap_isolation)) 2443 goto out; 2444 2445 tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst); 2446 if (!tt_local_entry) 2447 goto out; 2448 2449 tt_global_entry = batadv_tt_global_hash_find(bat_priv, src); 2450 if (!tt_global_entry) 2451 goto out; 2452 2453 if (!_batadv_is_ap_isolated(tt_local_entry, tt_global_entry)) 2454 goto out; 2455 2456 ret = true; 2457 2458 out: 2459 if (tt_global_entry) 2460 batadv_tt_global_entry_free_ref(tt_global_entry); 2461 if (tt_local_entry) 2462 batadv_tt_local_entry_free_ref(tt_local_entry); 2463 return ret; 2464 } 2465 2466 void batadv_tt_update_orig(struct batadv_priv *bat_priv, 2467 struct batadv_orig_node *orig_node, 2468 const unsigned char *tt_buff, uint8_t tt_num_changes, 2469 uint8_t ttvn, uint16_t tt_crc) 2470 { 2471 uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); 2472 bool full_table = true; 2473 struct batadv_tt_change *tt_change; 2474 2475 /* don't care about a backbone gateways updates. */ 2476 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig)) 2477 return; 2478 2479 /* orig table not initialised AND first diff is in the OGM OR the ttvn 2480 * increased by one -> we can apply the attached changes 2481 */ 2482 if ((!orig_node->tt_initialised && ttvn == 1) || 2483 ttvn - orig_ttvn == 1) { 2484 /* the OGM could not contain the changes due to their size or 2485 * because they have already been sent BATADV_TT_OGM_APPEND_MAX 2486 * times. 2487 * In this case send a tt request 2488 */ 2489 if (!tt_num_changes) { 2490 full_table = false; 2491 goto request_table; 2492 } 2493 2494 tt_change = (struct batadv_tt_change *)tt_buff; 2495 batadv_tt_update_changes(bat_priv, orig_node, tt_num_changes, 2496 ttvn, tt_change); 2497 2498 /* Even if we received the precomputed crc with the OGM, we 2499 * prefer to recompute it to spot any possible inconsistency 2500 * in the global table 2501 */ 2502 orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node); 2503 2504 /* The ttvn alone is not enough to guarantee consistency 2505 * because a single value could represent different states 2506 * (due to the wrap around). Thus a node has to check whether 2507 * the resulting table (after applying the changes) is still 2508 * consistent or not. E.g. a node could disconnect while its 2509 * ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case 2510 * checking the CRC value is mandatory to detect the 2511 * inconsistency 2512 */ 2513 if (orig_node->tt_crc != tt_crc) 2514 goto request_table; 2515 } else { 2516 /* if we missed more than one change or our tables are not 2517 * in sync anymore -> request fresh tt data 2518 */ 2519 if (!orig_node->tt_initialised || ttvn != orig_ttvn || 2520 orig_node->tt_crc != tt_crc) { 2521 request_table: 2522 batadv_dbg(BATADV_DBG_TT, bat_priv, 2523 "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u crc: %#.4x last_crc: %#.4x num_changes: %u)\n", 2524 orig_node->orig, ttvn, orig_ttvn, tt_crc, 2525 orig_node->tt_crc, tt_num_changes); 2526 batadv_send_tt_request(bat_priv, orig_node, ttvn, 2527 tt_crc, full_table); 2528 return; 2529 } 2530 } 2531 } 2532 2533 /* returns true whether we know that the client has moved from its old 2534 * originator to another one. This entry is kept is still kept for consistency 2535 * purposes 2536 */ 2537 bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, 2538 uint8_t *addr) 2539 { 2540 struct batadv_tt_global_entry *tt_global_entry; 2541 bool ret = false; 2542 2543 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); 2544 if (!tt_global_entry) 2545 goto out; 2546 2547 ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM; 2548 batadv_tt_global_entry_free_ref(tt_global_entry); 2549 out: 2550 return ret; 2551 } 2552 2553 /** 2554 * batadv_tt_local_client_is_roaming - tells whether the client is roaming 2555 * @bat_priv: the bat priv with all the soft interface information 2556 * @addr: the MAC address of the local client to query 2557 * 2558 * Returns true if the local client is known to be roaming (it is not served by 2559 * this node anymore) or not. If yes, the client is still present in the table 2560 * to keep the latter consistent with the node TTVN 2561 */ 2562 bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv, 2563 uint8_t *addr) 2564 { 2565 struct batadv_tt_local_entry *tt_local_entry; 2566 bool ret = false; 2567 2568 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); 2569 if (!tt_local_entry) 2570 goto out; 2571 2572 ret = tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM; 2573 batadv_tt_local_entry_free_ref(tt_local_entry); 2574 out: 2575 return ret; 2576 } 2577 2578 bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, 2579 struct batadv_orig_node *orig_node, 2580 const unsigned char *addr) 2581 { 2582 bool ret = false; 2583 2584 /* if the originator is a backbone node (meaning it belongs to the same 2585 * LAN of this node) the temporary client must not be added because to 2586 * reach such destination the node must use the LAN instead of the mesh 2587 */ 2588 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig)) 2589 goto out; 2590 2591 if (!batadv_tt_global_add(bat_priv, orig_node, addr, 2592 BATADV_TT_CLIENT_TEMP, 2593 atomic_read(&orig_node->last_ttvn))) 2594 goto out; 2595 2596 batadv_dbg(BATADV_DBG_TT, bat_priv, 2597 "Added temporary global client (addr: %pM orig: %pM)\n", 2598 addr, orig_node->orig); 2599 ret = true; 2600 out: 2601 return ret; 2602 } 2603