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