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->priority = TC_PRIO_CONTROL; 1630 skb_reserve(skb, ETH_HLEN); 1631 tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len); 1632 tt_response->ttvn = ttvn; 1633 1634 tt_change = (struct batadv_tt_change *)(skb->data + tt_query_size); 1635 tt_count = 0; 1636 1637 rcu_read_lock(); 1638 for (i = 0; i < hash->size; i++) { 1639 head = &hash->table[i]; 1640 1641 hlist_for_each_entry_rcu(tt_common_entry, 1642 head, hash_entry) { 1643 if (tt_count == tt_tot) 1644 break; 1645 1646 if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data))) 1647 continue; 1648 1649 memcpy(tt_change->addr, tt_common_entry->addr, 1650 ETH_ALEN); 1651 tt_change->flags = tt_common_entry->flags; 1652 1653 tt_count++; 1654 tt_change++; 1655 } 1656 } 1657 rcu_read_unlock(); 1658 1659 /* store in the message the number of entries we have successfully 1660 * copied 1661 */ 1662 tt_response->tt_data = htons(tt_count); 1663 1664 out: 1665 return skb; 1666 } 1667 1668 static int batadv_send_tt_request(struct batadv_priv *bat_priv, 1669 struct batadv_orig_node *dst_orig_node, 1670 uint8_t ttvn, uint16_t tt_crc, 1671 bool full_table) 1672 { 1673 struct sk_buff *skb = NULL; 1674 struct batadv_tt_query_packet *tt_request; 1675 struct batadv_hard_iface *primary_if; 1676 struct batadv_tt_req_node *tt_req_node = NULL; 1677 int ret = 1; 1678 size_t tt_req_len; 1679 1680 primary_if = batadv_primary_if_get_selected(bat_priv); 1681 if (!primary_if) 1682 goto out; 1683 1684 /* The new tt_req will be issued only if I'm not waiting for a 1685 * reply from the same orig_node yet 1686 */ 1687 tt_req_node = batadv_new_tt_req_node(bat_priv, dst_orig_node); 1688 if (!tt_req_node) 1689 goto out; 1690 1691 skb = netdev_alloc_skb_ip_align(NULL, sizeof(*tt_request) + ETH_HLEN); 1692 if (!skb) 1693 goto out; 1694 1695 skb->priority = TC_PRIO_CONTROL; 1696 skb_reserve(skb, ETH_HLEN); 1697 1698 tt_req_len = sizeof(*tt_request); 1699 tt_request = (struct batadv_tt_query_packet *)skb_put(skb, tt_req_len); 1700 1701 tt_request->header.packet_type = BATADV_TT_QUERY; 1702 tt_request->header.version = BATADV_COMPAT_VERSION; 1703 memcpy(tt_request->src, primary_if->net_dev->dev_addr, ETH_ALEN); 1704 memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN); 1705 tt_request->header.ttl = BATADV_TTL; 1706 tt_request->ttvn = ttvn; 1707 tt_request->tt_data = htons(tt_crc); 1708 tt_request->flags = BATADV_TT_REQUEST; 1709 1710 if (full_table) 1711 tt_request->flags |= BATADV_TT_FULL_TABLE; 1712 1713 batadv_dbg(BATADV_DBG_TT, bat_priv, "Sending TT_REQUEST to %pM [%c]\n", 1714 dst_orig_node->orig, (full_table ? 'F' : '.')); 1715 1716 batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX); 1717 1718 if (batadv_send_skb_to_orig(skb, dst_orig_node, NULL) != NET_XMIT_DROP) 1719 ret = 0; 1720 1721 out: 1722 if (primary_if) 1723 batadv_hardif_free_ref(primary_if); 1724 if (ret) 1725 kfree_skb(skb); 1726 if (ret && tt_req_node) { 1727 spin_lock_bh(&bat_priv->tt.req_list_lock); 1728 list_del(&tt_req_node->list); 1729 spin_unlock_bh(&bat_priv->tt.req_list_lock); 1730 kfree(tt_req_node); 1731 } 1732 return ret; 1733 } 1734 1735 static bool 1736 batadv_send_other_tt_response(struct batadv_priv *bat_priv, 1737 struct batadv_tt_query_packet *tt_request) 1738 { 1739 struct batadv_orig_node *req_dst_orig_node; 1740 struct batadv_orig_node *res_dst_orig_node = NULL; 1741 uint8_t orig_ttvn, req_ttvn, ttvn; 1742 int res, ret = false; 1743 unsigned char *tt_buff; 1744 bool full_table; 1745 uint16_t tt_len, tt_tot; 1746 struct sk_buff *skb = NULL; 1747 struct batadv_tt_query_packet *tt_response; 1748 uint8_t *packet_pos; 1749 size_t len; 1750 1751 batadv_dbg(BATADV_DBG_TT, bat_priv, 1752 "Received TT_REQUEST from %pM for ttvn: %u (%pM) [%c]\n", 1753 tt_request->src, tt_request->ttvn, tt_request->dst, 1754 (tt_request->flags & BATADV_TT_FULL_TABLE ? 'F' : '.')); 1755 1756 /* Let's get the orig node of the REAL destination */ 1757 req_dst_orig_node = batadv_orig_hash_find(bat_priv, tt_request->dst); 1758 if (!req_dst_orig_node) 1759 goto out; 1760 1761 res_dst_orig_node = batadv_orig_hash_find(bat_priv, tt_request->src); 1762 if (!res_dst_orig_node) 1763 goto out; 1764 1765 orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn); 1766 req_ttvn = tt_request->ttvn; 1767 1768 /* I don't have the requested data */ 1769 if (orig_ttvn != req_ttvn || 1770 tt_request->tt_data != htons(req_dst_orig_node->tt_crc)) 1771 goto out; 1772 1773 /* If the full table has been explicitly requested */ 1774 if (tt_request->flags & BATADV_TT_FULL_TABLE || 1775 !req_dst_orig_node->tt_buff) 1776 full_table = true; 1777 else 1778 full_table = false; 1779 1780 /* In this version, fragmentation is not implemented, then 1781 * I'll send only one packet with as much TT entries as I can 1782 */ 1783 if (!full_table) { 1784 spin_lock_bh(&req_dst_orig_node->tt_buff_lock); 1785 tt_len = req_dst_orig_node->tt_buff_len; 1786 tt_tot = tt_len / sizeof(struct batadv_tt_change); 1787 1788 len = sizeof(*tt_response) + tt_len; 1789 skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN); 1790 if (!skb) 1791 goto unlock; 1792 1793 skb->priority = TC_PRIO_CONTROL; 1794 skb_reserve(skb, ETH_HLEN); 1795 packet_pos = skb_put(skb, len); 1796 tt_response = (struct batadv_tt_query_packet *)packet_pos; 1797 tt_response->ttvn = req_ttvn; 1798 tt_response->tt_data = htons(tt_tot); 1799 1800 tt_buff = skb->data + sizeof(*tt_response); 1801 /* Copy the last orig_node's OGM buffer */ 1802 memcpy(tt_buff, req_dst_orig_node->tt_buff, 1803 req_dst_orig_node->tt_buff_len); 1804 1805 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); 1806 } else { 1807 tt_len = (uint16_t)atomic_read(&req_dst_orig_node->tt_size); 1808 tt_len *= sizeof(struct batadv_tt_change); 1809 ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn); 1810 1811 skb = batadv_tt_response_fill_table(tt_len, ttvn, 1812 bat_priv->tt.global_hash, 1813 bat_priv, 1814 batadv_tt_global_valid, 1815 req_dst_orig_node); 1816 if (!skb) 1817 goto out; 1818 1819 tt_response = (struct batadv_tt_query_packet *)skb->data; 1820 } 1821 1822 tt_response->header.packet_type = BATADV_TT_QUERY; 1823 tt_response->header.version = BATADV_COMPAT_VERSION; 1824 tt_response->header.ttl = BATADV_TTL; 1825 memcpy(tt_response->src, req_dst_orig_node->orig, ETH_ALEN); 1826 memcpy(tt_response->dst, tt_request->src, ETH_ALEN); 1827 tt_response->flags = BATADV_TT_RESPONSE; 1828 1829 if (full_table) 1830 tt_response->flags |= BATADV_TT_FULL_TABLE; 1831 1832 batadv_dbg(BATADV_DBG_TT, bat_priv, 1833 "Sending TT_RESPONSE %pM for %pM (ttvn: %u)\n", 1834 res_dst_orig_node->orig, req_dst_orig_node->orig, req_ttvn); 1835 1836 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX); 1837 1838 res = batadv_send_skb_to_orig(skb, res_dst_orig_node, NULL); 1839 if (res != NET_XMIT_DROP) 1840 ret = true; 1841 1842 goto out; 1843 1844 unlock: 1845 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); 1846 1847 out: 1848 if (res_dst_orig_node) 1849 batadv_orig_node_free_ref(res_dst_orig_node); 1850 if (req_dst_orig_node) 1851 batadv_orig_node_free_ref(req_dst_orig_node); 1852 if (!ret) 1853 kfree_skb(skb); 1854 return ret; 1855 } 1856 1857 static bool 1858 batadv_send_my_tt_response(struct batadv_priv *bat_priv, 1859 struct batadv_tt_query_packet *tt_request) 1860 { 1861 struct batadv_orig_node *orig_node; 1862 struct batadv_hard_iface *primary_if = NULL; 1863 uint8_t my_ttvn, req_ttvn, ttvn; 1864 int ret = false; 1865 unsigned char *tt_buff; 1866 bool full_table; 1867 uint16_t tt_len, tt_tot; 1868 struct sk_buff *skb = NULL; 1869 struct batadv_tt_query_packet *tt_response; 1870 uint8_t *packet_pos; 1871 size_t len; 1872 1873 batadv_dbg(BATADV_DBG_TT, bat_priv, 1874 "Received TT_REQUEST from %pM for ttvn: %u (me) [%c]\n", 1875 tt_request->src, tt_request->ttvn, 1876 (tt_request->flags & BATADV_TT_FULL_TABLE ? 'F' : '.')); 1877 1878 1879 my_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); 1880 req_ttvn = tt_request->ttvn; 1881 1882 orig_node = batadv_orig_hash_find(bat_priv, tt_request->src); 1883 if (!orig_node) 1884 goto out; 1885 1886 primary_if = batadv_primary_if_get_selected(bat_priv); 1887 if (!primary_if) 1888 goto out; 1889 1890 /* If the full table has been explicitly requested or the gap 1891 * is too big send the whole local translation table 1892 */ 1893 if (tt_request->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn || 1894 !bat_priv->tt.last_changeset) 1895 full_table = true; 1896 else 1897 full_table = false; 1898 1899 /* In this version, fragmentation is not implemented, then 1900 * I'll send only one packet with as much TT entries as I can 1901 */ 1902 if (!full_table) { 1903 spin_lock_bh(&bat_priv->tt.last_changeset_lock); 1904 tt_len = bat_priv->tt.last_changeset_len; 1905 tt_tot = tt_len / sizeof(struct batadv_tt_change); 1906 1907 len = sizeof(*tt_response) + tt_len; 1908 skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN); 1909 if (!skb) 1910 goto unlock; 1911 1912 skb->priority = TC_PRIO_CONTROL; 1913 skb_reserve(skb, ETH_HLEN); 1914 packet_pos = skb_put(skb, len); 1915 tt_response = (struct batadv_tt_query_packet *)packet_pos; 1916 tt_response->ttvn = req_ttvn; 1917 tt_response->tt_data = htons(tt_tot); 1918 1919 tt_buff = skb->data + sizeof(*tt_response); 1920 memcpy(tt_buff, bat_priv->tt.last_changeset, 1921 bat_priv->tt.last_changeset_len); 1922 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); 1923 } else { 1924 tt_len = (uint16_t)atomic_read(&bat_priv->tt.local_entry_num); 1925 tt_len *= sizeof(struct batadv_tt_change); 1926 ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); 1927 1928 skb = batadv_tt_response_fill_table(tt_len, ttvn, 1929 bat_priv->tt.local_hash, 1930 bat_priv, 1931 batadv_tt_local_valid_entry, 1932 NULL); 1933 if (!skb) 1934 goto out; 1935 1936 tt_response = (struct batadv_tt_query_packet *)skb->data; 1937 } 1938 1939 tt_response->header.packet_type = BATADV_TT_QUERY; 1940 tt_response->header.version = BATADV_COMPAT_VERSION; 1941 tt_response->header.ttl = BATADV_TTL; 1942 memcpy(tt_response->src, primary_if->net_dev->dev_addr, ETH_ALEN); 1943 memcpy(tt_response->dst, tt_request->src, ETH_ALEN); 1944 tt_response->flags = BATADV_TT_RESPONSE; 1945 1946 if (full_table) 1947 tt_response->flags |= BATADV_TT_FULL_TABLE; 1948 1949 batadv_dbg(BATADV_DBG_TT, bat_priv, 1950 "Sending TT_RESPONSE to %pM [%c]\n", 1951 orig_node->orig, 1952 (tt_response->flags & BATADV_TT_FULL_TABLE ? 'F' : '.')); 1953 1954 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX); 1955 1956 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP) 1957 ret = true; 1958 goto out; 1959 1960 unlock: 1961 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); 1962 out: 1963 if (orig_node) 1964 batadv_orig_node_free_ref(orig_node); 1965 if (primary_if) 1966 batadv_hardif_free_ref(primary_if); 1967 if (!ret) 1968 kfree_skb(skb); 1969 /* This packet was for me, so it doesn't need to be re-routed */ 1970 return true; 1971 } 1972 1973 bool batadv_send_tt_response(struct batadv_priv *bat_priv, 1974 struct batadv_tt_query_packet *tt_request) 1975 { 1976 if (batadv_is_my_mac(bat_priv, tt_request->dst)) { 1977 /* don't answer backbone gws! */ 1978 if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_request->src)) 1979 return true; 1980 1981 return batadv_send_my_tt_response(bat_priv, tt_request); 1982 } else { 1983 return batadv_send_other_tt_response(bat_priv, tt_request); 1984 } 1985 } 1986 1987 static void _batadv_tt_update_changes(struct batadv_priv *bat_priv, 1988 struct batadv_orig_node *orig_node, 1989 struct batadv_tt_change *tt_change, 1990 uint16_t tt_num_changes, uint8_t ttvn) 1991 { 1992 int i; 1993 int roams; 1994 1995 for (i = 0; i < tt_num_changes; i++) { 1996 if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) { 1997 roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM; 1998 batadv_tt_global_del(bat_priv, orig_node, 1999 (tt_change + i)->addr, 2000 "tt removed by changes", 2001 roams); 2002 } else { 2003 if (!batadv_tt_global_add(bat_priv, orig_node, 2004 (tt_change + i)->addr, 2005 (tt_change + i)->flags, ttvn)) 2006 /* In case of problem while storing a 2007 * global_entry, we stop the updating 2008 * procedure without committing the 2009 * ttvn change. This will avoid to send 2010 * corrupted data on tt_request 2011 */ 2012 return; 2013 } 2014 } 2015 orig_node->tt_initialised = true; 2016 } 2017 2018 static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv, 2019 struct batadv_tt_query_packet *tt_response) 2020 { 2021 struct batadv_orig_node *orig_node; 2022 2023 orig_node = batadv_orig_hash_find(bat_priv, tt_response->src); 2024 if (!orig_node) 2025 goto out; 2026 2027 /* Purge the old table first.. */ 2028 batadv_tt_global_del_orig(bat_priv, orig_node, "Received full table"); 2029 2030 _batadv_tt_update_changes(bat_priv, orig_node, 2031 (struct batadv_tt_change *)(tt_response + 1), 2032 ntohs(tt_response->tt_data), 2033 tt_response->ttvn); 2034 2035 spin_lock_bh(&orig_node->tt_buff_lock); 2036 kfree(orig_node->tt_buff); 2037 orig_node->tt_buff_len = 0; 2038 orig_node->tt_buff = NULL; 2039 spin_unlock_bh(&orig_node->tt_buff_lock); 2040 2041 atomic_set(&orig_node->last_ttvn, tt_response->ttvn); 2042 2043 out: 2044 if (orig_node) 2045 batadv_orig_node_free_ref(orig_node); 2046 } 2047 2048 static void batadv_tt_update_changes(struct batadv_priv *bat_priv, 2049 struct batadv_orig_node *orig_node, 2050 uint16_t tt_num_changes, uint8_t ttvn, 2051 struct batadv_tt_change *tt_change) 2052 { 2053 _batadv_tt_update_changes(bat_priv, orig_node, tt_change, 2054 tt_num_changes, ttvn); 2055 2056 batadv_tt_save_orig_buffer(bat_priv, orig_node, 2057 (unsigned char *)tt_change, tt_num_changes); 2058 atomic_set(&orig_node->last_ttvn, ttvn); 2059 } 2060 2061 bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr) 2062 { 2063 struct batadv_tt_local_entry *tt_local_entry; 2064 bool ret = false; 2065 2066 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); 2067 if (!tt_local_entry) 2068 goto out; 2069 /* Check if the client has been logically deleted (but is kept for 2070 * consistency purpose) 2071 */ 2072 if ((tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) || 2073 (tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM)) 2074 goto out; 2075 ret = true; 2076 out: 2077 if (tt_local_entry) 2078 batadv_tt_local_entry_free_ref(tt_local_entry); 2079 return ret; 2080 } 2081 2082 void batadv_handle_tt_response(struct batadv_priv *bat_priv, 2083 struct batadv_tt_query_packet *tt_response) 2084 { 2085 struct batadv_tt_req_node *node, *safe; 2086 struct batadv_orig_node *orig_node = NULL; 2087 struct batadv_tt_change *tt_change; 2088 2089 batadv_dbg(BATADV_DBG_TT, bat_priv, 2090 "Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n", 2091 tt_response->src, tt_response->ttvn, 2092 ntohs(tt_response->tt_data), 2093 (tt_response->flags & BATADV_TT_FULL_TABLE ? 'F' : '.')); 2094 2095 /* we should have never asked a backbone gw */ 2096 if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_response->src)) 2097 goto out; 2098 2099 orig_node = batadv_orig_hash_find(bat_priv, tt_response->src); 2100 if (!orig_node) 2101 goto out; 2102 2103 if (tt_response->flags & BATADV_TT_FULL_TABLE) { 2104 batadv_tt_fill_gtable(bat_priv, tt_response); 2105 } else { 2106 tt_change = (struct batadv_tt_change *)(tt_response + 1); 2107 batadv_tt_update_changes(bat_priv, orig_node, 2108 ntohs(tt_response->tt_data), 2109 tt_response->ttvn, tt_change); 2110 } 2111 2112 /* Delete the tt_req_node from pending tt_requests list */ 2113 spin_lock_bh(&bat_priv->tt.req_list_lock); 2114 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { 2115 if (!batadv_compare_eth(node->addr, tt_response->src)) 2116 continue; 2117 list_del(&node->list); 2118 kfree(node); 2119 } 2120 spin_unlock_bh(&bat_priv->tt.req_list_lock); 2121 2122 /* Recalculate the CRC for this orig_node and store it */ 2123 orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node); 2124 out: 2125 if (orig_node) 2126 batadv_orig_node_free_ref(orig_node); 2127 } 2128 2129 int batadv_tt_init(struct batadv_priv *bat_priv) 2130 { 2131 int ret; 2132 2133 ret = batadv_tt_local_init(bat_priv); 2134 if (ret < 0) 2135 return ret; 2136 2137 ret = batadv_tt_global_init(bat_priv); 2138 if (ret < 0) 2139 return ret; 2140 2141 INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge); 2142 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work, 2143 msecs_to_jiffies(BATADV_TT_WORK_PERIOD)); 2144 2145 return 1; 2146 } 2147 2148 static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv) 2149 { 2150 struct batadv_tt_roam_node *node, *safe; 2151 2152 spin_lock_bh(&bat_priv->tt.roam_list_lock); 2153 2154 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { 2155 list_del(&node->list); 2156 kfree(node); 2157 } 2158 2159 spin_unlock_bh(&bat_priv->tt.roam_list_lock); 2160 } 2161 2162 static void batadv_tt_roam_purge(struct batadv_priv *bat_priv) 2163 { 2164 struct batadv_tt_roam_node *node, *safe; 2165 2166 spin_lock_bh(&bat_priv->tt.roam_list_lock); 2167 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { 2168 if (!batadv_has_timed_out(node->first_time, 2169 BATADV_ROAMING_MAX_TIME)) 2170 continue; 2171 2172 list_del(&node->list); 2173 kfree(node); 2174 } 2175 spin_unlock_bh(&bat_priv->tt.roam_list_lock); 2176 } 2177 2178 /* This function checks whether the client already reached the 2179 * maximum number of possible roaming phases. In this case the ROAMING_ADV 2180 * will not be sent. 2181 * 2182 * returns true if the ROAMING_ADV can be sent, false otherwise 2183 */ 2184 static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv, 2185 uint8_t *client) 2186 { 2187 struct batadv_tt_roam_node *tt_roam_node; 2188 bool ret = false; 2189 2190 spin_lock_bh(&bat_priv->tt.roam_list_lock); 2191 /* The new tt_req will be issued only if I'm not waiting for a 2192 * reply from the same orig_node yet 2193 */ 2194 list_for_each_entry(tt_roam_node, &bat_priv->tt.roam_list, list) { 2195 if (!batadv_compare_eth(tt_roam_node->addr, client)) 2196 continue; 2197 2198 if (batadv_has_timed_out(tt_roam_node->first_time, 2199 BATADV_ROAMING_MAX_TIME)) 2200 continue; 2201 2202 if (!batadv_atomic_dec_not_zero(&tt_roam_node->counter)) 2203 /* Sorry, you roamed too many times! */ 2204 goto unlock; 2205 ret = true; 2206 break; 2207 } 2208 2209 if (!ret) { 2210 tt_roam_node = kmalloc(sizeof(*tt_roam_node), GFP_ATOMIC); 2211 if (!tt_roam_node) 2212 goto unlock; 2213 2214 tt_roam_node->first_time = jiffies; 2215 atomic_set(&tt_roam_node->counter, 2216 BATADV_ROAMING_MAX_COUNT - 1); 2217 memcpy(tt_roam_node->addr, client, ETH_ALEN); 2218 2219 list_add(&tt_roam_node->list, &bat_priv->tt.roam_list); 2220 ret = true; 2221 } 2222 2223 unlock: 2224 spin_unlock_bh(&bat_priv->tt.roam_list_lock); 2225 return ret; 2226 } 2227 2228 static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, 2229 struct batadv_orig_node *orig_node) 2230 { 2231 struct sk_buff *skb = NULL; 2232 struct batadv_roam_adv_packet *roam_adv_packet; 2233 int ret = 1; 2234 struct batadv_hard_iface *primary_if; 2235 size_t len = sizeof(*roam_adv_packet); 2236 2237 /* before going on we have to check whether the client has 2238 * already roamed to us too many times 2239 */ 2240 if (!batadv_tt_check_roam_count(bat_priv, client)) 2241 goto out; 2242 2243 skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN); 2244 if (!skb) 2245 goto out; 2246 2247 skb->priority = TC_PRIO_CONTROL; 2248 skb_reserve(skb, ETH_HLEN); 2249 2250 roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len); 2251 2252 roam_adv_packet->header.packet_type = BATADV_ROAM_ADV; 2253 roam_adv_packet->header.version = BATADV_COMPAT_VERSION; 2254 roam_adv_packet->header.ttl = BATADV_TTL; 2255 roam_adv_packet->reserved = 0; 2256 primary_if = batadv_primary_if_get_selected(bat_priv); 2257 if (!primary_if) 2258 goto out; 2259 memcpy(roam_adv_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN); 2260 batadv_hardif_free_ref(primary_if); 2261 memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN); 2262 memcpy(roam_adv_packet->client, client, ETH_ALEN); 2263 2264 batadv_dbg(BATADV_DBG_TT, bat_priv, 2265 "Sending ROAMING_ADV to %pM (client %pM)\n", 2266 orig_node->orig, client); 2267 2268 batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX); 2269 2270 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP) 2271 ret = 0; 2272 2273 out: 2274 if (ret && skb) 2275 kfree_skb(skb); 2276 return; 2277 } 2278 2279 static void batadv_tt_purge(struct work_struct *work) 2280 { 2281 struct delayed_work *delayed_work; 2282 struct batadv_priv_tt *priv_tt; 2283 struct batadv_priv *bat_priv; 2284 2285 delayed_work = container_of(work, struct delayed_work, work); 2286 priv_tt = container_of(delayed_work, struct batadv_priv_tt, work); 2287 bat_priv = container_of(priv_tt, struct batadv_priv, tt); 2288 2289 batadv_tt_local_purge(bat_priv); 2290 batadv_tt_global_purge(bat_priv); 2291 batadv_tt_req_purge(bat_priv); 2292 batadv_tt_roam_purge(bat_priv); 2293 2294 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work, 2295 msecs_to_jiffies(BATADV_TT_WORK_PERIOD)); 2296 } 2297 2298 void batadv_tt_free(struct batadv_priv *bat_priv) 2299 { 2300 cancel_delayed_work_sync(&bat_priv->tt.work); 2301 2302 batadv_tt_local_table_free(bat_priv); 2303 batadv_tt_global_table_free(bat_priv); 2304 batadv_tt_req_list_free(bat_priv); 2305 batadv_tt_changes_list_free(bat_priv); 2306 batadv_tt_roam_list_free(bat_priv); 2307 2308 kfree(bat_priv->tt.last_changeset); 2309 } 2310 2311 /* This function will enable or disable the specified flags for all the entries 2312 * in the given hash table and returns the number of modified entries 2313 */ 2314 static uint16_t batadv_tt_set_flags(struct batadv_hashtable *hash, 2315 uint16_t flags, bool enable) 2316 { 2317 uint32_t i; 2318 uint16_t changed_num = 0; 2319 struct hlist_head *head; 2320 struct batadv_tt_common_entry *tt_common_entry; 2321 2322 if (!hash) 2323 goto out; 2324 2325 for (i = 0; i < hash->size; i++) { 2326 head = &hash->table[i]; 2327 2328 rcu_read_lock(); 2329 hlist_for_each_entry_rcu(tt_common_entry, 2330 head, hash_entry) { 2331 if (enable) { 2332 if ((tt_common_entry->flags & flags) == flags) 2333 continue; 2334 tt_common_entry->flags |= flags; 2335 } else { 2336 if (!(tt_common_entry->flags & flags)) 2337 continue; 2338 tt_common_entry->flags &= ~flags; 2339 } 2340 changed_num++; 2341 } 2342 rcu_read_unlock(); 2343 } 2344 out: 2345 return changed_num; 2346 } 2347 2348 /* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */ 2349 static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) 2350 { 2351 struct batadv_hashtable *hash = bat_priv->tt.local_hash; 2352 struct batadv_tt_common_entry *tt_common; 2353 struct batadv_tt_local_entry *tt_local; 2354 struct hlist_node *node_tmp; 2355 struct hlist_head *head; 2356 spinlock_t *list_lock; /* protects write access to the hash lists */ 2357 uint32_t i; 2358 2359 if (!hash) 2360 return; 2361 2362 for (i = 0; i < hash->size; i++) { 2363 head = &hash->table[i]; 2364 list_lock = &hash->list_locks[i]; 2365 2366 spin_lock_bh(list_lock); 2367 hlist_for_each_entry_safe(tt_common, node_tmp, head, 2368 hash_entry) { 2369 if (!(tt_common->flags & BATADV_TT_CLIENT_PENDING)) 2370 continue; 2371 2372 batadv_dbg(BATADV_DBG_TT, bat_priv, 2373 "Deleting local tt entry (%pM): pending\n", 2374 tt_common->addr); 2375 2376 atomic_dec(&bat_priv->tt.local_entry_num); 2377 hlist_del_rcu(&tt_common->hash_entry); 2378 tt_local = container_of(tt_common, 2379 struct batadv_tt_local_entry, 2380 common); 2381 batadv_tt_local_entry_free_ref(tt_local); 2382 } 2383 spin_unlock_bh(list_lock); 2384 } 2385 } 2386 2387 static int batadv_tt_commit_changes(struct batadv_priv *bat_priv, 2388 unsigned char **packet_buff, 2389 int *packet_buff_len, int packet_min_len) 2390 { 2391 uint16_t changed_num = 0; 2392 2393 if (atomic_read(&bat_priv->tt.local_changes) < 1) 2394 return -ENOENT; 2395 2396 changed_num = batadv_tt_set_flags(bat_priv->tt.local_hash, 2397 BATADV_TT_CLIENT_NEW, false); 2398 2399 /* all reset entries have to be counted as local entries */ 2400 atomic_add(changed_num, &bat_priv->tt.local_entry_num); 2401 batadv_tt_local_purge_pending_clients(bat_priv); 2402 bat_priv->tt.local_crc = batadv_tt_local_crc(bat_priv); 2403 2404 /* Increment the TTVN only once per OGM interval */ 2405 atomic_inc(&bat_priv->tt.vn); 2406 batadv_dbg(BATADV_DBG_TT, bat_priv, 2407 "Local changes committed, updating to ttvn %u\n", 2408 (uint8_t)atomic_read(&bat_priv->tt.vn)); 2409 2410 /* reset the sending counter */ 2411 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); 2412 2413 return batadv_tt_changes_fill_buff(bat_priv, packet_buff, 2414 packet_buff_len, packet_min_len); 2415 } 2416 2417 /* when calling this function (hard_iface == primary_if) has to be true */ 2418 int batadv_tt_append_diff(struct batadv_priv *bat_priv, 2419 unsigned char **packet_buff, int *packet_buff_len, 2420 int packet_min_len) 2421 { 2422 int tt_num_changes; 2423 2424 /* if at least one change happened */ 2425 tt_num_changes = batadv_tt_commit_changes(bat_priv, packet_buff, 2426 packet_buff_len, 2427 packet_min_len); 2428 2429 /* if the changes have been sent often enough */ 2430 if ((tt_num_changes < 0) && 2431 (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))) { 2432 batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len, 2433 packet_min_len, packet_min_len); 2434 tt_num_changes = 0; 2435 } 2436 2437 return tt_num_changes; 2438 } 2439 2440 bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src, 2441 uint8_t *dst) 2442 { 2443 struct batadv_tt_local_entry *tt_local_entry = NULL; 2444 struct batadv_tt_global_entry *tt_global_entry = NULL; 2445 bool ret = false; 2446 2447 if (!atomic_read(&bat_priv->ap_isolation)) 2448 goto out; 2449 2450 tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst); 2451 if (!tt_local_entry) 2452 goto out; 2453 2454 tt_global_entry = batadv_tt_global_hash_find(bat_priv, src); 2455 if (!tt_global_entry) 2456 goto out; 2457 2458 if (!_batadv_is_ap_isolated(tt_local_entry, tt_global_entry)) 2459 goto out; 2460 2461 ret = true; 2462 2463 out: 2464 if (tt_global_entry) 2465 batadv_tt_global_entry_free_ref(tt_global_entry); 2466 if (tt_local_entry) 2467 batadv_tt_local_entry_free_ref(tt_local_entry); 2468 return ret; 2469 } 2470 2471 void batadv_tt_update_orig(struct batadv_priv *bat_priv, 2472 struct batadv_orig_node *orig_node, 2473 const unsigned char *tt_buff, uint8_t tt_num_changes, 2474 uint8_t ttvn, uint16_t tt_crc) 2475 { 2476 uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); 2477 bool full_table = true; 2478 struct batadv_tt_change *tt_change; 2479 2480 /* don't care about a backbone gateways updates. */ 2481 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig)) 2482 return; 2483 2484 /* orig table not initialised AND first diff is in the OGM OR the ttvn 2485 * increased by one -> we can apply the attached changes 2486 */ 2487 if ((!orig_node->tt_initialised && ttvn == 1) || 2488 ttvn - orig_ttvn == 1) { 2489 /* the OGM could not contain the changes due to their size or 2490 * because they have already been sent BATADV_TT_OGM_APPEND_MAX 2491 * times. 2492 * In this case send a tt request 2493 */ 2494 if (!tt_num_changes) { 2495 full_table = false; 2496 goto request_table; 2497 } 2498 2499 tt_change = (struct batadv_tt_change *)tt_buff; 2500 batadv_tt_update_changes(bat_priv, orig_node, tt_num_changes, 2501 ttvn, tt_change); 2502 2503 /* Even if we received the precomputed crc with the OGM, we 2504 * prefer to recompute it to spot any possible inconsistency 2505 * in the global table 2506 */ 2507 orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node); 2508 2509 /* The ttvn alone is not enough to guarantee consistency 2510 * because a single value could represent different states 2511 * (due to the wrap around). Thus a node has to check whether 2512 * the resulting table (after applying the changes) is still 2513 * consistent or not. E.g. a node could disconnect while its 2514 * ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case 2515 * checking the CRC value is mandatory to detect the 2516 * inconsistency 2517 */ 2518 if (orig_node->tt_crc != tt_crc) 2519 goto request_table; 2520 } else { 2521 /* if we missed more than one change or our tables are not 2522 * in sync anymore -> request fresh tt data 2523 */ 2524 if (!orig_node->tt_initialised || ttvn != orig_ttvn || 2525 orig_node->tt_crc != tt_crc) { 2526 request_table: 2527 batadv_dbg(BATADV_DBG_TT, bat_priv, 2528 "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u crc: %#.4x last_crc: %#.4x num_changes: %u)\n", 2529 orig_node->orig, ttvn, orig_ttvn, tt_crc, 2530 orig_node->tt_crc, tt_num_changes); 2531 batadv_send_tt_request(bat_priv, orig_node, ttvn, 2532 tt_crc, full_table); 2533 return; 2534 } 2535 } 2536 } 2537 2538 /* returns true whether we know that the client has moved from its old 2539 * originator to another one. This entry is kept is still kept for consistency 2540 * purposes 2541 */ 2542 bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, 2543 uint8_t *addr) 2544 { 2545 struct batadv_tt_global_entry *tt_global_entry; 2546 bool ret = false; 2547 2548 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr); 2549 if (!tt_global_entry) 2550 goto out; 2551 2552 ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM; 2553 batadv_tt_global_entry_free_ref(tt_global_entry); 2554 out: 2555 return ret; 2556 } 2557 2558 /** 2559 * batadv_tt_local_client_is_roaming - tells whether the client is roaming 2560 * @bat_priv: the bat priv with all the soft interface information 2561 * @addr: the MAC address of the local client to query 2562 * 2563 * Returns true if the local client is known to be roaming (it is not served by 2564 * this node anymore) or not. If yes, the client is still present in the table 2565 * to keep the latter consistent with the node TTVN 2566 */ 2567 bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv, 2568 uint8_t *addr) 2569 { 2570 struct batadv_tt_local_entry *tt_local_entry; 2571 bool ret = false; 2572 2573 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); 2574 if (!tt_local_entry) 2575 goto out; 2576 2577 ret = tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM; 2578 batadv_tt_local_entry_free_ref(tt_local_entry); 2579 out: 2580 return ret; 2581 } 2582 2583 bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, 2584 struct batadv_orig_node *orig_node, 2585 const unsigned char *addr) 2586 { 2587 bool ret = false; 2588 2589 /* if the originator is a backbone node (meaning it belongs to the same 2590 * LAN of this node) the temporary client must not be added because to 2591 * reach such destination the node must use the LAN instead of the mesh 2592 */ 2593 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig)) 2594 goto out; 2595 2596 if (!batadv_tt_global_add(bat_priv, orig_node, addr, 2597 BATADV_TT_CLIENT_TEMP, 2598 atomic_read(&orig_node->last_ttvn))) 2599 goto out; 2600 2601 batadv_dbg(BATADV_DBG_TT, bat_priv, 2602 "Added temporary global client (addr: %pM orig: %pM)\n", 2603 addr, orig_node->orig); 2604 ret = true; 2605 out: 2606 return ret; 2607 } 2608