1 /* Copyright (C) 2007-2015 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, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "translation-table.h" 19 #include "main.h" 20 21 #include <linux/atomic.h> 22 #include <linux/bug.h> 23 #include <linux/byteorder/generic.h> 24 #include <linux/compiler.h> 25 #include <linux/crc32c.h> 26 #include <linux/errno.h> 27 #include <linux/etherdevice.h> 28 #include <linux/fs.h> 29 #include <linux/if_ether.h> 30 #include <linux/jhash.h> 31 #include <linux/jiffies.h> 32 #include <linux/kernel.h> 33 #include <linux/list.h> 34 #include <linux/lockdep.h> 35 #include <linux/netdevice.h> 36 #include <linux/rculist.h> 37 #include <linux/rcupdate.h> 38 #include <linux/seq_file.h> 39 #include <linux/slab.h> 40 #include <linux/spinlock.h> 41 #include <linux/stddef.h> 42 #include <linux/string.h> 43 #include <linux/workqueue.h> 44 #include <net/net_namespace.h> 45 46 #include "bridge_loop_avoidance.h" 47 #include "hard-interface.h" 48 #include "hash.h" 49 #include "multicast.h" 50 #include "originator.h" 51 #include "packet.h" 52 #include "soft-interface.h" 53 54 /* hash class keys */ 55 static struct lock_class_key batadv_tt_local_hash_lock_class_key; 56 static struct lock_class_key batadv_tt_global_hash_lock_class_key; 57 58 static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, 59 unsigned short vid, 60 struct batadv_orig_node *orig_node); 61 static void batadv_tt_purge(struct work_struct *work); 62 static void 63 batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry); 64 static void batadv_tt_global_del(struct batadv_priv *bat_priv, 65 struct batadv_orig_node *orig_node, 66 const unsigned char *addr, 67 unsigned short vid, const char *message, 68 bool roaming); 69 70 /* returns 1 if they are the same mac addr */ 71 static int batadv_compare_tt(const struct hlist_node *node, const void *data2) 72 { 73 const void *data1 = container_of(node, struct batadv_tt_common_entry, 74 hash_entry); 75 76 return batadv_compare_eth(data1, data2); 77 } 78 79 /** 80 * batadv_choose_tt - return the index of the tt entry in the hash table 81 * @data: pointer to the tt_common_entry object to map 82 * @size: the size of the hash table 83 * 84 * Returns the hash index where the object represented by 'data' should be 85 * stored at. 86 */ 87 static inline uint32_t batadv_choose_tt(const void *data, uint32_t size) 88 { 89 struct batadv_tt_common_entry *tt; 90 uint32_t hash = 0; 91 92 tt = (struct batadv_tt_common_entry *)data; 93 hash = jhash(&tt->addr, ETH_ALEN, hash); 94 hash = jhash(&tt->vid, sizeof(tt->vid), hash); 95 96 return hash % size; 97 } 98 99 /** 100 * batadv_tt_hash_find - look for a client in the given hash table 101 * @hash: the hash table to search 102 * @addr: the mac address of the client to look for 103 * @vid: VLAN identifier 104 * 105 * Returns a pointer to the tt_common struct belonging to the searched client if 106 * found, NULL otherwise. 107 */ 108 static struct batadv_tt_common_entry * 109 batadv_tt_hash_find(struct batadv_hashtable *hash, const uint8_t *addr, 110 unsigned short vid) 111 { 112 struct hlist_head *head; 113 struct batadv_tt_common_entry to_search, *tt, *tt_tmp = NULL; 114 uint32_t index; 115 116 if (!hash) 117 return NULL; 118 119 ether_addr_copy(to_search.addr, addr); 120 to_search.vid = vid; 121 122 index = batadv_choose_tt(&to_search, hash->size); 123 head = &hash->table[index]; 124 125 rcu_read_lock(); 126 hlist_for_each_entry_rcu(tt, head, hash_entry) { 127 if (!batadv_compare_eth(tt, addr)) 128 continue; 129 130 if (tt->vid != vid) 131 continue; 132 133 if (!atomic_inc_not_zero(&tt->refcount)) 134 continue; 135 136 tt_tmp = tt; 137 break; 138 } 139 rcu_read_unlock(); 140 141 return tt_tmp; 142 } 143 144 /** 145 * batadv_tt_local_hash_find - search the local table for a given client 146 * @bat_priv: the bat priv with all the soft interface information 147 * @addr: the mac address of the client to look for 148 * @vid: VLAN identifier 149 * 150 * Returns a pointer to the corresponding tt_local_entry struct if the client is 151 * found, NULL otherwise. 152 */ 153 static struct batadv_tt_local_entry * 154 batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const uint8_t *addr, 155 unsigned short vid) 156 { 157 struct batadv_tt_common_entry *tt_common_entry; 158 struct batadv_tt_local_entry *tt_local_entry = NULL; 159 160 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, addr, 161 vid); 162 if (tt_common_entry) 163 tt_local_entry = container_of(tt_common_entry, 164 struct batadv_tt_local_entry, 165 common); 166 return tt_local_entry; 167 } 168 169 /** 170 * batadv_tt_global_hash_find - search the global table for a given client 171 * @bat_priv: the bat priv with all the soft interface information 172 * @addr: the mac address of the client to look for 173 * @vid: VLAN identifier 174 * 175 * Returns a pointer to the corresponding tt_global_entry struct if the client 176 * is found, NULL otherwise. 177 */ 178 static struct batadv_tt_global_entry * 179 batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const uint8_t *addr, 180 unsigned short vid) 181 { 182 struct batadv_tt_common_entry *tt_common_entry; 183 struct batadv_tt_global_entry *tt_global_entry = NULL; 184 185 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, addr, 186 vid); 187 if (tt_common_entry) 188 tt_global_entry = container_of(tt_common_entry, 189 struct batadv_tt_global_entry, 190 common); 191 return tt_global_entry; 192 } 193 194 static void 195 batadv_tt_local_entry_free_ref(struct batadv_tt_local_entry *tt_local_entry) 196 { 197 if (atomic_dec_and_test(&tt_local_entry->common.refcount)) 198 kfree_rcu(tt_local_entry, common.rcu); 199 } 200 201 /** 202 * batadv_tt_global_entry_free_ref - decrement the refcounter for a 203 * tt_global_entry and possibly free it 204 * @tt_global_entry: the object to free 205 */ 206 static void 207 batadv_tt_global_entry_free_ref(struct batadv_tt_global_entry *tt_global_entry) 208 { 209 if (atomic_dec_and_test(&tt_global_entry->common.refcount)) { 210 batadv_tt_global_del_orig_list(tt_global_entry); 211 kfree_rcu(tt_global_entry, common.rcu); 212 } 213 } 214 215 /** 216 * batadv_tt_global_hash_count - count the number of orig entries 217 * @hash: hash table containing the tt entries 218 * @addr: the mac address of the client to count entries for 219 * @vid: VLAN identifier 220 * 221 * Return the number of originators advertising the given address/data 222 * (excluding ourself). 223 */ 224 int batadv_tt_global_hash_count(struct batadv_priv *bat_priv, 225 const uint8_t *addr, unsigned short vid) 226 { 227 struct batadv_tt_global_entry *tt_global_entry; 228 int count; 229 230 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid); 231 if (!tt_global_entry) 232 return 0; 233 234 count = atomic_read(&tt_global_entry->orig_list_count); 235 batadv_tt_global_entry_free_ref(tt_global_entry); 236 237 return count; 238 } 239 240 static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu) 241 { 242 struct batadv_tt_orig_list_entry *orig_entry; 243 244 orig_entry = container_of(rcu, struct batadv_tt_orig_list_entry, rcu); 245 246 /* We are in an rcu callback here, therefore we cannot use 247 * batadv_orig_node_free_ref() and its call_rcu(): 248 * An rcu_barrier() wouldn't wait for that to finish 249 */ 250 batadv_orig_node_free_ref_now(orig_entry->orig_node); 251 kfree(orig_entry); 252 } 253 254 /** 255 * batadv_tt_local_size_mod - change the size by v of the local table identified 256 * by vid 257 * @bat_priv: the bat priv with all the soft interface information 258 * @vid: the VLAN identifier of the sub-table to change 259 * @v: the amount to sum to the local table size 260 */ 261 static void batadv_tt_local_size_mod(struct batadv_priv *bat_priv, 262 unsigned short vid, int v) 263 { 264 struct batadv_softif_vlan *vlan; 265 266 vlan = batadv_softif_vlan_get(bat_priv, vid); 267 if (!vlan) 268 return; 269 270 atomic_add(v, &vlan->tt.num_entries); 271 272 batadv_softif_vlan_free_ref(vlan); 273 } 274 275 /** 276 * batadv_tt_local_size_inc - increase by one the local table size for the given 277 * vid 278 * @bat_priv: the bat priv with all the soft interface information 279 * @vid: the VLAN identifier 280 */ 281 static void batadv_tt_local_size_inc(struct batadv_priv *bat_priv, 282 unsigned short vid) 283 { 284 batadv_tt_local_size_mod(bat_priv, vid, 1); 285 } 286 287 /** 288 * batadv_tt_local_size_dec - decrease by one the local table size for the given 289 * vid 290 * @bat_priv: the bat priv with all the soft interface information 291 * @vid: the VLAN identifier 292 */ 293 static void batadv_tt_local_size_dec(struct batadv_priv *bat_priv, 294 unsigned short vid) 295 { 296 batadv_tt_local_size_mod(bat_priv, vid, -1); 297 } 298 299 /** 300 * batadv_tt_global_size_mod - change the size by v of the local table 301 * identified by vid 302 * @bat_priv: the bat priv with all the soft interface information 303 * @vid: the VLAN identifier 304 * @v: the amount to sum to the global table size 305 */ 306 static void batadv_tt_global_size_mod(struct batadv_orig_node *orig_node, 307 unsigned short vid, int v) 308 { 309 struct batadv_orig_node_vlan *vlan; 310 311 vlan = batadv_orig_node_vlan_new(orig_node, vid); 312 if (!vlan) 313 return; 314 315 if (atomic_add_return(v, &vlan->tt.num_entries) == 0) { 316 spin_lock_bh(&orig_node->vlan_list_lock); 317 list_del_rcu(&vlan->list); 318 spin_unlock_bh(&orig_node->vlan_list_lock); 319 batadv_orig_node_vlan_free_ref(vlan); 320 } 321 322 batadv_orig_node_vlan_free_ref(vlan); 323 } 324 325 /** 326 * batadv_tt_global_size_inc - increase by one the global table size for the 327 * given vid 328 * @orig_node: the originator which global table size has to be decreased 329 * @vid: the vlan identifier 330 */ 331 static void batadv_tt_global_size_inc(struct batadv_orig_node *orig_node, 332 unsigned short vid) 333 { 334 batadv_tt_global_size_mod(orig_node, vid, 1); 335 } 336 337 /** 338 * batadv_tt_global_size_dec - decrease by one the global table size for the 339 * given vid 340 * @orig_node: the originator which global table size has to be decreased 341 * @vid: the vlan identifier 342 */ 343 static void batadv_tt_global_size_dec(struct batadv_orig_node *orig_node, 344 unsigned short vid) 345 { 346 batadv_tt_global_size_mod(orig_node, vid, -1); 347 } 348 349 static void 350 batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry) 351 { 352 if (!atomic_dec_and_test(&orig_entry->refcount)) 353 return; 354 355 call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu); 356 } 357 358 /** 359 * batadv_tt_local_event - store a local TT event (ADD/DEL) 360 * @bat_priv: the bat priv with all the soft interface information 361 * @tt_local_entry: the TT entry involved in the event 362 * @event_flags: flags to store in the event structure 363 */ 364 static void batadv_tt_local_event(struct batadv_priv *bat_priv, 365 struct batadv_tt_local_entry *tt_local_entry, 366 uint8_t event_flags) 367 { 368 struct batadv_tt_change_node *tt_change_node, *entry, *safe; 369 struct batadv_tt_common_entry *common = &tt_local_entry->common; 370 uint8_t flags = common->flags | event_flags; 371 bool event_removed = false; 372 bool del_op_requested, del_op_entry; 373 374 tt_change_node = kmalloc(sizeof(*tt_change_node), GFP_ATOMIC); 375 if (!tt_change_node) 376 return; 377 378 tt_change_node->change.flags = flags; 379 memset(tt_change_node->change.reserved, 0, 380 sizeof(tt_change_node->change.reserved)); 381 ether_addr_copy(tt_change_node->change.addr, common->addr); 382 tt_change_node->change.vid = htons(common->vid); 383 384 del_op_requested = flags & BATADV_TT_CLIENT_DEL; 385 386 /* check for ADD+DEL or DEL+ADD events */ 387 spin_lock_bh(&bat_priv->tt.changes_list_lock); 388 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, 389 list) { 390 if (!batadv_compare_eth(entry->change.addr, common->addr)) 391 continue; 392 393 /* DEL+ADD in the same orig interval have no effect and can be 394 * removed to avoid silly behaviour on the receiver side. The 395 * other way around (ADD+DEL) can happen in case of roaming of 396 * a client still in the NEW state. Roaming of NEW clients is 397 * now possible due to automatically recognition of "temporary" 398 * clients 399 */ 400 del_op_entry = entry->change.flags & BATADV_TT_CLIENT_DEL; 401 if (!del_op_requested && del_op_entry) 402 goto del; 403 if (del_op_requested && !del_op_entry) 404 goto del; 405 406 /* this is a second add in the same originator interval. It 407 * means that flags have been changed: update them! 408 */ 409 if (!del_op_requested && !del_op_entry) 410 entry->change.flags = flags; 411 412 continue; 413 del: 414 list_del(&entry->list); 415 kfree(entry); 416 kfree(tt_change_node); 417 event_removed = true; 418 goto unlock; 419 } 420 421 /* track the change in the OGMinterval list */ 422 list_add_tail(&tt_change_node->list, &bat_priv->tt.changes_list); 423 424 unlock: 425 spin_unlock_bh(&bat_priv->tt.changes_list_lock); 426 427 if (event_removed) 428 atomic_dec(&bat_priv->tt.local_changes); 429 else 430 atomic_inc(&bat_priv->tt.local_changes); 431 } 432 433 /** 434 * batadv_tt_len - compute length in bytes of given number of tt changes 435 * @changes_num: number of tt changes 436 * 437 * Returns computed length in bytes. 438 */ 439 static int batadv_tt_len(int changes_num) 440 { 441 return changes_num * sizeof(struct batadv_tvlv_tt_change); 442 } 443 444 /** 445 * batadv_tt_entries - compute the number of entries fitting in tt_len bytes 446 * @tt_len: available space 447 * 448 * Returns the number of entries. 449 */ 450 static uint16_t batadv_tt_entries(uint16_t tt_len) 451 { 452 return tt_len / batadv_tt_len(1); 453 } 454 455 /** 456 * batadv_tt_local_table_transmit_size - calculates the local translation table 457 * size when transmitted over the air 458 * @bat_priv: the bat priv with all the soft interface information 459 * 460 * Returns local translation table size in bytes. 461 */ 462 static int batadv_tt_local_table_transmit_size(struct batadv_priv *bat_priv) 463 { 464 uint16_t num_vlan = 0, tt_local_entries = 0; 465 struct batadv_softif_vlan *vlan; 466 int hdr_size; 467 468 rcu_read_lock(); 469 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { 470 num_vlan++; 471 tt_local_entries += atomic_read(&vlan->tt.num_entries); 472 } 473 rcu_read_unlock(); 474 475 /* header size of tvlv encapsulated tt response payload */ 476 hdr_size = sizeof(struct batadv_unicast_tvlv_packet); 477 hdr_size += sizeof(struct batadv_tvlv_hdr); 478 hdr_size += sizeof(struct batadv_tvlv_tt_data); 479 hdr_size += num_vlan * sizeof(struct batadv_tvlv_tt_vlan_data); 480 481 return hdr_size + batadv_tt_len(tt_local_entries); 482 } 483 484 static int batadv_tt_local_init(struct batadv_priv *bat_priv) 485 { 486 if (bat_priv->tt.local_hash) 487 return 0; 488 489 bat_priv->tt.local_hash = batadv_hash_new(1024); 490 491 if (!bat_priv->tt.local_hash) 492 return -ENOMEM; 493 494 batadv_hash_set_lock_class(bat_priv->tt.local_hash, 495 &batadv_tt_local_hash_lock_class_key); 496 497 return 0; 498 } 499 500 static void batadv_tt_global_free(struct batadv_priv *bat_priv, 501 struct batadv_tt_global_entry *tt_global, 502 const char *message) 503 { 504 batadv_dbg(BATADV_DBG_TT, bat_priv, 505 "Deleting global tt entry %pM (vid: %d): %s\n", 506 tt_global->common.addr, 507 BATADV_PRINT_VID(tt_global->common.vid), message); 508 509 batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt, 510 batadv_choose_tt, &tt_global->common); 511 batadv_tt_global_entry_free_ref(tt_global); 512 } 513 514 /** 515 * batadv_tt_local_add - add a new client to the local table or update an 516 * existing client 517 * @soft_iface: netdev struct of the mesh interface 518 * @addr: the mac address of the client to add 519 * @vid: VLAN identifier 520 * @ifindex: index of the interface where the client is connected to (useful to 521 * identify wireless clients) 522 * @mark: the value contained in the skb->mark field of the received packet (if 523 * any) 524 * 525 * Returns true if the client was successfully added, false otherwise. 526 */ 527 bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, 528 unsigned short vid, int ifindex, uint32_t mark) 529 { 530 struct batadv_priv *bat_priv = netdev_priv(soft_iface); 531 struct batadv_tt_local_entry *tt_local; 532 struct batadv_tt_global_entry *tt_global = NULL; 533 struct batadv_softif_vlan *vlan; 534 struct net_device *in_dev = NULL; 535 struct hlist_head *head; 536 struct batadv_tt_orig_list_entry *orig_entry; 537 int hash_added, table_size, packet_size_max; 538 bool ret = false, roamed_back = false; 539 uint8_t remote_flags; 540 uint32_t match_mark; 541 542 if (ifindex != BATADV_NULL_IFINDEX) 543 in_dev = dev_get_by_index(&init_net, ifindex); 544 545 tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid); 546 547 if (!is_multicast_ether_addr(addr)) 548 tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid); 549 550 if (tt_local) { 551 tt_local->last_seen = jiffies; 552 if (tt_local->common.flags & BATADV_TT_CLIENT_PENDING) { 553 batadv_dbg(BATADV_DBG_TT, bat_priv, 554 "Re-adding pending client %pM (vid: %d)\n", 555 addr, BATADV_PRINT_VID(vid)); 556 /* whatever the reason why the PENDING flag was set, 557 * this is a client which was enqueued to be removed in 558 * this orig_interval. Since it popped up again, the 559 * flag can be reset like it was never enqueued 560 */ 561 tt_local->common.flags &= ~BATADV_TT_CLIENT_PENDING; 562 goto add_event; 563 } 564 565 if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) { 566 batadv_dbg(BATADV_DBG_TT, bat_priv, 567 "Roaming client %pM (vid: %d) came back to its original location\n", 568 addr, BATADV_PRINT_VID(vid)); 569 /* the ROAM flag is set because this client roamed away 570 * and the node got a roaming_advertisement message. Now 571 * that the client popped up again at its original 572 * location such flag can be unset 573 */ 574 tt_local->common.flags &= ~BATADV_TT_CLIENT_ROAM; 575 roamed_back = true; 576 } 577 goto check_roaming; 578 } 579 580 /* Ignore the client if we cannot send it in a full table response. */ 581 table_size = batadv_tt_local_table_transmit_size(bat_priv); 582 table_size += batadv_tt_len(1); 583 packet_size_max = atomic_read(&bat_priv->packet_size_max); 584 if (table_size > packet_size_max) { 585 net_ratelimited_function(batadv_info, soft_iface, 586 "Local translation table size (%i) exceeds maximum packet size (%i); Ignoring new local tt entry: %pM\n", 587 table_size, packet_size_max, addr); 588 goto out; 589 } 590 591 tt_local = kmalloc(sizeof(*tt_local), GFP_ATOMIC); 592 if (!tt_local) 593 goto out; 594 595 /* increase the refcounter of the related vlan */ 596 vlan = batadv_softif_vlan_get(bat_priv, vid); 597 598 batadv_dbg(BATADV_DBG_TT, bat_priv, 599 "Creating new local tt entry: %pM (vid: %d, ttvn: %d)\n", 600 addr, BATADV_PRINT_VID(vid), 601 (uint8_t)atomic_read(&bat_priv->tt.vn)); 602 603 ether_addr_copy(tt_local->common.addr, addr); 604 /* The local entry has to be marked as NEW to avoid to send it in 605 * a full table response going out before the next ttvn increment 606 * (consistency check) 607 */ 608 tt_local->common.flags = BATADV_TT_CLIENT_NEW; 609 tt_local->common.vid = vid; 610 if (batadv_is_wifi_netdev(in_dev)) 611 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI; 612 atomic_set(&tt_local->common.refcount, 2); 613 tt_local->last_seen = jiffies; 614 tt_local->common.added_at = tt_local->last_seen; 615 616 /* the batman interface mac and multicast addresses should never be 617 * purged 618 */ 619 if (batadv_compare_eth(addr, soft_iface->dev_addr) || 620 is_multicast_ether_addr(addr)) 621 tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE; 622 623 hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt, 624 batadv_choose_tt, &tt_local->common, 625 &tt_local->common.hash_entry); 626 627 if (unlikely(hash_added != 0)) { 628 /* remove the reference for the hash */ 629 batadv_tt_local_entry_free_ref(tt_local); 630 batadv_softif_vlan_free_ref(vlan); 631 goto out; 632 } 633 634 add_event: 635 batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS); 636 637 check_roaming: 638 /* Check whether it is a roaming, but don't do anything if the roaming 639 * process has already been handled 640 */ 641 if (tt_global && !(tt_global->common.flags & BATADV_TT_CLIENT_ROAM)) { 642 /* These node are probably going to update their tt table */ 643 head = &tt_global->orig_list; 644 rcu_read_lock(); 645 hlist_for_each_entry_rcu(orig_entry, head, list) { 646 batadv_send_roam_adv(bat_priv, tt_global->common.addr, 647 tt_global->common.vid, 648 orig_entry->orig_node); 649 } 650 rcu_read_unlock(); 651 if (roamed_back) { 652 batadv_tt_global_free(bat_priv, tt_global, 653 "Roaming canceled"); 654 tt_global = NULL; 655 } else { 656 /* The global entry has to be marked as ROAMING and 657 * has to be kept for consistency purpose 658 */ 659 tt_global->common.flags |= BATADV_TT_CLIENT_ROAM; 660 tt_global->roam_at = jiffies; 661 } 662 } 663 664 /* store the current remote flags before altering them. This helps 665 * understanding is flags are changing or not 666 */ 667 remote_flags = tt_local->common.flags & BATADV_TT_REMOTE_MASK; 668 669 if (batadv_is_wifi_netdev(in_dev)) 670 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI; 671 else 672 tt_local->common.flags &= ~BATADV_TT_CLIENT_WIFI; 673 674 /* check the mark in the skb: if it's equal to the configured 675 * isolation_mark, it means the packet is coming from an isolated 676 * non-mesh client 677 */ 678 match_mark = (mark & bat_priv->isolation_mark_mask); 679 if (bat_priv->isolation_mark_mask && 680 match_mark == bat_priv->isolation_mark) 681 tt_local->common.flags |= BATADV_TT_CLIENT_ISOLA; 682 else 683 tt_local->common.flags &= ~BATADV_TT_CLIENT_ISOLA; 684 685 /* if any "dynamic" flag has been modified, resend an ADD event for this 686 * entry so that all the nodes can get the new flags 687 */ 688 if (remote_flags ^ (tt_local->common.flags & BATADV_TT_REMOTE_MASK)) 689 batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS); 690 691 ret = true; 692 out: 693 if (in_dev) 694 dev_put(in_dev); 695 if (tt_local) 696 batadv_tt_local_entry_free_ref(tt_local); 697 if (tt_global) 698 batadv_tt_global_entry_free_ref(tt_global); 699 return ret; 700 } 701 702 /** 703 * batadv_tt_prepare_tvlv_global_data - prepare the TVLV TT header to send 704 * within a TT Response directed to another node 705 * @orig_node: originator for which the TT data has to be prepared 706 * @tt_data: uninitialised pointer to the address of the TVLV buffer 707 * @tt_change: uninitialised pointer to the address of the area where the TT 708 * changed can be stored 709 * @tt_len: pointer to the length to reserve to the tt_change. if -1 this 710 * function reserves the amount of space needed to send the entire global TT 711 * table. In case of success the value is updated with the real amount of 712 * reserved bytes 713 714 * Allocate the needed amount of memory for the entire TT TVLV and write its 715 * header made up by one tvlv_tt_data object and a series of tvlv_tt_vlan_data 716 * objects, one per active VLAN served by the originator node. 717 * 718 * Return the size of the allocated buffer or 0 in case of failure. 719 */ 720 static uint16_t 721 batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node, 722 struct batadv_tvlv_tt_data **tt_data, 723 struct batadv_tvlv_tt_change **tt_change, 724 int32_t *tt_len) 725 { 726 uint16_t num_vlan = 0, num_entries = 0, change_offset, tvlv_len; 727 struct batadv_tvlv_tt_vlan_data *tt_vlan; 728 struct batadv_orig_node_vlan *vlan; 729 uint8_t *tt_change_ptr; 730 731 rcu_read_lock(); 732 list_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) { 733 num_vlan++; 734 num_entries += atomic_read(&vlan->tt.num_entries); 735 } 736 737 change_offset = sizeof(**tt_data); 738 change_offset += num_vlan * sizeof(*tt_vlan); 739 740 /* if tt_len is negative, allocate the space needed by the full table */ 741 if (*tt_len < 0) 742 *tt_len = batadv_tt_len(num_entries); 743 744 tvlv_len = *tt_len; 745 tvlv_len += change_offset; 746 747 *tt_data = kmalloc(tvlv_len, GFP_ATOMIC); 748 if (!*tt_data) { 749 *tt_len = 0; 750 goto out; 751 } 752 753 (*tt_data)->flags = BATADV_NO_FLAGS; 754 (*tt_data)->ttvn = atomic_read(&orig_node->last_ttvn); 755 (*tt_data)->num_vlan = htons(num_vlan); 756 757 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1); 758 list_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) { 759 tt_vlan->vid = htons(vlan->vid); 760 tt_vlan->crc = htonl(vlan->tt.crc); 761 762 tt_vlan++; 763 } 764 765 tt_change_ptr = (uint8_t *)*tt_data + change_offset; 766 *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr; 767 768 out: 769 rcu_read_unlock(); 770 return tvlv_len; 771 } 772 773 /** 774 * batadv_tt_prepare_tvlv_local_data - allocate and prepare the TT TVLV for this 775 * node 776 * @bat_priv: the bat priv with all the soft interface information 777 * @tt_data: uninitialised pointer to the address of the TVLV buffer 778 * @tt_change: uninitialised pointer to the address of the area where the TT 779 * changes can be stored 780 * @tt_len: pointer to the length to reserve to the tt_change. if -1 this 781 * function reserves the amount of space needed to send the entire local TT 782 * table. In case of success the value is updated with the real amount of 783 * reserved bytes 784 * 785 * Allocate the needed amount of memory for the entire TT TVLV and write its 786 * header made up by one tvlv_tt_data object and a series of tvlv_tt_vlan_data 787 * objects, one per active VLAN. 788 * 789 * Return the size of the allocated buffer or 0 in case of failure. 790 */ 791 static uint16_t 792 batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, 793 struct batadv_tvlv_tt_data **tt_data, 794 struct batadv_tvlv_tt_change **tt_change, 795 int32_t *tt_len) 796 { 797 struct batadv_tvlv_tt_vlan_data *tt_vlan; 798 struct batadv_softif_vlan *vlan; 799 uint16_t num_vlan = 0, num_entries = 0, tvlv_len; 800 uint8_t *tt_change_ptr; 801 int change_offset; 802 803 rcu_read_lock(); 804 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { 805 num_vlan++; 806 num_entries += atomic_read(&vlan->tt.num_entries); 807 } 808 809 change_offset = sizeof(**tt_data); 810 change_offset += num_vlan * sizeof(*tt_vlan); 811 812 /* if tt_len is negative, allocate the space needed by the full table */ 813 if (*tt_len < 0) 814 *tt_len = batadv_tt_len(num_entries); 815 816 tvlv_len = *tt_len; 817 tvlv_len += change_offset; 818 819 *tt_data = kmalloc(tvlv_len, GFP_ATOMIC); 820 if (!*tt_data) { 821 tvlv_len = 0; 822 goto out; 823 } 824 825 (*tt_data)->flags = BATADV_NO_FLAGS; 826 (*tt_data)->ttvn = atomic_read(&bat_priv->tt.vn); 827 (*tt_data)->num_vlan = htons(num_vlan); 828 829 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1); 830 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { 831 tt_vlan->vid = htons(vlan->vid); 832 tt_vlan->crc = htonl(vlan->tt.crc); 833 834 tt_vlan++; 835 } 836 837 tt_change_ptr = (uint8_t *)*tt_data + change_offset; 838 *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr; 839 840 out: 841 rcu_read_unlock(); 842 return tvlv_len; 843 } 844 845 /** 846 * batadv_tt_tvlv_container_update - update the translation table tvlv container 847 * after local tt changes have been committed 848 * @bat_priv: the bat priv with all the soft interface information 849 */ 850 static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv) 851 { 852 struct batadv_tt_change_node *entry, *safe; 853 struct batadv_tvlv_tt_data *tt_data; 854 struct batadv_tvlv_tt_change *tt_change; 855 int tt_diff_len, tt_change_len = 0; 856 int tt_diff_entries_num = 0, tt_diff_entries_count = 0; 857 uint16_t tvlv_len; 858 859 tt_diff_entries_num = atomic_read(&bat_priv->tt.local_changes); 860 tt_diff_len = batadv_tt_len(tt_diff_entries_num); 861 862 /* if we have too many changes for one packet don't send any 863 * and wait for the tt table request which will be fragmented 864 */ 865 if (tt_diff_len > bat_priv->soft_iface->mtu) 866 tt_diff_len = 0; 867 868 tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv, &tt_data, 869 &tt_change, &tt_diff_len); 870 if (!tvlv_len) 871 return; 872 873 tt_data->flags = BATADV_TT_OGM_DIFF; 874 875 if (tt_diff_len == 0) 876 goto container_register; 877 878 spin_lock_bh(&bat_priv->tt.changes_list_lock); 879 atomic_set(&bat_priv->tt.local_changes, 0); 880 881 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, 882 list) { 883 if (tt_diff_entries_count < tt_diff_entries_num) { 884 memcpy(tt_change + tt_diff_entries_count, 885 &entry->change, 886 sizeof(struct batadv_tvlv_tt_change)); 887 tt_diff_entries_count++; 888 } 889 list_del(&entry->list); 890 kfree(entry); 891 } 892 spin_unlock_bh(&bat_priv->tt.changes_list_lock); 893 894 /* Keep the buffer for possible tt_request */ 895 spin_lock_bh(&bat_priv->tt.last_changeset_lock); 896 kfree(bat_priv->tt.last_changeset); 897 bat_priv->tt.last_changeset_len = 0; 898 bat_priv->tt.last_changeset = NULL; 899 tt_change_len = batadv_tt_len(tt_diff_entries_count); 900 /* check whether this new OGM has no changes due to size problems */ 901 if (tt_diff_entries_count > 0) { 902 /* if kmalloc() fails we will reply with the full table 903 * instead of providing the diff 904 */ 905 bat_priv->tt.last_changeset = kzalloc(tt_diff_len, GFP_ATOMIC); 906 if (bat_priv->tt.last_changeset) { 907 memcpy(bat_priv->tt.last_changeset, 908 tt_change, tt_change_len); 909 bat_priv->tt.last_changeset_len = tt_diff_len; 910 } 911 } 912 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); 913 914 container_register: 915 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_TT, 1, tt_data, 916 tvlv_len); 917 kfree(tt_data); 918 } 919 920 int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) 921 { 922 struct net_device *net_dev = (struct net_device *)seq->private; 923 struct batadv_priv *bat_priv = netdev_priv(net_dev); 924 struct batadv_hashtable *hash = bat_priv->tt.local_hash; 925 struct batadv_tt_common_entry *tt_common_entry; 926 struct batadv_tt_local_entry *tt_local; 927 struct batadv_hard_iface *primary_if; 928 struct batadv_softif_vlan *vlan; 929 struct hlist_head *head; 930 unsigned short vid; 931 uint32_t i; 932 int last_seen_secs; 933 int last_seen_msecs; 934 unsigned long last_seen_jiffies; 935 bool no_purge; 936 uint16_t np_flag = BATADV_TT_CLIENT_NOPURGE; 937 938 primary_if = batadv_seq_print_text_primary_if_get(seq); 939 if (!primary_if) 940 goto out; 941 942 seq_printf(seq, 943 "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n", 944 net_dev->name, (uint8_t)atomic_read(&bat_priv->tt.vn)); 945 seq_printf(seq, " %-13s %s %-8s %-9s (%-10s)\n", "Client", "VID", 946 "Flags", "Last seen", "CRC"); 947 948 for (i = 0; i < hash->size; i++) { 949 head = &hash->table[i]; 950 951 rcu_read_lock(); 952 hlist_for_each_entry_rcu(tt_common_entry, 953 head, hash_entry) { 954 tt_local = container_of(tt_common_entry, 955 struct batadv_tt_local_entry, 956 common); 957 vid = tt_common_entry->vid; 958 last_seen_jiffies = jiffies - tt_local->last_seen; 959 last_seen_msecs = jiffies_to_msecs(last_seen_jiffies); 960 last_seen_secs = last_seen_msecs / 1000; 961 last_seen_msecs = last_seen_msecs % 1000; 962 963 no_purge = tt_common_entry->flags & np_flag; 964 965 vlan = batadv_softif_vlan_get(bat_priv, vid); 966 if (!vlan) { 967 seq_printf(seq, "Cannot retrieve VLAN %d\n", 968 BATADV_PRINT_VID(vid)); 969 continue; 970 } 971 972 seq_printf(seq, 973 " * %pM %4i [%c%c%c%c%c%c] %3u.%03u (%#.8x)\n", 974 tt_common_entry->addr, 975 BATADV_PRINT_VID(tt_common_entry->vid), 976 ((tt_common_entry->flags & 977 BATADV_TT_CLIENT_ROAM) ? 'R' : '.'), 978 no_purge ? 'P' : '.', 979 ((tt_common_entry->flags & 980 BATADV_TT_CLIENT_NEW) ? 'N' : '.'), 981 ((tt_common_entry->flags & 982 BATADV_TT_CLIENT_PENDING) ? 'X' : '.'), 983 ((tt_common_entry->flags & 984 BATADV_TT_CLIENT_WIFI) ? 'W' : '.'), 985 ((tt_common_entry->flags & 986 BATADV_TT_CLIENT_ISOLA) ? 'I' : '.'), 987 no_purge ? 0 : last_seen_secs, 988 no_purge ? 0 : last_seen_msecs, 989 vlan->tt.crc); 990 991 batadv_softif_vlan_free_ref(vlan); 992 } 993 rcu_read_unlock(); 994 } 995 out: 996 if (primary_if) 997 batadv_hardif_free_ref(primary_if); 998 return 0; 999 } 1000 1001 static void 1002 batadv_tt_local_set_pending(struct batadv_priv *bat_priv, 1003 struct batadv_tt_local_entry *tt_local_entry, 1004 uint16_t flags, const char *message) 1005 { 1006 batadv_tt_local_event(bat_priv, tt_local_entry, flags); 1007 1008 /* The local client has to be marked as "pending to be removed" but has 1009 * to be kept in the table in order to send it in a full table 1010 * response issued before the net ttvn increment (consistency check) 1011 */ 1012 tt_local_entry->common.flags |= BATADV_TT_CLIENT_PENDING; 1013 1014 batadv_dbg(BATADV_DBG_TT, bat_priv, 1015 "Local tt entry (%pM, vid: %d) pending to be removed: %s\n", 1016 tt_local_entry->common.addr, 1017 BATADV_PRINT_VID(tt_local_entry->common.vid), message); 1018 } 1019 1020 /** 1021 * batadv_tt_local_remove - logically remove an entry from the local table 1022 * @bat_priv: the bat priv with all the soft interface information 1023 * @addr: the MAC address of the client to remove 1024 * @vid: VLAN identifier 1025 * @message: message to append to the log on deletion 1026 * @roaming: true if the deletion is due to a roaming event 1027 * 1028 * Returns the flags assigned to the local entry before being deleted 1029 */ 1030 uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, 1031 const uint8_t *addr, unsigned short vid, 1032 const char *message, bool roaming) 1033 { 1034 struct batadv_tt_local_entry *tt_local_entry; 1035 uint16_t flags, curr_flags = BATADV_NO_FLAGS; 1036 struct batadv_softif_vlan *vlan; 1037 1038 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid); 1039 if (!tt_local_entry) 1040 goto out; 1041 1042 curr_flags = tt_local_entry->common.flags; 1043 1044 flags = BATADV_TT_CLIENT_DEL; 1045 /* if this global entry addition is due to a roaming, the node has to 1046 * mark the local entry as "roamed" in order to correctly reroute 1047 * packets later 1048 */ 1049 if (roaming) { 1050 flags |= BATADV_TT_CLIENT_ROAM; 1051 /* mark the local client as ROAMed */ 1052 tt_local_entry->common.flags |= BATADV_TT_CLIENT_ROAM; 1053 } 1054 1055 if (!(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) { 1056 batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, 1057 message); 1058 goto out; 1059 } 1060 /* if this client has been added right now, it is possible to 1061 * immediately purge it 1062 */ 1063 batadv_tt_local_event(bat_priv, tt_local_entry, BATADV_TT_CLIENT_DEL); 1064 hlist_del_rcu(&tt_local_entry->common.hash_entry); 1065 batadv_tt_local_entry_free_ref(tt_local_entry); 1066 1067 /* decrease the reference held for this vlan */ 1068 vlan = batadv_softif_vlan_get(bat_priv, vid); 1069 batadv_softif_vlan_free_ref(vlan); 1070 batadv_softif_vlan_free_ref(vlan); 1071 1072 out: 1073 if (tt_local_entry) 1074 batadv_tt_local_entry_free_ref(tt_local_entry); 1075 1076 return curr_flags; 1077 } 1078 1079 /** 1080 * batadv_tt_local_purge_list - purge inactive tt local entries 1081 * @bat_priv: the bat priv with all the soft interface information 1082 * @head: pointer to the list containing the local tt entries 1083 * @timeout: parameter deciding whether a given tt local entry is considered 1084 * inactive or not 1085 */ 1086 static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv, 1087 struct hlist_head *head, 1088 int timeout) 1089 { 1090 struct batadv_tt_local_entry *tt_local_entry; 1091 struct batadv_tt_common_entry *tt_common_entry; 1092 struct hlist_node *node_tmp; 1093 1094 hlist_for_each_entry_safe(tt_common_entry, node_tmp, head, 1095 hash_entry) { 1096 tt_local_entry = container_of(tt_common_entry, 1097 struct batadv_tt_local_entry, 1098 common); 1099 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_NOPURGE) 1100 continue; 1101 1102 /* entry already marked for deletion */ 1103 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) 1104 continue; 1105 1106 if (!batadv_has_timed_out(tt_local_entry->last_seen, timeout)) 1107 continue; 1108 1109 batadv_tt_local_set_pending(bat_priv, tt_local_entry, 1110 BATADV_TT_CLIENT_DEL, "timed out"); 1111 } 1112 } 1113 1114 /** 1115 * batadv_tt_local_purge - purge inactive tt local entries 1116 * @bat_priv: the bat priv with all the soft interface information 1117 * @timeout: parameter deciding whether a given tt local entry is considered 1118 * inactive or not 1119 */ 1120 static void batadv_tt_local_purge(struct batadv_priv *bat_priv, 1121 int timeout) 1122 { 1123 struct batadv_hashtable *hash = bat_priv->tt.local_hash; 1124 struct hlist_head *head; 1125 spinlock_t *list_lock; /* protects write access to the hash lists */ 1126 uint32_t i; 1127 1128 for (i = 0; i < hash->size; i++) { 1129 head = &hash->table[i]; 1130 list_lock = &hash->list_locks[i]; 1131 1132 spin_lock_bh(list_lock); 1133 batadv_tt_local_purge_list(bat_priv, head, timeout); 1134 spin_unlock_bh(list_lock); 1135 } 1136 } 1137 1138 static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) 1139 { 1140 struct batadv_hashtable *hash; 1141 spinlock_t *list_lock; /* protects write access to the hash lists */ 1142 struct batadv_tt_common_entry *tt_common_entry; 1143 struct batadv_tt_local_entry *tt_local; 1144 struct batadv_softif_vlan *vlan; 1145 struct hlist_node *node_tmp; 1146 struct hlist_head *head; 1147 uint32_t i; 1148 1149 if (!bat_priv->tt.local_hash) 1150 return; 1151 1152 hash = bat_priv->tt.local_hash; 1153 1154 for (i = 0; i < hash->size; i++) { 1155 head = &hash->table[i]; 1156 list_lock = &hash->list_locks[i]; 1157 1158 spin_lock_bh(list_lock); 1159 hlist_for_each_entry_safe(tt_common_entry, node_tmp, 1160 head, hash_entry) { 1161 hlist_del_rcu(&tt_common_entry->hash_entry); 1162 tt_local = container_of(tt_common_entry, 1163 struct batadv_tt_local_entry, 1164 common); 1165 1166 /* decrease the reference held for this vlan */ 1167 vlan = batadv_softif_vlan_get(bat_priv, 1168 tt_common_entry->vid); 1169 batadv_softif_vlan_free_ref(vlan); 1170 batadv_softif_vlan_free_ref(vlan); 1171 1172 batadv_tt_local_entry_free_ref(tt_local); 1173 } 1174 spin_unlock_bh(list_lock); 1175 } 1176 1177 batadv_hash_destroy(hash); 1178 1179 bat_priv->tt.local_hash = NULL; 1180 } 1181 1182 static int batadv_tt_global_init(struct batadv_priv *bat_priv) 1183 { 1184 if (bat_priv->tt.global_hash) 1185 return 0; 1186 1187 bat_priv->tt.global_hash = batadv_hash_new(1024); 1188 1189 if (!bat_priv->tt.global_hash) 1190 return -ENOMEM; 1191 1192 batadv_hash_set_lock_class(bat_priv->tt.global_hash, 1193 &batadv_tt_global_hash_lock_class_key); 1194 1195 return 0; 1196 } 1197 1198 static void batadv_tt_changes_list_free(struct batadv_priv *bat_priv) 1199 { 1200 struct batadv_tt_change_node *entry, *safe; 1201 1202 spin_lock_bh(&bat_priv->tt.changes_list_lock); 1203 1204 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, 1205 list) { 1206 list_del(&entry->list); 1207 kfree(entry); 1208 } 1209 1210 atomic_set(&bat_priv->tt.local_changes, 0); 1211 spin_unlock_bh(&bat_priv->tt.changes_list_lock); 1212 } 1213 1214 /* retrieves the orig_tt_list_entry belonging to orig_node from the 1215 * batadv_tt_global_entry list 1216 * 1217 * returns it with an increased refcounter, NULL if not found 1218 */ 1219 static struct batadv_tt_orig_list_entry * 1220 batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry, 1221 const struct batadv_orig_node *orig_node) 1222 { 1223 struct batadv_tt_orig_list_entry *tmp_orig_entry, *orig_entry = NULL; 1224 const struct hlist_head *head; 1225 1226 rcu_read_lock(); 1227 head = &entry->orig_list; 1228 hlist_for_each_entry_rcu(tmp_orig_entry, head, list) { 1229 if (tmp_orig_entry->orig_node != orig_node) 1230 continue; 1231 if (!atomic_inc_not_zero(&tmp_orig_entry->refcount)) 1232 continue; 1233 1234 orig_entry = tmp_orig_entry; 1235 break; 1236 } 1237 rcu_read_unlock(); 1238 1239 return orig_entry; 1240 } 1241 1242 /* find out if an orig_node is already in the list of a tt_global_entry. 1243 * returns true if found, false otherwise 1244 */ 1245 static bool 1246 batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry, 1247 const struct batadv_orig_node *orig_node) 1248 { 1249 struct batadv_tt_orig_list_entry *orig_entry; 1250 bool found = false; 1251 1252 orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node); 1253 if (orig_entry) { 1254 found = true; 1255 batadv_tt_orig_list_entry_free_ref(orig_entry); 1256 } 1257 1258 return found; 1259 } 1260 1261 static void 1262 batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, 1263 struct batadv_orig_node *orig_node, int ttvn) 1264 { 1265 struct batadv_tt_orig_list_entry *orig_entry; 1266 1267 orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node); 1268 if (orig_entry) { 1269 /* refresh the ttvn: the current value could be a bogus one that 1270 * was added during a "temporary client detection" 1271 */ 1272 orig_entry->ttvn = ttvn; 1273 goto out; 1274 } 1275 1276 orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC); 1277 if (!orig_entry) 1278 goto out; 1279 1280 INIT_HLIST_NODE(&orig_entry->list); 1281 atomic_inc(&orig_node->refcount); 1282 batadv_tt_global_size_inc(orig_node, tt_global->common.vid); 1283 orig_entry->orig_node = orig_node; 1284 orig_entry->ttvn = ttvn; 1285 atomic_set(&orig_entry->refcount, 2); 1286 1287 spin_lock_bh(&tt_global->list_lock); 1288 hlist_add_head_rcu(&orig_entry->list, 1289 &tt_global->orig_list); 1290 spin_unlock_bh(&tt_global->list_lock); 1291 atomic_inc(&tt_global->orig_list_count); 1292 1293 out: 1294 if (orig_entry) 1295 batadv_tt_orig_list_entry_free_ref(orig_entry); 1296 } 1297 1298 /** 1299 * batadv_tt_global_add - add a new TT global entry or update an existing one 1300 * @bat_priv: the bat priv with all the soft interface information 1301 * @orig_node: the originator announcing the client 1302 * @tt_addr: the mac address of the non-mesh client 1303 * @vid: VLAN identifier 1304 * @flags: TT flags that have to be set for this non-mesh client 1305 * @ttvn: the tt version number ever announcing this non-mesh client 1306 * 1307 * Add a new TT global entry for the given originator. If the entry already 1308 * exists add a new reference to the given originator (a global entry can have 1309 * references to multiple originators) and adjust the flags attribute to reflect 1310 * the function argument. 1311 * If a TT local entry exists for this non-mesh client remove it. 1312 * 1313 * The caller must hold orig_node refcount. 1314 * 1315 * Return true if the new entry has been added, false otherwise 1316 */ 1317 static bool batadv_tt_global_add(struct batadv_priv *bat_priv, 1318 struct batadv_orig_node *orig_node, 1319 const unsigned char *tt_addr, 1320 unsigned short vid, uint16_t flags, 1321 uint8_t ttvn) 1322 { 1323 struct batadv_tt_global_entry *tt_global_entry; 1324 struct batadv_tt_local_entry *tt_local_entry; 1325 bool ret = false; 1326 int hash_added; 1327 struct batadv_tt_common_entry *common; 1328 uint16_t local_flags; 1329 1330 /* ignore global entries from backbone nodes */ 1331 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) 1332 return true; 1333 1334 tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr, vid); 1335 tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr, vid); 1336 1337 /* if the node already has a local client for this entry, it has to wait 1338 * for a roaming advertisement instead of manually messing up the global 1339 * table 1340 */ 1341 if ((flags & BATADV_TT_CLIENT_TEMP) && tt_local_entry && 1342 !(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) 1343 goto out; 1344 1345 if (!tt_global_entry) { 1346 tt_global_entry = kzalloc(sizeof(*tt_global_entry), GFP_ATOMIC); 1347 if (!tt_global_entry) 1348 goto out; 1349 1350 common = &tt_global_entry->common; 1351 ether_addr_copy(common->addr, tt_addr); 1352 common->vid = vid; 1353 1354 common->flags = flags; 1355 tt_global_entry->roam_at = 0; 1356 /* node must store current time in case of roaming. This is 1357 * needed to purge this entry out on timeout (if nobody claims 1358 * it) 1359 */ 1360 if (flags & BATADV_TT_CLIENT_ROAM) 1361 tt_global_entry->roam_at = jiffies; 1362 atomic_set(&common->refcount, 2); 1363 common->added_at = jiffies; 1364 1365 INIT_HLIST_HEAD(&tt_global_entry->orig_list); 1366 atomic_set(&tt_global_entry->orig_list_count, 0); 1367 spin_lock_init(&tt_global_entry->list_lock); 1368 1369 hash_added = batadv_hash_add(bat_priv->tt.global_hash, 1370 batadv_compare_tt, 1371 batadv_choose_tt, common, 1372 &common->hash_entry); 1373 1374 if (unlikely(hash_added != 0)) { 1375 /* remove the reference for the hash */ 1376 batadv_tt_global_entry_free_ref(tt_global_entry); 1377 goto out_remove; 1378 } 1379 } else { 1380 common = &tt_global_entry->common; 1381 /* If there is already a global entry, we can use this one for 1382 * our processing. 1383 * But if we are trying to add a temporary client then here are 1384 * two options at this point: 1385 * 1) the global client is not a temporary client: the global 1386 * client has to be left as it is, temporary information 1387 * should never override any already known client state 1388 * 2) the global client is a temporary client: purge the 1389 * originator list and add the new one orig_entry 1390 */ 1391 if (flags & BATADV_TT_CLIENT_TEMP) { 1392 if (!(common->flags & BATADV_TT_CLIENT_TEMP)) 1393 goto out; 1394 if (batadv_tt_global_entry_has_orig(tt_global_entry, 1395 orig_node)) 1396 goto out_remove; 1397 batadv_tt_global_del_orig_list(tt_global_entry); 1398 goto add_orig_entry; 1399 } 1400 1401 /* if the client was temporary added before receiving the first 1402 * OGM announcing it, we have to clear the TEMP flag 1403 */ 1404 common->flags &= ~BATADV_TT_CLIENT_TEMP; 1405 1406 /* the change can carry possible "attribute" flags like the 1407 * TT_CLIENT_WIFI, therefore they have to be copied in the 1408 * client entry 1409 */ 1410 tt_global_entry->common.flags |= flags; 1411 1412 /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only 1413 * one originator left in the list and we previously received a 1414 * delete + roaming change for this originator. 1415 * 1416 * We should first delete the old originator before adding the 1417 * new one. 1418 */ 1419 if (common->flags & BATADV_TT_CLIENT_ROAM) { 1420 batadv_tt_global_del_orig_list(tt_global_entry); 1421 common->flags &= ~BATADV_TT_CLIENT_ROAM; 1422 tt_global_entry->roam_at = 0; 1423 } 1424 } 1425 add_orig_entry: 1426 /* add the new orig_entry (if needed) or update it */ 1427 batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn); 1428 1429 batadv_dbg(BATADV_DBG_TT, bat_priv, 1430 "Creating new global tt entry: %pM (vid: %d, via %pM)\n", 1431 common->addr, BATADV_PRINT_VID(common->vid), 1432 orig_node->orig); 1433 ret = true; 1434 1435 out_remove: 1436 /* Do not remove multicast addresses from the local hash on 1437 * global additions 1438 */ 1439 if (is_multicast_ether_addr(tt_addr)) 1440 goto out; 1441 1442 /* remove address from local hash if present */ 1443 local_flags = batadv_tt_local_remove(bat_priv, tt_addr, vid, 1444 "global tt received", 1445 flags & BATADV_TT_CLIENT_ROAM); 1446 tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI; 1447 1448 if (!(flags & BATADV_TT_CLIENT_ROAM)) 1449 /* this is a normal global add. Therefore the client is not in a 1450 * roaming state anymore. 1451 */ 1452 tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM; 1453 1454 out: 1455 if (tt_global_entry) 1456 batadv_tt_global_entry_free_ref(tt_global_entry); 1457 if (tt_local_entry) 1458 batadv_tt_local_entry_free_ref(tt_local_entry); 1459 return ret; 1460 } 1461 1462 /** 1463 * batadv_transtable_best_orig - Get best originator list entry from tt entry 1464 * @bat_priv: the bat priv with all the soft interface information 1465 * @tt_global_entry: global translation table entry to be analyzed 1466 * 1467 * This functon assumes the caller holds rcu_read_lock(). 1468 * Returns best originator list entry or NULL on errors. 1469 */ 1470 static struct batadv_tt_orig_list_entry * 1471 batadv_transtable_best_orig(struct batadv_priv *bat_priv, 1472 struct batadv_tt_global_entry *tt_global_entry) 1473 { 1474 struct batadv_neigh_node *router, *best_router = NULL; 1475 struct batadv_algo_ops *bao = bat_priv->bat_algo_ops; 1476 struct hlist_head *head; 1477 struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL; 1478 1479 head = &tt_global_entry->orig_list; 1480 hlist_for_each_entry_rcu(orig_entry, head, list) { 1481 router = batadv_orig_router_get(orig_entry->orig_node, 1482 BATADV_IF_DEFAULT); 1483 if (!router) 1484 continue; 1485 1486 if (best_router && 1487 bao->bat_neigh_cmp(router, BATADV_IF_DEFAULT, 1488 best_router, BATADV_IF_DEFAULT) <= 0) { 1489 batadv_neigh_node_free_ref(router); 1490 continue; 1491 } 1492 1493 /* release the refcount for the "old" best */ 1494 if (best_router) 1495 batadv_neigh_node_free_ref(best_router); 1496 1497 best_entry = orig_entry; 1498 best_router = router; 1499 } 1500 1501 if (best_router) 1502 batadv_neigh_node_free_ref(best_router); 1503 1504 return best_entry; 1505 } 1506 1507 /** 1508 * batadv_tt_global_print_entry - print all orig nodes who announce the address 1509 * for this global entry 1510 * @bat_priv: the bat priv with all the soft interface information 1511 * @tt_global_entry: global translation table entry to be printed 1512 * @seq: debugfs table seq_file struct 1513 * 1514 * This functon assumes the caller holds rcu_read_lock(). 1515 */ 1516 static void 1517 batadv_tt_global_print_entry(struct batadv_priv *bat_priv, 1518 struct batadv_tt_global_entry *tt_global_entry, 1519 struct seq_file *seq) 1520 { 1521 struct batadv_tt_orig_list_entry *orig_entry, *best_entry; 1522 struct batadv_tt_common_entry *tt_common_entry; 1523 struct batadv_orig_node_vlan *vlan; 1524 struct hlist_head *head; 1525 uint8_t last_ttvn; 1526 uint16_t flags; 1527 1528 tt_common_entry = &tt_global_entry->common; 1529 flags = tt_common_entry->flags; 1530 1531 best_entry = batadv_transtable_best_orig(bat_priv, tt_global_entry); 1532 if (best_entry) { 1533 vlan = batadv_orig_node_vlan_get(best_entry->orig_node, 1534 tt_common_entry->vid); 1535 if (!vlan) { 1536 seq_printf(seq, 1537 " * Cannot retrieve VLAN %d for originator %pM\n", 1538 BATADV_PRINT_VID(tt_common_entry->vid), 1539 best_entry->orig_node->orig); 1540 goto print_list; 1541 } 1542 1543 last_ttvn = atomic_read(&best_entry->orig_node->last_ttvn); 1544 seq_printf(seq, 1545 " %c %pM %4i (%3u) via %pM (%3u) (%#.8x) [%c%c%c%c]\n", 1546 '*', tt_global_entry->common.addr, 1547 BATADV_PRINT_VID(tt_global_entry->common.vid), 1548 best_entry->ttvn, best_entry->orig_node->orig, 1549 last_ttvn, vlan->tt.crc, 1550 ((flags & BATADV_TT_CLIENT_ROAM) ? 'R' : '.'), 1551 ((flags & BATADV_TT_CLIENT_WIFI) ? 'W' : '.'), 1552 ((flags & BATADV_TT_CLIENT_ISOLA) ? 'I' : '.'), 1553 ((flags & BATADV_TT_CLIENT_TEMP) ? 'T' : '.')); 1554 1555 batadv_orig_node_vlan_free_ref(vlan); 1556 } 1557 1558 print_list: 1559 head = &tt_global_entry->orig_list; 1560 1561 hlist_for_each_entry_rcu(orig_entry, head, list) { 1562 if (best_entry == orig_entry) 1563 continue; 1564 1565 vlan = batadv_orig_node_vlan_get(orig_entry->orig_node, 1566 tt_common_entry->vid); 1567 if (!vlan) { 1568 seq_printf(seq, 1569 " + Cannot retrieve VLAN %d for originator %pM\n", 1570 BATADV_PRINT_VID(tt_common_entry->vid), 1571 orig_entry->orig_node->orig); 1572 continue; 1573 } 1574 1575 last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn); 1576 seq_printf(seq, 1577 " %c %pM %4d (%3u) via %pM (%3u) (%#.8x) [%c%c%c%c]\n", 1578 '+', tt_global_entry->common.addr, 1579 BATADV_PRINT_VID(tt_global_entry->common.vid), 1580 orig_entry->ttvn, orig_entry->orig_node->orig, 1581 last_ttvn, vlan->tt.crc, 1582 ((flags & BATADV_TT_CLIENT_ROAM) ? 'R' : '.'), 1583 ((flags & BATADV_TT_CLIENT_WIFI) ? 'W' : '.'), 1584 ((flags & BATADV_TT_CLIENT_ISOLA) ? 'I' : '.'), 1585 ((flags & BATADV_TT_CLIENT_TEMP) ? 'T' : '.')); 1586 1587 batadv_orig_node_vlan_free_ref(vlan); 1588 } 1589 } 1590 1591 int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset) 1592 { 1593 struct net_device *net_dev = (struct net_device *)seq->private; 1594 struct batadv_priv *bat_priv = netdev_priv(net_dev); 1595 struct batadv_hashtable *hash = bat_priv->tt.global_hash; 1596 struct batadv_tt_common_entry *tt_common_entry; 1597 struct batadv_tt_global_entry *tt_global; 1598 struct batadv_hard_iface *primary_if; 1599 struct hlist_head *head; 1600 uint32_t i; 1601 1602 primary_if = batadv_seq_print_text_primary_if_get(seq); 1603 if (!primary_if) 1604 goto out; 1605 1606 seq_printf(seq, 1607 "Globally announced TT entries received via the mesh %s\n", 1608 net_dev->name); 1609 seq_printf(seq, " %-13s %s %s %-15s %s (%-10s) %s\n", 1610 "Client", "VID", "(TTVN)", "Originator", "(Curr TTVN)", 1611 "CRC", "Flags"); 1612 1613 for (i = 0; i < hash->size; i++) { 1614 head = &hash->table[i]; 1615 1616 rcu_read_lock(); 1617 hlist_for_each_entry_rcu(tt_common_entry, 1618 head, hash_entry) { 1619 tt_global = container_of(tt_common_entry, 1620 struct batadv_tt_global_entry, 1621 common); 1622 batadv_tt_global_print_entry(bat_priv, tt_global, seq); 1623 } 1624 rcu_read_unlock(); 1625 } 1626 out: 1627 if (primary_if) 1628 batadv_hardif_free_ref(primary_if); 1629 return 0; 1630 } 1631 1632 /** 1633 * batadv_tt_global_del_orig_entry - remove and free an orig_entry 1634 * @tt_global_entry: the global entry to remove the orig_entry from 1635 * @orig_entry: the orig entry to remove and free 1636 * 1637 * Remove an orig_entry from its list in the given tt_global_entry and 1638 * free this orig_entry afterwards. 1639 */ 1640 static void 1641 batadv_tt_global_del_orig_entry(struct batadv_tt_global_entry *tt_global_entry, 1642 struct batadv_tt_orig_list_entry *orig_entry) 1643 { 1644 batadv_tt_global_size_dec(orig_entry->orig_node, 1645 tt_global_entry->common.vid); 1646 atomic_dec(&tt_global_entry->orig_list_count); 1647 hlist_del_rcu(&orig_entry->list); 1648 batadv_tt_orig_list_entry_free_ref(orig_entry); 1649 } 1650 1651 /* deletes the orig list of a tt_global_entry */ 1652 static void 1653 batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry) 1654 { 1655 struct hlist_head *head; 1656 struct hlist_node *safe; 1657 struct batadv_tt_orig_list_entry *orig_entry; 1658 1659 spin_lock_bh(&tt_global_entry->list_lock); 1660 head = &tt_global_entry->orig_list; 1661 hlist_for_each_entry_safe(orig_entry, safe, head, list) 1662 batadv_tt_global_del_orig_entry(tt_global_entry, orig_entry); 1663 spin_unlock_bh(&tt_global_entry->list_lock); 1664 } 1665 1666 /** 1667 * batadv_tt_global_del_orig_node - remove orig_node from a global tt entry 1668 * @bat_priv: the bat priv with all the soft interface information 1669 * @tt_global_entry: the global entry to remove the orig_node from 1670 * @orig_node: the originator announcing the client 1671 * @message: message to append to the log on deletion 1672 * 1673 * Remove the given orig_node and its according orig_entry from the given 1674 * global tt entry. 1675 */ 1676 static void 1677 batadv_tt_global_del_orig_node(struct batadv_priv *bat_priv, 1678 struct batadv_tt_global_entry *tt_global_entry, 1679 struct batadv_orig_node *orig_node, 1680 const char *message) 1681 { 1682 struct hlist_head *head; 1683 struct hlist_node *safe; 1684 struct batadv_tt_orig_list_entry *orig_entry; 1685 unsigned short vid; 1686 1687 spin_lock_bh(&tt_global_entry->list_lock); 1688 head = &tt_global_entry->orig_list; 1689 hlist_for_each_entry_safe(orig_entry, safe, head, list) { 1690 if (orig_entry->orig_node == orig_node) { 1691 vid = tt_global_entry->common.vid; 1692 batadv_dbg(BATADV_DBG_TT, bat_priv, 1693 "Deleting %pM from global tt entry %pM (vid: %d): %s\n", 1694 orig_node->orig, 1695 tt_global_entry->common.addr, 1696 BATADV_PRINT_VID(vid), message); 1697 batadv_tt_global_del_orig_entry(tt_global_entry, 1698 orig_entry); 1699 } 1700 } 1701 spin_unlock_bh(&tt_global_entry->list_lock); 1702 } 1703 1704 /* If the client is to be deleted, we check if it is the last origantor entry 1705 * within tt_global entry. If yes, we set the BATADV_TT_CLIENT_ROAM flag and the 1706 * timer, otherwise we simply remove the originator scheduled for deletion. 1707 */ 1708 static void 1709 batadv_tt_global_del_roaming(struct batadv_priv *bat_priv, 1710 struct batadv_tt_global_entry *tt_global_entry, 1711 struct batadv_orig_node *orig_node, 1712 const char *message) 1713 { 1714 bool last_entry = true; 1715 struct hlist_head *head; 1716 struct batadv_tt_orig_list_entry *orig_entry; 1717 1718 /* no local entry exists, case 1: 1719 * Check if this is the last one or if other entries exist. 1720 */ 1721 1722 rcu_read_lock(); 1723 head = &tt_global_entry->orig_list; 1724 hlist_for_each_entry_rcu(orig_entry, head, list) { 1725 if (orig_entry->orig_node != orig_node) { 1726 last_entry = false; 1727 break; 1728 } 1729 } 1730 rcu_read_unlock(); 1731 1732 if (last_entry) { 1733 /* its the last one, mark for roaming. */ 1734 tt_global_entry->common.flags |= BATADV_TT_CLIENT_ROAM; 1735 tt_global_entry->roam_at = jiffies; 1736 } else 1737 /* there is another entry, we can simply delete this 1738 * one and can still use the other one. 1739 */ 1740 batadv_tt_global_del_orig_node(bat_priv, tt_global_entry, 1741 orig_node, message); 1742 } 1743 1744 /** 1745 * batadv_tt_global_del - remove a client from the global table 1746 * @bat_priv: the bat priv with all the soft interface information 1747 * @orig_node: an originator serving this client 1748 * @addr: the mac address of the client 1749 * @vid: VLAN identifier 1750 * @message: a message explaining the reason for deleting the client to print 1751 * for debugging purpose 1752 * @roaming: true if the deletion has been triggered by a roaming event 1753 */ 1754 static void batadv_tt_global_del(struct batadv_priv *bat_priv, 1755 struct batadv_orig_node *orig_node, 1756 const unsigned char *addr, unsigned short vid, 1757 const char *message, bool roaming) 1758 { 1759 struct batadv_tt_global_entry *tt_global_entry; 1760 struct batadv_tt_local_entry *local_entry = NULL; 1761 1762 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid); 1763 if (!tt_global_entry) 1764 goto out; 1765 1766 if (!roaming) { 1767 batadv_tt_global_del_orig_node(bat_priv, tt_global_entry, 1768 orig_node, message); 1769 1770 if (hlist_empty(&tt_global_entry->orig_list)) 1771 batadv_tt_global_free(bat_priv, tt_global_entry, 1772 message); 1773 1774 goto out; 1775 } 1776 1777 /* if we are deleting a global entry due to a roam 1778 * event, there are two possibilities: 1779 * 1) the client roamed from node A to node B => if there 1780 * is only one originator left for this client, we mark 1781 * it with BATADV_TT_CLIENT_ROAM, we start a timer and we 1782 * wait for node B to claim it. In case of timeout 1783 * the entry is purged. 1784 * 1785 * If there are other originators left, we directly delete 1786 * the originator. 1787 * 2) the client roamed to us => we can directly delete 1788 * the global entry, since it is useless now. 1789 */ 1790 local_entry = batadv_tt_local_hash_find(bat_priv, 1791 tt_global_entry->common.addr, 1792 vid); 1793 if (local_entry) { 1794 /* local entry exists, case 2: client roamed to us. */ 1795 batadv_tt_global_del_orig_list(tt_global_entry); 1796 batadv_tt_global_free(bat_priv, tt_global_entry, message); 1797 } else 1798 /* no local entry exists, case 1: check for roaming */ 1799 batadv_tt_global_del_roaming(bat_priv, tt_global_entry, 1800 orig_node, message); 1801 1802 out: 1803 if (tt_global_entry) 1804 batadv_tt_global_entry_free_ref(tt_global_entry); 1805 if (local_entry) 1806 batadv_tt_local_entry_free_ref(local_entry); 1807 } 1808 1809 /** 1810 * batadv_tt_global_del_orig - remove all the TT global entries belonging to the 1811 * given originator matching the provided vid 1812 * @bat_priv: the bat priv with all the soft interface information 1813 * @orig_node: the originator owning the entries to remove 1814 * @match_vid: the VLAN identifier to match. If negative all the entries will be 1815 * removed 1816 * @message: debug message to print as "reason" 1817 */ 1818 void batadv_tt_global_del_orig(struct batadv_priv *bat_priv, 1819 struct batadv_orig_node *orig_node, 1820 int32_t match_vid, 1821 const char *message) 1822 { 1823 struct batadv_tt_global_entry *tt_global; 1824 struct batadv_tt_common_entry *tt_common_entry; 1825 uint32_t i; 1826 struct batadv_hashtable *hash = bat_priv->tt.global_hash; 1827 struct hlist_node *safe; 1828 struct hlist_head *head; 1829 spinlock_t *list_lock; /* protects write access to the hash lists */ 1830 unsigned short vid; 1831 1832 if (!hash) 1833 return; 1834 1835 for (i = 0; i < hash->size; i++) { 1836 head = &hash->table[i]; 1837 list_lock = &hash->list_locks[i]; 1838 1839 spin_lock_bh(list_lock); 1840 hlist_for_each_entry_safe(tt_common_entry, safe, 1841 head, hash_entry) { 1842 /* remove only matching entries */ 1843 if (match_vid >= 0 && tt_common_entry->vid != match_vid) 1844 continue; 1845 1846 tt_global = container_of(tt_common_entry, 1847 struct batadv_tt_global_entry, 1848 common); 1849 1850 batadv_tt_global_del_orig_node(bat_priv, tt_global, 1851 orig_node, message); 1852 1853 if (hlist_empty(&tt_global->orig_list)) { 1854 vid = tt_global->common.vid; 1855 batadv_dbg(BATADV_DBG_TT, bat_priv, 1856 "Deleting global tt entry %pM (vid: %d): %s\n", 1857 tt_global->common.addr, 1858 BATADV_PRINT_VID(vid), message); 1859 hlist_del_rcu(&tt_common_entry->hash_entry); 1860 batadv_tt_global_entry_free_ref(tt_global); 1861 } 1862 } 1863 spin_unlock_bh(list_lock); 1864 } 1865 orig_node->capa_initialized &= ~BATADV_ORIG_CAPA_HAS_TT; 1866 } 1867 1868 static bool batadv_tt_global_to_purge(struct batadv_tt_global_entry *tt_global, 1869 char **msg) 1870 { 1871 bool purge = false; 1872 unsigned long roam_timeout = BATADV_TT_CLIENT_ROAM_TIMEOUT; 1873 unsigned long temp_timeout = BATADV_TT_CLIENT_TEMP_TIMEOUT; 1874 1875 if ((tt_global->common.flags & BATADV_TT_CLIENT_ROAM) && 1876 batadv_has_timed_out(tt_global->roam_at, roam_timeout)) { 1877 purge = true; 1878 *msg = "Roaming timeout\n"; 1879 } 1880 1881 if ((tt_global->common.flags & BATADV_TT_CLIENT_TEMP) && 1882 batadv_has_timed_out(tt_global->common.added_at, temp_timeout)) { 1883 purge = true; 1884 *msg = "Temporary client timeout\n"; 1885 } 1886 1887 return purge; 1888 } 1889 1890 static void batadv_tt_global_purge(struct batadv_priv *bat_priv) 1891 { 1892 struct batadv_hashtable *hash = bat_priv->tt.global_hash; 1893 struct hlist_head *head; 1894 struct hlist_node *node_tmp; 1895 spinlock_t *list_lock; /* protects write access to the hash lists */ 1896 uint32_t i; 1897 char *msg = NULL; 1898 struct batadv_tt_common_entry *tt_common; 1899 struct batadv_tt_global_entry *tt_global; 1900 1901 for (i = 0; i < hash->size; i++) { 1902 head = &hash->table[i]; 1903 list_lock = &hash->list_locks[i]; 1904 1905 spin_lock_bh(list_lock); 1906 hlist_for_each_entry_safe(tt_common, node_tmp, head, 1907 hash_entry) { 1908 tt_global = container_of(tt_common, 1909 struct batadv_tt_global_entry, 1910 common); 1911 1912 if (!batadv_tt_global_to_purge(tt_global, &msg)) 1913 continue; 1914 1915 batadv_dbg(BATADV_DBG_TT, bat_priv, 1916 "Deleting global tt entry %pM (vid: %d): %s\n", 1917 tt_global->common.addr, 1918 BATADV_PRINT_VID(tt_global->common.vid), 1919 msg); 1920 1921 hlist_del_rcu(&tt_common->hash_entry); 1922 1923 batadv_tt_global_entry_free_ref(tt_global); 1924 } 1925 spin_unlock_bh(list_lock); 1926 } 1927 } 1928 1929 static void batadv_tt_global_table_free(struct batadv_priv *bat_priv) 1930 { 1931 struct batadv_hashtable *hash; 1932 spinlock_t *list_lock; /* protects write access to the hash lists */ 1933 struct batadv_tt_common_entry *tt_common_entry; 1934 struct batadv_tt_global_entry *tt_global; 1935 struct hlist_node *node_tmp; 1936 struct hlist_head *head; 1937 uint32_t i; 1938 1939 if (!bat_priv->tt.global_hash) 1940 return; 1941 1942 hash = bat_priv->tt.global_hash; 1943 1944 for (i = 0; i < hash->size; i++) { 1945 head = &hash->table[i]; 1946 list_lock = &hash->list_locks[i]; 1947 1948 spin_lock_bh(list_lock); 1949 hlist_for_each_entry_safe(tt_common_entry, node_tmp, 1950 head, hash_entry) { 1951 hlist_del_rcu(&tt_common_entry->hash_entry); 1952 tt_global = container_of(tt_common_entry, 1953 struct batadv_tt_global_entry, 1954 common); 1955 batadv_tt_global_entry_free_ref(tt_global); 1956 } 1957 spin_unlock_bh(list_lock); 1958 } 1959 1960 batadv_hash_destroy(hash); 1961 1962 bat_priv->tt.global_hash = NULL; 1963 } 1964 1965 static bool 1966 _batadv_is_ap_isolated(struct batadv_tt_local_entry *tt_local_entry, 1967 struct batadv_tt_global_entry *tt_global_entry) 1968 { 1969 bool ret = false; 1970 1971 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_WIFI && 1972 tt_global_entry->common.flags & BATADV_TT_CLIENT_WIFI) 1973 ret = true; 1974 1975 /* check if the two clients are marked as isolated */ 1976 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_ISOLA && 1977 tt_global_entry->common.flags & BATADV_TT_CLIENT_ISOLA) 1978 ret = true; 1979 1980 return ret; 1981 } 1982 1983 /** 1984 * batadv_transtable_search - get the mesh destination for a given client 1985 * @bat_priv: the bat priv with all the soft interface information 1986 * @src: mac address of the source client 1987 * @addr: mac address of the destination client 1988 * @vid: VLAN identifier 1989 * 1990 * Returns a pointer to the originator that was selected as destination in the 1991 * mesh for contacting the client 'addr', NULL otherwise. 1992 * In case of multiple originators serving the same client, the function returns 1993 * the best one (best in terms of metric towards the destination node). 1994 * 1995 * If the two clients are AP isolated the function returns NULL. 1996 */ 1997 struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv, 1998 const uint8_t *src, 1999 const uint8_t *addr, 2000 unsigned short vid) 2001 { 2002 struct batadv_tt_local_entry *tt_local_entry = NULL; 2003 struct batadv_tt_global_entry *tt_global_entry = NULL; 2004 struct batadv_orig_node *orig_node = NULL; 2005 struct batadv_tt_orig_list_entry *best_entry; 2006 2007 if (src && batadv_vlan_ap_isola_get(bat_priv, vid)) { 2008 tt_local_entry = batadv_tt_local_hash_find(bat_priv, src, vid); 2009 if (!tt_local_entry || 2010 (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)) 2011 goto out; 2012 } 2013 2014 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid); 2015 if (!tt_global_entry) 2016 goto out; 2017 2018 /* check whether the clients should not communicate due to AP 2019 * isolation 2020 */ 2021 if (tt_local_entry && 2022 _batadv_is_ap_isolated(tt_local_entry, tt_global_entry)) 2023 goto out; 2024 2025 rcu_read_lock(); 2026 best_entry = batadv_transtable_best_orig(bat_priv, tt_global_entry); 2027 /* found anything? */ 2028 if (best_entry) 2029 orig_node = best_entry->orig_node; 2030 if (orig_node && !atomic_inc_not_zero(&orig_node->refcount)) 2031 orig_node = NULL; 2032 rcu_read_unlock(); 2033 2034 out: 2035 if (tt_global_entry) 2036 batadv_tt_global_entry_free_ref(tt_global_entry); 2037 if (tt_local_entry) 2038 batadv_tt_local_entry_free_ref(tt_local_entry); 2039 2040 return orig_node; 2041 } 2042 2043 /** 2044 * batadv_tt_global_crc - calculates the checksum of the local table belonging 2045 * to the given orig_node 2046 * @bat_priv: the bat priv with all the soft interface information 2047 * @orig_node: originator for which the CRC should be computed 2048 * @vid: VLAN identifier for which the CRC32 has to be computed 2049 * 2050 * This function computes the checksum for the global table corresponding to a 2051 * specific originator. In particular, the checksum is computed as follows: For 2052 * each client connected to the originator the CRC32C of the MAC address and the 2053 * VID is computed and then all the CRC32Cs of the various clients are xor'ed 2054 * together. 2055 * 2056 * The idea behind is that CRC32C should be used as much as possible in order to 2057 * produce a unique hash of the table, but since the order which is used to feed 2058 * the CRC32C function affects the result and since every node in the network 2059 * probably sorts the clients differently, the hash function cannot be directly 2060 * computed over the entire table. Hence the CRC32C is used only on 2061 * the single client entry, while all the results are then xor'ed together 2062 * because the XOR operation can combine them all while trying to reduce the 2063 * noise as much as possible. 2064 * 2065 * Returns the checksum of the global table of a given originator. 2066 */ 2067 static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv, 2068 struct batadv_orig_node *orig_node, 2069 unsigned short vid) 2070 { 2071 struct batadv_hashtable *hash = bat_priv->tt.global_hash; 2072 struct batadv_tt_common_entry *tt_common; 2073 struct batadv_tt_global_entry *tt_global; 2074 struct hlist_head *head; 2075 uint32_t i, crc_tmp, crc = 0; 2076 uint8_t flags; 2077 __be16 tmp_vid; 2078 2079 for (i = 0; i < hash->size; i++) { 2080 head = &hash->table[i]; 2081 2082 rcu_read_lock(); 2083 hlist_for_each_entry_rcu(tt_common, head, hash_entry) { 2084 tt_global = container_of(tt_common, 2085 struct batadv_tt_global_entry, 2086 common); 2087 /* compute the CRC only for entries belonging to the 2088 * VLAN identified by the vid passed as parameter 2089 */ 2090 if (tt_common->vid != vid) 2091 continue; 2092 2093 /* Roaming clients are in the global table for 2094 * consistency only. They don't have to be 2095 * taken into account while computing the 2096 * global crc 2097 */ 2098 if (tt_common->flags & BATADV_TT_CLIENT_ROAM) 2099 continue; 2100 /* Temporary clients have not been announced yet, so 2101 * they have to be skipped while computing the global 2102 * crc 2103 */ 2104 if (tt_common->flags & BATADV_TT_CLIENT_TEMP) 2105 continue; 2106 2107 /* find out if this global entry is announced by this 2108 * originator 2109 */ 2110 if (!batadv_tt_global_entry_has_orig(tt_global, 2111 orig_node)) 2112 continue; 2113 2114 /* use network order to read the VID: this ensures that 2115 * every node reads the bytes in the same order. 2116 */ 2117 tmp_vid = htons(tt_common->vid); 2118 crc_tmp = crc32c(0, &tmp_vid, sizeof(tmp_vid)); 2119 2120 /* compute the CRC on flags that have to be kept in sync 2121 * among nodes 2122 */ 2123 flags = tt_common->flags & BATADV_TT_SYNC_MASK; 2124 crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags)); 2125 2126 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN); 2127 } 2128 rcu_read_unlock(); 2129 } 2130 2131 return crc; 2132 } 2133 2134 /** 2135 * batadv_tt_local_crc - calculates the checksum of the local table 2136 * @bat_priv: the bat priv with all the soft interface information 2137 * @vid: VLAN identifier for which the CRC32 has to be computed 2138 * 2139 * For details about the computation, please refer to the documentation for 2140 * batadv_tt_global_crc(). 2141 * 2142 * Returns the checksum of the local table 2143 */ 2144 static uint32_t batadv_tt_local_crc(struct batadv_priv *bat_priv, 2145 unsigned short vid) 2146 { 2147 struct batadv_hashtable *hash = bat_priv->tt.local_hash; 2148 struct batadv_tt_common_entry *tt_common; 2149 struct hlist_head *head; 2150 uint32_t i, crc_tmp, crc = 0; 2151 uint8_t flags; 2152 __be16 tmp_vid; 2153 2154 for (i = 0; i < hash->size; i++) { 2155 head = &hash->table[i]; 2156 2157 rcu_read_lock(); 2158 hlist_for_each_entry_rcu(tt_common, head, hash_entry) { 2159 /* compute the CRC only for entries belonging to the 2160 * VLAN identified by vid 2161 */ 2162 if (tt_common->vid != vid) 2163 continue; 2164 2165 /* not yet committed clients have not to be taken into 2166 * account while computing the CRC 2167 */ 2168 if (tt_common->flags & BATADV_TT_CLIENT_NEW) 2169 continue; 2170 2171 /* use network order to read the VID: this ensures that 2172 * every node reads the bytes in the same order. 2173 */ 2174 tmp_vid = htons(tt_common->vid); 2175 crc_tmp = crc32c(0, &tmp_vid, sizeof(tmp_vid)); 2176 2177 /* compute the CRC on flags that have to be kept in sync 2178 * among nodes 2179 */ 2180 flags = tt_common->flags & BATADV_TT_SYNC_MASK; 2181 crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags)); 2182 2183 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN); 2184 } 2185 rcu_read_unlock(); 2186 } 2187 2188 return crc; 2189 } 2190 2191 static void batadv_tt_req_list_free(struct batadv_priv *bat_priv) 2192 { 2193 struct batadv_tt_req_node *node, *safe; 2194 2195 spin_lock_bh(&bat_priv->tt.req_list_lock); 2196 2197 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { 2198 list_del(&node->list); 2199 kfree(node); 2200 } 2201 2202 spin_unlock_bh(&bat_priv->tt.req_list_lock); 2203 } 2204 2205 static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv, 2206 struct batadv_orig_node *orig_node, 2207 const void *tt_buff, 2208 uint16_t tt_buff_len) 2209 { 2210 /* Replace the old buffer only if I received something in the 2211 * last OGM (the OGM could carry no changes) 2212 */ 2213 spin_lock_bh(&orig_node->tt_buff_lock); 2214 if (tt_buff_len > 0) { 2215 kfree(orig_node->tt_buff); 2216 orig_node->tt_buff_len = 0; 2217 orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC); 2218 if (orig_node->tt_buff) { 2219 memcpy(orig_node->tt_buff, tt_buff, tt_buff_len); 2220 orig_node->tt_buff_len = tt_buff_len; 2221 } 2222 } 2223 spin_unlock_bh(&orig_node->tt_buff_lock); 2224 } 2225 2226 static void batadv_tt_req_purge(struct batadv_priv *bat_priv) 2227 { 2228 struct batadv_tt_req_node *node, *safe; 2229 2230 spin_lock_bh(&bat_priv->tt.req_list_lock); 2231 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { 2232 if (batadv_has_timed_out(node->issued_at, 2233 BATADV_TT_REQUEST_TIMEOUT)) { 2234 list_del(&node->list); 2235 kfree(node); 2236 } 2237 } 2238 spin_unlock_bh(&bat_priv->tt.req_list_lock); 2239 } 2240 2241 /* returns the pointer to the new tt_req_node struct if no request 2242 * has already been issued for this orig_node, NULL otherwise 2243 */ 2244 static struct batadv_tt_req_node * 2245 batadv_new_tt_req_node(struct batadv_priv *bat_priv, 2246 struct batadv_orig_node *orig_node) 2247 { 2248 struct batadv_tt_req_node *tt_req_node_tmp, *tt_req_node = NULL; 2249 2250 spin_lock_bh(&bat_priv->tt.req_list_lock); 2251 list_for_each_entry(tt_req_node_tmp, &bat_priv->tt.req_list, list) { 2252 if (batadv_compare_eth(tt_req_node_tmp, orig_node) && 2253 !batadv_has_timed_out(tt_req_node_tmp->issued_at, 2254 BATADV_TT_REQUEST_TIMEOUT)) 2255 goto unlock; 2256 } 2257 2258 tt_req_node = kmalloc(sizeof(*tt_req_node), GFP_ATOMIC); 2259 if (!tt_req_node) 2260 goto unlock; 2261 2262 ether_addr_copy(tt_req_node->addr, orig_node->orig); 2263 tt_req_node->issued_at = jiffies; 2264 2265 list_add(&tt_req_node->list, &bat_priv->tt.req_list); 2266 unlock: 2267 spin_unlock_bh(&bat_priv->tt.req_list_lock); 2268 return tt_req_node; 2269 } 2270 2271 /** 2272 * batadv_tt_local_valid - verify that given tt entry is a valid one 2273 * @entry_ptr: to be checked local tt entry 2274 * @data_ptr: not used but definition required to satisfy the callback prototype 2275 * 2276 * Returns 1 if the entry is a valid, 0 otherwise. 2277 */ 2278 static int batadv_tt_local_valid(const void *entry_ptr, const void *data_ptr) 2279 { 2280 const struct batadv_tt_common_entry *tt_common_entry = entry_ptr; 2281 2282 if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW) 2283 return 0; 2284 return 1; 2285 } 2286 2287 static int batadv_tt_global_valid(const void *entry_ptr, 2288 const void *data_ptr) 2289 { 2290 const struct batadv_tt_common_entry *tt_common_entry = entry_ptr; 2291 const struct batadv_tt_global_entry *tt_global_entry; 2292 const struct batadv_orig_node *orig_node = data_ptr; 2293 2294 if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM || 2295 tt_common_entry->flags & BATADV_TT_CLIENT_TEMP) 2296 return 0; 2297 2298 tt_global_entry = container_of(tt_common_entry, 2299 struct batadv_tt_global_entry, 2300 common); 2301 2302 return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node); 2303 } 2304 2305 /** 2306 * batadv_tt_tvlv_generate - fill the tvlv buff with the tt entries from the 2307 * specified tt hash 2308 * @bat_priv: the bat priv with all the soft interface information 2309 * @hash: hash table containing the tt entries 2310 * @tt_len: expected tvlv tt data buffer length in number of bytes 2311 * @tvlv_buff: pointer to the buffer to fill with the TT data 2312 * @valid_cb: function to filter tt change entries 2313 * @cb_data: data passed to the filter function as argument 2314 */ 2315 static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv, 2316 struct batadv_hashtable *hash, 2317 void *tvlv_buff, uint16_t tt_len, 2318 int (*valid_cb)(const void *, const void *), 2319 void *cb_data) 2320 { 2321 struct batadv_tt_common_entry *tt_common_entry; 2322 struct batadv_tvlv_tt_change *tt_change; 2323 struct hlist_head *head; 2324 uint16_t tt_tot, tt_num_entries = 0; 2325 uint32_t i; 2326 2327 tt_tot = batadv_tt_entries(tt_len); 2328 tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff; 2329 2330 rcu_read_lock(); 2331 for (i = 0; i < hash->size; i++) { 2332 head = &hash->table[i]; 2333 2334 hlist_for_each_entry_rcu(tt_common_entry, 2335 head, hash_entry) { 2336 if (tt_tot == tt_num_entries) 2337 break; 2338 2339 if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data))) 2340 continue; 2341 2342 ether_addr_copy(tt_change->addr, tt_common_entry->addr); 2343 tt_change->flags = tt_common_entry->flags; 2344 tt_change->vid = htons(tt_common_entry->vid); 2345 memset(tt_change->reserved, 0, 2346 sizeof(tt_change->reserved)); 2347 2348 tt_num_entries++; 2349 tt_change++; 2350 } 2351 } 2352 rcu_read_unlock(); 2353 } 2354 2355 /** 2356 * batadv_tt_global_check_crc - check if all the CRCs are correct 2357 * @orig_node: originator for which the CRCs have to be checked 2358 * @tt_vlan: pointer to the first tvlv VLAN entry 2359 * @num_vlan: number of tvlv VLAN entries 2360 * @create: if true, create VLAN objects if not found 2361 * 2362 * Return true if all the received CRCs match the locally stored ones, false 2363 * otherwise 2364 */ 2365 static bool batadv_tt_global_check_crc(struct batadv_orig_node *orig_node, 2366 struct batadv_tvlv_tt_vlan_data *tt_vlan, 2367 uint16_t num_vlan) 2368 { 2369 struct batadv_tvlv_tt_vlan_data *tt_vlan_tmp; 2370 struct batadv_orig_node_vlan *vlan; 2371 uint32_t crc; 2372 int i; 2373 2374 /* check if each received CRC matches the locally stored one */ 2375 for (i = 0; i < num_vlan; i++) { 2376 tt_vlan_tmp = tt_vlan + i; 2377 2378 /* if orig_node is a backbone node for this VLAN, don't check 2379 * the CRC as we ignore all the global entries over it 2380 */ 2381 if (batadv_bla_is_backbone_gw_orig(orig_node->bat_priv, 2382 orig_node->orig, 2383 ntohs(tt_vlan_tmp->vid))) 2384 continue; 2385 2386 vlan = batadv_orig_node_vlan_get(orig_node, 2387 ntohs(tt_vlan_tmp->vid)); 2388 if (!vlan) 2389 return false; 2390 2391 crc = vlan->tt.crc; 2392 batadv_orig_node_vlan_free_ref(vlan); 2393 2394 if (crc != ntohl(tt_vlan_tmp->crc)) 2395 return false; 2396 } 2397 2398 return true; 2399 } 2400 2401 /** 2402 * batadv_tt_local_update_crc - update all the local CRCs 2403 * @bat_priv: the bat priv with all the soft interface information 2404 */ 2405 static void batadv_tt_local_update_crc(struct batadv_priv *bat_priv) 2406 { 2407 struct batadv_softif_vlan *vlan; 2408 2409 /* recompute the global CRC for each VLAN */ 2410 rcu_read_lock(); 2411 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { 2412 vlan->tt.crc = batadv_tt_local_crc(bat_priv, vlan->vid); 2413 } 2414 rcu_read_unlock(); 2415 } 2416 2417 /** 2418 * batadv_tt_global_update_crc - update all the global CRCs for this orig_node 2419 * @bat_priv: the bat priv with all the soft interface information 2420 * @orig_node: the orig_node for which the CRCs have to be updated 2421 */ 2422 static void batadv_tt_global_update_crc(struct batadv_priv *bat_priv, 2423 struct batadv_orig_node *orig_node) 2424 { 2425 struct batadv_orig_node_vlan *vlan; 2426 uint32_t crc; 2427 2428 /* recompute the global CRC for each VLAN */ 2429 rcu_read_lock(); 2430 list_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) { 2431 /* if orig_node is a backbone node for this VLAN, don't compute 2432 * the CRC as we ignore all the global entries over it 2433 */ 2434 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, 2435 vlan->vid)) 2436 continue; 2437 2438 crc = batadv_tt_global_crc(bat_priv, orig_node, vlan->vid); 2439 vlan->tt.crc = crc; 2440 } 2441 rcu_read_unlock(); 2442 } 2443 2444 /** 2445 * batadv_send_tt_request - send a TT Request message to a given node 2446 * @bat_priv: the bat priv with all the soft interface information 2447 * @dst_orig_node: the destination of the message 2448 * @ttvn: the version number that the source of the message is looking for 2449 * @tt_vlan: pointer to the first tvlv VLAN object to request 2450 * @num_vlan: number of tvlv VLAN entries 2451 * @full_table: ask for the entire translation table if true, while only for the 2452 * last TT diff otherwise 2453 */ 2454 static int batadv_send_tt_request(struct batadv_priv *bat_priv, 2455 struct batadv_orig_node *dst_orig_node, 2456 uint8_t ttvn, 2457 struct batadv_tvlv_tt_vlan_data *tt_vlan, 2458 uint16_t num_vlan, bool full_table) 2459 { 2460 struct batadv_tvlv_tt_data *tvlv_tt_data = NULL; 2461 struct batadv_tt_req_node *tt_req_node = NULL; 2462 struct batadv_tvlv_tt_vlan_data *tt_vlan_req; 2463 struct batadv_hard_iface *primary_if; 2464 bool ret = false; 2465 int i, size; 2466 2467 primary_if = batadv_primary_if_get_selected(bat_priv); 2468 if (!primary_if) 2469 goto out; 2470 2471 /* The new tt_req will be issued only if I'm not waiting for a 2472 * reply from the same orig_node yet 2473 */ 2474 tt_req_node = batadv_new_tt_req_node(bat_priv, dst_orig_node); 2475 if (!tt_req_node) 2476 goto out; 2477 2478 size = sizeof(*tvlv_tt_data) + sizeof(*tt_vlan_req) * num_vlan; 2479 tvlv_tt_data = kzalloc(size, GFP_ATOMIC); 2480 if (!tvlv_tt_data) 2481 goto out; 2482 2483 tvlv_tt_data->flags = BATADV_TT_REQUEST; 2484 tvlv_tt_data->ttvn = ttvn; 2485 tvlv_tt_data->num_vlan = htons(num_vlan); 2486 2487 /* send all the CRCs within the request. This is needed by intermediate 2488 * nodes to ensure they have the correct table before replying 2489 */ 2490 tt_vlan_req = (struct batadv_tvlv_tt_vlan_data *)(tvlv_tt_data + 1); 2491 for (i = 0; i < num_vlan; i++) { 2492 tt_vlan_req->vid = tt_vlan->vid; 2493 tt_vlan_req->crc = tt_vlan->crc; 2494 2495 tt_vlan_req++; 2496 tt_vlan++; 2497 } 2498 2499 if (full_table) 2500 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE; 2501 2502 batadv_dbg(BATADV_DBG_TT, bat_priv, "Sending TT_REQUEST to %pM [%c]\n", 2503 dst_orig_node->orig, full_table ? 'F' : '.'); 2504 2505 batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX); 2506 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr, 2507 dst_orig_node->orig, BATADV_TVLV_TT, 1, 2508 tvlv_tt_data, size); 2509 ret = true; 2510 2511 out: 2512 if (primary_if) 2513 batadv_hardif_free_ref(primary_if); 2514 if (ret && tt_req_node) { 2515 spin_lock_bh(&bat_priv->tt.req_list_lock); 2516 list_del(&tt_req_node->list); 2517 spin_unlock_bh(&bat_priv->tt.req_list_lock); 2518 kfree(tt_req_node); 2519 } 2520 kfree(tvlv_tt_data); 2521 return ret; 2522 } 2523 2524 /** 2525 * batadv_send_other_tt_response - send reply to tt request concerning another 2526 * node's translation table 2527 * @bat_priv: the bat priv with all the soft interface information 2528 * @tt_data: tt data containing the tt request information 2529 * @req_src: mac address of tt request sender 2530 * @req_dst: mac address of tt request recipient 2531 * 2532 * Returns true if tt request reply was sent, false otherwise. 2533 */ 2534 static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv, 2535 struct batadv_tvlv_tt_data *tt_data, 2536 uint8_t *req_src, uint8_t *req_dst) 2537 { 2538 struct batadv_orig_node *req_dst_orig_node; 2539 struct batadv_orig_node *res_dst_orig_node = NULL; 2540 struct batadv_tvlv_tt_change *tt_change; 2541 struct batadv_tvlv_tt_data *tvlv_tt_data = NULL; 2542 struct batadv_tvlv_tt_vlan_data *tt_vlan; 2543 bool ret = false, full_table; 2544 uint8_t orig_ttvn, req_ttvn; 2545 uint16_t tvlv_len; 2546 int32_t tt_len; 2547 2548 batadv_dbg(BATADV_DBG_TT, bat_priv, 2549 "Received TT_REQUEST from %pM for ttvn: %u (%pM) [%c]\n", 2550 req_src, tt_data->ttvn, req_dst, 2551 ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.')); 2552 2553 /* Let's get the orig node of the REAL destination */ 2554 req_dst_orig_node = batadv_orig_hash_find(bat_priv, req_dst); 2555 if (!req_dst_orig_node) 2556 goto out; 2557 2558 res_dst_orig_node = batadv_orig_hash_find(bat_priv, req_src); 2559 if (!res_dst_orig_node) 2560 goto out; 2561 2562 orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn); 2563 req_ttvn = tt_data->ttvn; 2564 2565 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(tt_data + 1); 2566 /* this node doesn't have the requested data */ 2567 if (orig_ttvn != req_ttvn || 2568 !batadv_tt_global_check_crc(req_dst_orig_node, tt_vlan, 2569 ntohs(tt_data->num_vlan))) 2570 goto out; 2571 2572 /* If the full table has been explicitly requested */ 2573 if (tt_data->flags & BATADV_TT_FULL_TABLE || 2574 !req_dst_orig_node->tt_buff) 2575 full_table = true; 2576 else 2577 full_table = false; 2578 2579 /* TT fragmentation hasn't been implemented yet, so send as many 2580 * TT entries fit a single packet as possible only 2581 */ 2582 if (!full_table) { 2583 spin_lock_bh(&req_dst_orig_node->tt_buff_lock); 2584 tt_len = req_dst_orig_node->tt_buff_len; 2585 2586 tvlv_len = batadv_tt_prepare_tvlv_global_data(req_dst_orig_node, 2587 &tvlv_tt_data, 2588 &tt_change, 2589 &tt_len); 2590 if (!tt_len) 2591 goto unlock; 2592 2593 /* Copy the last orig_node's OGM buffer */ 2594 memcpy(tt_change, req_dst_orig_node->tt_buff, 2595 req_dst_orig_node->tt_buff_len); 2596 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); 2597 } else { 2598 /* allocate the tvlv, put the tt_data and all the tt_vlan_data 2599 * in the initial part 2600 */ 2601 tt_len = -1; 2602 tvlv_len = batadv_tt_prepare_tvlv_global_data(req_dst_orig_node, 2603 &tvlv_tt_data, 2604 &tt_change, 2605 &tt_len); 2606 if (!tt_len) 2607 goto out; 2608 2609 /* fill the rest of the tvlv with the real TT entries */ 2610 batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.global_hash, 2611 tt_change, tt_len, 2612 batadv_tt_global_valid, 2613 req_dst_orig_node); 2614 } 2615 2616 /* Don't send the response, if larger than fragmented packet. */ 2617 tt_len = sizeof(struct batadv_unicast_tvlv_packet) + tvlv_len; 2618 if (tt_len > atomic_read(&bat_priv->packet_size_max)) { 2619 net_ratelimited_function(batadv_info, bat_priv->soft_iface, 2620 "Ignoring TT_REQUEST from %pM; Response size exceeds max packet size.\n", 2621 res_dst_orig_node->orig); 2622 goto out; 2623 } 2624 2625 tvlv_tt_data->flags = BATADV_TT_RESPONSE; 2626 tvlv_tt_data->ttvn = req_ttvn; 2627 2628 if (full_table) 2629 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE; 2630 2631 batadv_dbg(BATADV_DBG_TT, bat_priv, 2632 "Sending TT_RESPONSE %pM for %pM [%c] (ttvn: %u)\n", 2633 res_dst_orig_node->orig, req_dst_orig_node->orig, 2634 full_table ? 'F' : '.', req_ttvn); 2635 2636 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX); 2637 2638 batadv_tvlv_unicast_send(bat_priv, req_dst_orig_node->orig, 2639 req_src, BATADV_TVLV_TT, 1, tvlv_tt_data, 2640 tvlv_len); 2641 2642 ret = true; 2643 goto out; 2644 2645 unlock: 2646 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); 2647 2648 out: 2649 if (res_dst_orig_node) 2650 batadv_orig_node_free_ref(res_dst_orig_node); 2651 if (req_dst_orig_node) 2652 batadv_orig_node_free_ref(req_dst_orig_node); 2653 kfree(tvlv_tt_data); 2654 return ret; 2655 } 2656 2657 /** 2658 * batadv_send_my_tt_response - send reply to tt request concerning this node's 2659 * translation table 2660 * @bat_priv: the bat priv with all the soft interface information 2661 * @tt_data: tt data containing the tt request information 2662 * @req_src: mac address of tt request sender 2663 * 2664 * Returns true if tt request reply was sent, false otherwise. 2665 */ 2666 static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv, 2667 struct batadv_tvlv_tt_data *tt_data, 2668 uint8_t *req_src) 2669 { 2670 struct batadv_tvlv_tt_data *tvlv_tt_data = NULL; 2671 struct batadv_hard_iface *primary_if = NULL; 2672 struct batadv_tvlv_tt_change *tt_change; 2673 struct batadv_orig_node *orig_node; 2674 uint8_t my_ttvn, req_ttvn; 2675 uint16_t tvlv_len; 2676 bool full_table; 2677 int32_t tt_len; 2678 2679 batadv_dbg(BATADV_DBG_TT, bat_priv, 2680 "Received TT_REQUEST from %pM for ttvn: %u (me) [%c]\n", 2681 req_src, tt_data->ttvn, 2682 ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.')); 2683 2684 spin_lock_bh(&bat_priv->tt.commit_lock); 2685 2686 my_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); 2687 req_ttvn = tt_data->ttvn; 2688 2689 orig_node = batadv_orig_hash_find(bat_priv, req_src); 2690 if (!orig_node) 2691 goto out; 2692 2693 primary_if = batadv_primary_if_get_selected(bat_priv); 2694 if (!primary_if) 2695 goto out; 2696 2697 /* If the full table has been explicitly requested or the gap 2698 * is too big send the whole local translation table 2699 */ 2700 if (tt_data->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn || 2701 !bat_priv->tt.last_changeset) 2702 full_table = true; 2703 else 2704 full_table = false; 2705 2706 /* TT fragmentation hasn't been implemented yet, so send as many 2707 * TT entries fit a single packet as possible only 2708 */ 2709 if (!full_table) { 2710 spin_lock_bh(&bat_priv->tt.last_changeset_lock); 2711 2712 tt_len = bat_priv->tt.last_changeset_len; 2713 tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv, 2714 &tvlv_tt_data, 2715 &tt_change, 2716 &tt_len); 2717 if (!tt_len) 2718 goto unlock; 2719 2720 /* Copy the last orig_node's OGM buffer */ 2721 memcpy(tt_change, bat_priv->tt.last_changeset, 2722 bat_priv->tt.last_changeset_len); 2723 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); 2724 } else { 2725 req_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); 2726 2727 /* allocate the tvlv, put the tt_data and all the tt_vlan_data 2728 * in the initial part 2729 */ 2730 tt_len = -1; 2731 tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv, 2732 &tvlv_tt_data, 2733 &tt_change, 2734 &tt_len); 2735 if (!tt_len) 2736 goto out; 2737 2738 /* fill the rest of the tvlv with the real TT entries */ 2739 batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.local_hash, 2740 tt_change, tt_len, 2741 batadv_tt_local_valid, NULL); 2742 } 2743 2744 tvlv_tt_data->flags = BATADV_TT_RESPONSE; 2745 tvlv_tt_data->ttvn = req_ttvn; 2746 2747 if (full_table) 2748 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE; 2749 2750 batadv_dbg(BATADV_DBG_TT, bat_priv, 2751 "Sending TT_RESPONSE to %pM [%c] (ttvn: %u)\n", 2752 orig_node->orig, full_table ? 'F' : '.', req_ttvn); 2753 2754 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX); 2755 2756 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr, 2757 req_src, BATADV_TVLV_TT, 1, tvlv_tt_data, 2758 tvlv_len); 2759 2760 goto out; 2761 2762 unlock: 2763 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); 2764 out: 2765 spin_unlock_bh(&bat_priv->tt.commit_lock); 2766 if (orig_node) 2767 batadv_orig_node_free_ref(orig_node); 2768 if (primary_if) 2769 batadv_hardif_free_ref(primary_if); 2770 kfree(tvlv_tt_data); 2771 /* The packet was for this host, so it doesn't need to be re-routed */ 2772 return true; 2773 } 2774 2775 /** 2776 * batadv_send_tt_response - send reply to tt request 2777 * @bat_priv: the bat priv with all the soft interface information 2778 * @tt_data: tt data containing the tt request information 2779 * @req_src: mac address of tt request sender 2780 * @req_dst: mac address of tt request recipient 2781 * 2782 * Returns true if tt request reply was sent, false otherwise. 2783 */ 2784 static bool batadv_send_tt_response(struct batadv_priv *bat_priv, 2785 struct batadv_tvlv_tt_data *tt_data, 2786 uint8_t *req_src, uint8_t *req_dst) 2787 { 2788 if (batadv_is_my_mac(bat_priv, req_dst)) 2789 return batadv_send_my_tt_response(bat_priv, tt_data, req_src); 2790 return batadv_send_other_tt_response(bat_priv, tt_data, req_src, 2791 req_dst); 2792 } 2793 2794 static void _batadv_tt_update_changes(struct batadv_priv *bat_priv, 2795 struct batadv_orig_node *orig_node, 2796 struct batadv_tvlv_tt_change *tt_change, 2797 uint16_t tt_num_changes, uint8_t ttvn) 2798 { 2799 int i; 2800 int roams; 2801 2802 for (i = 0; i < tt_num_changes; i++) { 2803 if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) { 2804 roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM; 2805 batadv_tt_global_del(bat_priv, orig_node, 2806 (tt_change + i)->addr, 2807 ntohs((tt_change + i)->vid), 2808 "tt removed by changes", 2809 roams); 2810 } else { 2811 if (!batadv_tt_global_add(bat_priv, orig_node, 2812 (tt_change + i)->addr, 2813 ntohs((tt_change + i)->vid), 2814 (tt_change + i)->flags, ttvn)) 2815 /* In case of problem while storing a 2816 * global_entry, we stop the updating 2817 * procedure without committing the 2818 * ttvn change. This will avoid to send 2819 * corrupted data on tt_request 2820 */ 2821 return; 2822 } 2823 } 2824 orig_node->capa_initialized |= BATADV_ORIG_CAPA_HAS_TT; 2825 } 2826 2827 static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv, 2828 struct batadv_tvlv_tt_change *tt_change, 2829 uint8_t ttvn, uint8_t *resp_src, 2830 uint16_t num_entries) 2831 { 2832 struct batadv_orig_node *orig_node; 2833 2834 orig_node = batadv_orig_hash_find(bat_priv, resp_src); 2835 if (!orig_node) 2836 goto out; 2837 2838 /* Purge the old table first.. */ 2839 batadv_tt_global_del_orig(bat_priv, orig_node, -1, 2840 "Received full table"); 2841 2842 _batadv_tt_update_changes(bat_priv, orig_node, tt_change, num_entries, 2843 ttvn); 2844 2845 spin_lock_bh(&orig_node->tt_buff_lock); 2846 kfree(orig_node->tt_buff); 2847 orig_node->tt_buff_len = 0; 2848 orig_node->tt_buff = NULL; 2849 spin_unlock_bh(&orig_node->tt_buff_lock); 2850 2851 atomic_set(&orig_node->last_ttvn, ttvn); 2852 2853 out: 2854 if (orig_node) 2855 batadv_orig_node_free_ref(orig_node); 2856 } 2857 2858 static void batadv_tt_update_changes(struct batadv_priv *bat_priv, 2859 struct batadv_orig_node *orig_node, 2860 uint16_t tt_num_changes, uint8_t ttvn, 2861 struct batadv_tvlv_tt_change *tt_change) 2862 { 2863 _batadv_tt_update_changes(bat_priv, orig_node, tt_change, 2864 tt_num_changes, ttvn); 2865 2866 batadv_tt_save_orig_buffer(bat_priv, orig_node, tt_change, 2867 batadv_tt_len(tt_num_changes)); 2868 atomic_set(&orig_node->last_ttvn, ttvn); 2869 } 2870 2871 /** 2872 * batadv_is_my_client - check if a client is served by the local node 2873 * @bat_priv: the bat priv with all the soft interface information 2874 * @addr: the mac address of the client to check 2875 * @vid: VLAN identifier 2876 * 2877 * Returns true if the client is served by this node, false otherwise. 2878 */ 2879 bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr, 2880 unsigned short vid) 2881 { 2882 struct batadv_tt_local_entry *tt_local_entry; 2883 bool ret = false; 2884 2885 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid); 2886 if (!tt_local_entry) 2887 goto out; 2888 /* Check if the client has been logically deleted (but is kept for 2889 * consistency purpose) 2890 */ 2891 if ((tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) || 2892 (tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM)) 2893 goto out; 2894 ret = true; 2895 out: 2896 if (tt_local_entry) 2897 batadv_tt_local_entry_free_ref(tt_local_entry); 2898 return ret; 2899 } 2900 2901 /** 2902 * batadv_handle_tt_response - process incoming tt reply 2903 * @bat_priv: the bat priv with all the soft interface information 2904 * @tt_data: tt data containing the tt request information 2905 * @resp_src: mac address of tt reply sender 2906 * @num_entries: number of tt change entries appended to the tt data 2907 */ 2908 static void batadv_handle_tt_response(struct batadv_priv *bat_priv, 2909 struct batadv_tvlv_tt_data *tt_data, 2910 uint8_t *resp_src, uint16_t num_entries) 2911 { 2912 struct batadv_tt_req_node *node, *safe; 2913 struct batadv_orig_node *orig_node = NULL; 2914 struct batadv_tvlv_tt_change *tt_change; 2915 uint8_t *tvlv_ptr = (uint8_t *)tt_data; 2916 uint16_t change_offset; 2917 2918 batadv_dbg(BATADV_DBG_TT, bat_priv, 2919 "Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n", 2920 resp_src, tt_data->ttvn, num_entries, 2921 ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.')); 2922 2923 orig_node = batadv_orig_hash_find(bat_priv, resp_src); 2924 if (!orig_node) 2925 goto out; 2926 2927 spin_lock_bh(&orig_node->tt_lock); 2928 2929 change_offset = sizeof(struct batadv_tvlv_tt_vlan_data); 2930 change_offset *= ntohs(tt_data->num_vlan); 2931 change_offset += sizeof(*tt_data); 2932 tvlv_ptr += change_offset; 2933 2934 tt_change = (struct batadv_tvlv_tt_change *)tvlv_ptr; 2935 if (tt_data->flags & BATADV_TT_FULL_TABLE) { 2936 batadv_tt_fill_gtable(bat_priv, tt_change, tt_data->ttvn, 2937 resp_src, num_entries); 2938 } else { 2939 batadv_tt_update_changes(bat_priv, orig_node, num_entries, 2940 tt_data->ttvn, tt_change); 2941 } 2942 2943 /* Recalculate the CRC for this orig_node and store it */ 2944 batadv_tt_global_update_crc(bat_priv, orig_node); 2945 2946 spin_unlock_bh(&orig_node->tt_lock); 2947 2948 /* Delete the tt_req_node from pending tt_requests list */ 2949 spin_lock_bh(&bat_priv->tt.req_list_lock); 2950 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { 2951 if (!batadv_compare_eth(node->addr, resp_src)) 2952 continue; 2953 list_del(&node->list); 2954 kfree(node); 2955 } 2956 2957 spin_unlock_bh(&bat_priv->tt.req_list_lock); 2958 out: 2959 if (orig_node) 2960 batadv_orig_node_free_ref(orig_node); 2961 } 2962 2963 static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv) 2964 { 2965 struct batadv_tt_roam_node *node, *safe; 2966 2967 spin_lock_bh(&bat_priv->tt.roam_list_lock); 2968 2969 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { 2970 list_del(&node->list); 2971 kfree(node); 2972 } 2973 2974 spin_unlock_bh(&bat_priv->tt.roam_list_lock); 2975 } 2976 2977 static void batadv_tt_roam_purge(struct batadv_priv *bat_priv) 2978 { 2979 struct batadv_tt_roam_node *node, *safe; 2980 2981 spin_lock_bh(&bat_priv->tt.roam_list_lock); 2982 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { 2983 if (!batadv_has_timed_out(node->first_time, 2984 BATADV_ROAMING_MAX_TIME)) 2985 continue; 2986 2987 list_del(&node->list); 2988 kfree(node); 2989 } 2990 spin_unlock_bh(&bat_priv->tt.roam_list_lock); 2991 } 2992 2993 /* This function checks whether the client already reached the 2994 * maximum number of possible roaming phases. In this case the ROAMING_ADV 2995 * will not be sent. 2996 * 2997 * returns true if the ROAMING_ADV can be sent, false otherwise 2998 */ 2999 static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv, 3000 uint8_t *client) 3001 { 3002 struct batadv_tt_roam_node *tt_roam_node; 3003 bool ret = false; 3004 3005 spin_lock_bh(&bat_priv->tt.roam_list_lock); 3006 /* The new tt_req will be issued only if I'm not waiting for a 3007 * reply from the same orig_node yet 3008 */ 3009 list_for_each_entry(tt_roam_node, &bat_priv->tt.roam_list, list) { 3010 if (!batadv_compare_eth(tt_roam_node->addr, client)) 3011 continue; 3012 3013 if (batadv_has_timed_out(tt_roam_node->first_time, 3014 BATADV_ROAMING_MAX_TIME)) 3015 continue; 3016 3017 if (!batadv_atomic_dec_not_zero(&tt_roam_node->counter)) 3018 /* Sorry, you roamed too many times! */ 3019 goto unlock; 3020 ret = true; 3021 break; 3022 } 3023 3024 if (!ret) { 3025 tt_roam_node = kmalloc(sizeof(*tt_roam_node), GFP_ATOMIC); 3026 if (!tt_roam_node) 3027 goto unlock; 3028 3029 tt_roam_node->first_time = jiffies; 3030 atomic_set(&tt_roam_node->counter, 3031 BATADV_ROAMING_MAX_COUNT - 1); 3032 ether_addr_copy(tt_roam_node->addr, client); 3033 3034 list_add(&tt_roam_node->list, &bat_priv->tt.roam_list); 3035 ret = true; 3036 } 3037 3038 unlock: 3039 spin_unlock_bh(&bat_priv->tt.roam_list_lock); 3040 return ret; 3041 } 3042 3043 /** 3044 * batadv_send_roam_adv - send a roaming advertisement message 3045 * @bat_priv: the bat priv with all the soft interface information 3046 * @client: mac address of the roaming client 3047 * @vid: VLAN identifier 3048 * @orig_node: message destination 3049 * 3050 * Send a ROAMING_ADV message to the node which was previously serving this 3051 * client. This is done to inform the node that from now on all traffic destined 3052 * for this particular roamed client has to be forwarded to the sender of the 3053 * roaming message. 3054 */ 3055 static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, 3056 unsigned short vid, 3057 struct batadv_orig_node *orig_node) 3058 { 3059 struct batadv_hard_iface *primary_if; 3060 struct batadv_tvlv_roam_adv tvlv_roam; 3061 3062 primary_if = batadv_primary_if_get_selected(bat_priv); 3063 if (!primary_if) 3064 goto out; 3065 3066 /* before going on we have to check whether the client has 3067 * already roamed to us too many times 3068 */ 3069 if (!batadv_tt_check_roam_count(bat_priv, client)) 3070 goto out; 3071 3072 batadv_dbg(BATADV_DBG_TT, bat_priv, 3073 "Sending ROAMING_ADV to %pM (client %pM, vid: %d)\n", 3074 orig_node->orig, client, BATADV_PRINT_VID(vid)); 3075 3076 batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX); 3077 3078 memcpy(tvlv_roam.client, client, sizeof(tvlv_roam.client)); 3079 tvlv_roam.vid = htons(vid); 3080 3081 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr, 3082 orig_node->orig, BATADV_TVLV_ROAM, 1, 3083 &tvlv_roam, sizeof(tvlv_roam)); 3084 3085 out: 3086 if (primary_if) 3087 batadv_hardif_free_ref(primary_if); 3088 } 3089 3090 static void batadv_tt_purge(struct work_struct *work) 3091 { 3092 struct delayed_work *delayed_work; 3093 struct batadv_priv_tt *priv_tt; 3094 struct batadv_priv *bat_priv; 3095 3096 delayed_work = container_of(work, struct delayed_work, work); 3097 priv_tt = container_of(delayed_work, struct batadv_priv_tt, work); 3098 bat_priv = container_of(priv_tt, struct batadv_priv, tt); 3099 3100 batadv_tt_local_purge(bat_priv, BATADV_TT_LOCAL_TIMEOUT); 3101 batadv_tt_global_purge(bat_priv); 3102 batadv_tt_req_purge(bat_priv); 3103 batadv_tt_roam_purge(bat_priv); 3104 3105 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work, 3106 msecs_to_jiffies(BATADV_TT_WORK_PERIOD)); 3107 } 3108 3109 void batadv_tt_free(struct batadv_priv *bat_priv) 3110 { 3111 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_TT, 1); 3112 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_TT, 1); 3113 3114 cancel_delayed_work_sync(&bat_priv->tt.work); 3115 3116 batadv_tt_local_table_free(bat_priv); 3117 batadv_tt_global_table_free(bat_priv); 3118 batadv_tt_req_list_free(bat_priv); 3119 batadv_tt_changes_list_free(bat_priv); 3120 batadv_tt_roam_list_free(bat_priv); 3121 3122 kfree(bat_priv->tt.last_changeset); 3123 } 3124 3125 /** 3126 * batadv_tt_local_set_flags - set or unset the specified flags on the local 3127 * table and possibly count them in the TT size 3128 * @bat_priv: the bat priv with all the soft interface information 3129 * @flags: the flag to switch 3130 * @enable: whether to set or unset the flag 3131 * @count: whether to increase the TT size by the number of changed entries 3132 */ 3133 static void batadv_tt_local_set_flags(struct batadv_priv *bat_priv, 3134 uint16_t flags, bool enable, bool count) 3135 { 3136 struct batadv_hashtable *hash = bat_priv->tt.local_hash; 3137 struct batadv_tt_common_entry *tt_common_entry; 3138 uint16_t changed_num = 0; 3139 struct hlist_head *head; 3140 uint32_t i; 3141 3142 if (!hash) 3143 return; 3144 3145 for (i = 0; i < hash->size; i++) { 3146 head = &hash->table[i]; 3147 3148 rcu_read_lock(); 3149 hlist_for_each_entry_rcu(tt_common_entry, 3150 head, hash_entry) { 3151 if (enable) { 3152 if ((tt_common_entry->flags & flags) == flags) 3153 continue; 3154 tt_common_entry->flags |= flags; 3155 } else { 3156 if (!(tt_common_entry->flags & flags)) 3157 continue; 3158 tt_common_entry->flags &= ~flags; 3159 } 3160 changed_num++; 3161 3162 if (!count) 3163 continue; 3164 3165 batadv_tt_local_size_inc(bat_priv, 3166 tt_common_entry->vid); 3167 } 3168 rcu_read_unlock(); 3169 } 3170 } 3171 3172 /* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */ 3173 static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) 3174 { 3175 struct batadv_hashtable *hash = bat_priv->tt.local_hash; 3176 struct batadv_tt_common_entry *tt_common; 3177 struct batadv_tt_local_entry *tt_local; 3178 struct batadv_softif_vlan *vlan; 3179 struct hlist_node *node_tmp; 3180 struct hlist_head *head; 3181 spinlock_t *list_lock; /* protects write access to the hash lists */ 3182 uint32_t i; 3183 3184 if (!hash) 3185 return; 3186 3187 for (i = 0; i < hash->size; i++) { 3188 head = &hash->table[i]; 3189 list_lock = &hash->list_locks[i]; 3190 3191 spin_lock_bh(list_lock); 3192 hlist_for_each_entry_safe(tt_common, node_tmp, head, 3193 hash_entry) { 3194 if (!(tt_common->flags & BATADV_TT_CLIENT_PENDING)) 3195 continue; 3196 3197 batadv_dbg(BATADV_DBG_TT, bat_priv, 3198 "Deleting local tt entry (%pM, vid: %d): pending\n", 3199 tt_common->addr, 3200 BATADV_PRINT_VID(tt_common->vid)); 3201 3202 batadv_tt_local_size_dec(bat_priv, tt_common->vid); 3203 hlist_del_rcu(&tt_common->hash_entry); 3204 tt_local = container_of(tt_common, 3205 struct batadv_tt_local_entry, 3206 common); 3207 3208 /* decrease the reference held for this vlan */ 3209 vlan = batadv_softif_vlan_get(bat_priv, tt_common->vid); 3210 batadv_softif_vlan_free_ref(vlan); 3211 batadv_softif_vlan_free_ref(vlan); 3212 3213 batadv_tt_local_entry_free_ref(tt_local); 3214 } 3215 spin_unlock_bh(list_lock); 3216 } 3217 } 3218 3219 /** 3220 * batadv_tt_local_commit_changes_nolock - commit all pending local tt changes 3221 * which have been queued in the time since the last commit 3222 * @bat_priv: the bat priv with all the soft interface information 3223 * 3224 * Caller must hold tt->commit_lock. 3225 */ 3226 static void batadv_tt_local_commit_changes_nolock(struct batadv_priv *bat_priv) 3227 { 3228 /* Update multicast addresses in local translation table */ 3229 batadv_mcast_mla_update(bat_priv); 3230 3231 if (atomic_read(&bat_priv->tt.local_changes) < 1) { 3232 if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt)) 3233 batadv_tt_tvlv_container_update(bat_priv); 3234 return; 3235 } 3236 3237 batadv_tt_local_set_flags(bat_priv, BATADV_TT_CLIENT_NEW, false, true); 3238 3239 batadv_tt_local_purge_pending_clients(bat_priv); 3240 batadv_tt_local_update_crc(bat_priv); 3241 3242 /* Increment the TTVN only once per OGM interval */ 3243 atomic_inc(&bat_priv->tt.vn); 3244 batadv_dbg(BATADV_DBG_TT, bat_priv, 3245 "Local changes committed, updating to ttvn %u\n", 3246 (uint8_t)atomic_read(&bat_priv->tt.vn)); 3247 3248 /* reset the sending counter */ 3249 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); 3250 batadv_tt_tvlv_container_update(bat_priv); 3251 } 3252 3253 /** 3254 * batadv_tt_local_commit_changes - commit all pending local tt changes which 3255 * have been queued in the time since the last commit 3256 * @bat_priv: the bat priv with all the soft interface information 3257 */ 3258 void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv) 3259 { 3260 spin_lock_bh(&bat_priv->tt.commit_lock); 3261 batadv_tt_local_commit_changes_nolock(bat_priv); 3262 spin_unlock_bh(&bat_priv->tt.commit_lock); 3263 } 3264 3265 bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src, 3266 uint8_t *dst, unsigned short vid) 3267 { 3268 struct batadv_tt_local_entry *tt_local_entry = NULL; 3269 struct batadv_tt_global_entry *tt_global_entry = NULL; 3270 struct batadv_softif_vlan *vlan; 3271 bool ret = false; 3272 3273 vlan = batadv_softif_vlan_get(bat_priv, vid); 3274 if (!vlan || !atomic_read(&vlan->ap_isolation)) 3275 goto out; 3276 3277 tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst, vid); 3278 if (!tt_local_entry) 3279 goto out; 3280 3281 tt_global_entry = batadv_tt_global_hash_find(bat_priv, src, vid); 3282 if (!tt_global_entry) 3283 goto out; 3284 3285 if (!_batadv_is_ap_isolated(tt_local_entry, tt_global_entry)) 3286 goto out; 3287 3288 ret = true; 3289 3290 out: 3291 if (vlan) 3292 batadv_softif_vlan_free_ref(vlan); 3293 if (tt_global_entry) 3294 batadv_tt_global_entry_free_ref(tt_global_entry); 3295 if (tt_local_entry) 3296 batadv_tt_local_entry_free_ref(tt_local_entry); 3297 return ret; 3298 } 3299 3300 /** 3301 * batadv_tt_update_orig - update global translation table with new tt 3302 * information received via ogms 3303 * @bat_priv: the bat priv with all the soft interface information 3304 * @orig: the orig_node of the ogm 3305 * @tt_vlan: pointer to the first tvlv VLAN entry 3306 * @tt_num_vlan: number of tvlv VLAN entries 3307 * @tt_change: pointer to the first entry in the TT buffer 3308 * @tt_num_changes: number of tt changes inside the tt buffer 3309 * @ttvn: translation table version number of this changeset 3310 * @tt_crc: crc32 checksum of orig node's translation table 3311 */ 3312 static void batadv_tt_update_orig(struct batadv_priv *bat_priv, 3313 struct batadv_orig_node *orig_node, 3314 const void *tt_buff, uint16_t tt_num_vlan, 3315 struct batadv_tvlv_tt_change *tt_change, 3316 uint16_t tt_num_changes, uint8_t ttvn) 3317 { 3318 uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); 3319 struct batadv_tvlv_tt_vlan_data *tt_vlan; 3320 bool full_table = true; 3321 bool has_tt_init; 3322 3323 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)tt_buff; 3324 has_tt_init = orig_node->capa_initialized & BATADV_ORIG_CAPA_HAS_TT; 3325 3326 /* orig table not initialised AND first diff is in the OGM OR the ttvn 3327 * increased by one -> we can apply the attached changes 3328 */ 3329 if ((!has_tt_init && ttvn == 1) || ttvn - orig_ttvn == 1) { 3330 /* the OGM could not contain the changes due to their size or 3331 * because they have already been sent BATADV_TT_OGM_APPEND_MAX 3332 * times. 3333 * In this case send a tt request 3334 */ 3335 if (!tt_num_changes) { 3336 full_table = false; 3337 goto request_table; 3338 } 3339 3340 spin_lock_bh(&orig_node->tt_lock); 3341 3342 batadv_tt_update_changes(bat_priv, orig_node, tt_num_changes, 3343 ttvn, tt_change); 3344 3345 /* Even if we received the precomputed crc with the OGM, we 3346 * prefer to recompute it to spot any possible inconsistency 3347 * in the global table 3348 */ 3349 batadv_tt_global_update_crc(bat_priv, orig_node); 3350 3351 spin_unlock_bh(&orig_node->tt_lock); 3352 3353 /* The ttvn alone is not enough to guarantee consistency 3354 * because a single value could represent different states 3355 * (due to the wrap around). Thus a node has to check whether 3356 * the resulting table (after applying the changes) is still 3357 * consistent or not. E.g. a node could disconnect while its 3358 * ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case 3359 * checking the CRC value is mandatory to detect the 3360 * inconsistency 3361 */ 3362 if (!batadv_tt_global_check_crc(orig_node, tt_vlan, 3363 tt_num_vlan)) 3364 goto request_table; 3365 } else { 3366 /* if we missed more than one change or our tables are not 3367 * in sync anymore -> request fresh tt data 3368 */ 3369 if (!has_tt_init || ttvn != orig_ttvn || 3370 !batadv_tt_global_check_crc(orig_node, tt_vlan, 3371 tt_num_vlan)) { 3372 request_table: 3373 batadv_dbg(BATADV_DBG_TT, bat_priv, 3374 "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u num_changes: %u)\n", 3375 orig_node->orig, ttvn, orig_ttvn, 3376 tt_num_changes); 3377 batadv_send_tt_request(bat_priv, orig_node, ttvn, 3378 tt_vlan, tt_num_vlan, 3379 full_table); 3380 return; 3381 } 3382 } 3383 } 3384 3385 /** 3386 * batadv_tt_global_client_is_roaming - check if a client is marked as roaming 3387 * @bat_priv: the bat priv with all the soft interface information 3388 * @addr: the mac address of the client to check 3389 * @vid: VLAN identifier 3390 * 3391 * Returns true if we know that the client has moved from its old originator 3392 * to another one. This entry is still kept for consistency purposes and will be 3393 * deleted later by a DEL or because of timeout 3394 */ 3395 bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, 3396 uint8_t *addr, unsigned short vid) 3397 { 3398 struct batadv_tt_global_entry *tt_global_entry; 3399 bool ret = false; 3400 3401 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid); 3402 if (!tt_global_entry) 3403 goto out; 3404 3405 ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM; 3406 batadv_tt_global_entry_free_ref(tt_global_entry); 3407 out: 3408 return ret; 3409 } 3410 3411 /** 3412 * batadv_tt_local_client_is_roaming - tells whether the client is roaming 3413 * @bat_priv: the bat priv with all the soft interface information 3414 * @addr: the mac address of the local client to query 3415 * @vid: VLAN identifier 3416 * 3417 * Returns true if the local client is known to be roaming (it is not served by 3418 * this node anymore) or not. If yes, the client is still present in the table 3419 * to keep the latter consistent with the node TTVN 3420 */ 3421 bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv, 3422 uint8_t *addr, unsigned short vid) 3423 { 3424 struct batadv_tt_local_entry *tt_local_entry; 3425 bool ret = false; 3426 3427 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid); 3428 if (!tt_local_entry) 3429 goto out; 3430 3431 ret = tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM; 3432 batadv_tt_local_entry_free_ref(tt_local_entry); 3433 out: 3434 return ret; 3435 } 3436 3437 bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, 3438 struct batadv_orig_node *orig_node, 3439 const unsigned char *addr, 3440 unsigned short vid) 3441 { 3442 bool ret = false; 3443 3444 if (!batadv_tt_global_add(bat_priv, orig_node, addr, vid, 3445 BATADV_TT_CLIENT_TEMP, 3446 atomic_read(&orig_node->last_ttvn))) 3447 goto out; 3448 3449 batadv_dbg(BATADV_DBG_TT, bat_priv, 3450 "Added temporary global client (addr: %pM, vid: %d, orig: %pM)\n", 3451 addr, BATADV_PRINT_VID(vid), orig_node->orig); 3452 ret = true; 3453 out: 3454 return ret; 3455 } 3456 3457 /** 3458 * batadv_tt_local_resize_to_mtu - resize the local translation table fit the 3459 * maximum packet size that can be transported through the mesh 3460 * @soft_iface: netdev struct of the mesh interface 3461 * 3462 * Remove entries older than 'timeout' and half timeout if more entries need 3463 * to be removed. 3464 */ 3465 void batadv_tt_local_resize_to_mtu(struct net_device *soft_iface) 3466 { 3467 struct batadv_priv *bat_priv = netdev_priv(soft_iface); 3468 int packet_size_max = atomic_read(&bat_priv->packet_size_max); 3469 int table_size, timeout = BATADV_TT_LOCAL_TIMEOUT / 2; 3470 bool reduced = false; 3471 3472 spin_lock_bh(&bat_priv->tt.commit_lock); 3473 3474 while (true) { 3475 table_size = batadv_tt_local_table_transmit_size(bat_priv); 3476 if (packet_size_max >= table_size) 3477 break; 3478 3479 batadv_tt_local_purge(bat_priv, timeout); 3480 batadv_tt_local_purge_pending_clients(bat_priv); 3481 3482 timeout /= 2; 3483 reduced = true; 3484 net_ratelimited_function(batadv_info, soft_iface, 3485 "Forced to purge local tt entries to fit new maximum fragment MTU (%i)\n", 3486 packet_size_max); 3487 } 3488 3489 /* commit these changes immediately, to avoid synchronization problem 3490 * with the TTVN 3491 */ 3492 if (reduced) 3493 batadv_tt_local_commit_changes_nolock(bat_priv); 3494 3495 spin_unlock_bh(&bat_priv->tt.commit_lock); 3496 } 3497 3498 /** 3499 * batadv_tt_tvlv_ogm_handler_v1 - process incoming tt tvlv container 3500 * @bat_priv: the bat priv with all the soft interface information 3501 * @orig: the orig_node of the ogm 3502 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags) 3503 * @tvlv_value: tvlv buffer containing the gateway data 3504 * @tvlv_value_len: tvlv buffer length 3505 */ 3506 static void batadv_tt_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, 3507 struct batadv_orig_node *orig, 3508 uint8_t flags, void *tvlv_value, 3509 uint16_t tvlv_value_len) 3510 { 3511 struct batadv_tvlv_tt_vlan_data *tt_vlan; 3512 struct batadv_tvlv_tt_change *tt_change; 3513 struct batadv_tvlv_tt_data *tt_data; 3514 uint16_t num_entries, num_vlan; 3515 3516 if (tvlv_value_len < sizeof(*tt_data)) 3517 return; 3518 3519 tt_data = (struct batadv_tvlv_tt_data *)tvlv_value; 3520 tvlv_value_len -= sizeof(*tt_data); 3521 3522 num_vlan = ntohs(tt_data->num_vlan); 3523 3524 if (tvlv_value_len < sizeof(*tt_vlan) * num_vlan) 3525 return; 3526 3527 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(tt_data + 1); 3528 tt_change = (struct batadv_tvlv_tt_change *)(tt_vlan + num_vlan); 3529 tvlv_value_len -= sizeof(*tt_vlan) * num_vlan; 3530 3531 num_entries = batadv_tt_entries(tvlv_value_len); 3532 3533 batadv_tt_update_orig(bat_priv, orig, tt_vlan, num_vlan, tt_change, 3534 num_entries, tt_data->ttvn); 3535 } 3536 3537 /** 3538 * batadv_tt_tvlv_unicast_handler_v1 - process incoming (unicast) tt tvlv 3539 * container 3540 * @bat_priv: the bat priv with all the soft interface information 3541 * @src: mac address of tt tvlv sender 3542 * @dst: mac address of tt tvlv recipient 3543 * @tvlv_value: tvlv buffer containing the tt data 3544 * @tvlv_value_len: tvlv buffer length 3545 * 3546 * Returns NET_RX_DROP if the tt tvlv is to be re-routed, NET_RX_SUCCESS 3547 * otherwise. 3548 */ 3549 static int batadv_tt_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv, 3550 uint8_t *src, uint8_t *dst, 3551 void *tvlv_value, 3552 uint16_t tvlv_value_len) 3553 { 3554 struct batadv_tvlv_tt_data *tt_data; 3555 uint16_t tt_vlan_len, tt_num_entries; 3556 char tt_flag; 3557 bool ret; 3558 3559 if (tvlv_value_len < sizeof(*tt_data)) 3560 return NET_RX_SUCCESS; 3561 3562 tt_data = (struct batadv_tvlv_tt_data *)tvlv_value; 3563 tvlv_value_len -= sizeof(*tt_data); 3564 3565 tt_vlan_len = sizeof(struct batadv_tvlv_tt_vlan_data); 3566 tt_vlan_len *= ntohs(tt_data->num_vlan); 3567 3568 if (tvlv_value_len < tt_vlan_len) 3569 return NET_RX_SUCCESS; 3570 3571 tvlv_value_len -= tt_vlan_len; 3572 tt_num_entries = batadv_tt_entries(tvlv_value_len); 3573 3574 switch (tt_data->flags & BATADV_TT_DATA_TYPE_MASK) { 3575 case BATADV_TT_REQUEST: 3576 batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_RX); 3577 3578 /* If this node cannot provide a TT response the tt_request is 3579 * forwarded 3580 */ 3581 ret = batadv_send_tt_response(bat_priv, tt_data, src, dst); 3582 if (!ret) { 3583 if (tt_data->flags & BATADV_TT_FULL_TABLE) 3584 tt_flag = 'F'; 3585 else 3586 tt_flag = '.'; 3587 3588 batadv_dbg(BATADV_DBG_TT, bat_priv, 3589 "Routing TT_REQUEST to %pM [%c]\n", 3590 dst, tt_flag); 3591 /* tvlv API will re-route the packet */ 3592 return NET_RX_DROP; 3593 } 3594 break; 3595 case BATADV_TT_RESPONSE: 3596 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_RX); 3597 3598 if (batadv_is_my_mac(bat_priv, dst)) { 3599 batadv_handle_tt_response(bat_priv, tt_data, 3600 src, tt_num_entries); 3601 return NET_RX_SUCCESS; 3602 } 3603 3604 if (tt_data->flags & BATADV_TT_FULL_TABLE) 3605 tt_flag = 'F'; 3606 else 3607 tt_flag = '.'; 3608 3609 batadv_dbg(BATADV_DBG_TT, bat_priv, 3610 "Routing TT_RESPONSE to %pM [%c]\n", dst, tt_flag); 3611 3612 /* tvlv API will re-route the packet */ 3613 return NET_RX_DROP; 3614 } 3615 3616 return NET_RX_SUCCESS; 3617 } 3618 3619 /** 3620 * batadv_roam_tvlv_unicast_handler_v1 - process incoming tt roam tvlv container 3621 * @bat_priv: the bat priv with all the soft interface information 3622 * @src: mac address of tt tvlv sender 3623 * @dst: mac address of tt tvlv recipient 3624 * @tvlv_value: tvlv buffer containing the tt data 3625 * @tvlv_value_len: tvlv buffer length 3626 * 3627 * Returns NET_RX_DROP if the tt roam tvlv is to be re-routed, NET_RX_SUCCESS 3628 * otherwise. 3629 */ 3630 static int batadv_roam_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv, 3631 uint8_t *src, uint8_t *dst, 3632 void *tvlv_value, 3633 uint16_t tvlv_value_len) 3634 { 3635 struct batadv_tvlv_roam_adv *roaming_adv; 3636 struct batadv_orig_node *orig_node = NULL; 3637 3638 /* If this node is not the intended recipient of the 3639 * roaming advertisement the packet is forwarded 3640 * (the tvlv API will re-route the packet). 3641 */ 3642 if (!batadv_is_my_mac(bat_priv, dst)) 3643 return NET_RX_DROP; 3644 3645 if (tvlv_value_len < sizeof(*roaming_adv)) 3646 goto out; 3647 3648 orig_node = batadv_orig_hash_find(bat_priv, src); 3649 if (!orig_node) 3650 goto out; 3651 3652 batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX); 3653 roaming_adv = (struct batadv_tvlv_roam_adv *)tvlv_value; 3654 3655 batadv_dbg(BATADV_DBG_TT, bat_priv, 3656 "Received ROAMING_ADV from %pM (client %pM)\n", 3657 src, roaming_adv->client); 3658 3659 batadv_tt_global_add(bat_priv, orig_node, roaming_adv->client, 3660 ntohs(roaming_adv->vid), BATADV_TT_CLIENT_ROAM, 3661 atomic_read(&orig_node->last_ttvn) + 1); 3662 3663 out: 3664 if (orig_node) 3665 batadv_orig_node_free_ref(orig_node); 3666 return NET_RX_SUCCESS; 3667 } 3668 3669 /** 3670 * batadv_tt_init - initialise the translation table internals 3671 * @bat_priv: the bat priv with all the soft interface information 3672 * 3673 * Return 0 on success or negative error number in case of failure. 3674 */ 3675 int batadv_tt_init(struct batadv_priv *bat_priv) 3676 { 3677 int ret; 3678 3679 /* synchronized flags must be remote */ 3680 BUILD_BUG_ON(!(BATADV_TT_SYNC_MASK & BATADV_TT_REMOTE_MASK)); 3681 3682 ret = batadv_tt_local_init(bat_priv); 3683 if (ret < 0) 3684 return ret; 3685 3686 ret = batadv_tt_global_init(bat_priv); 3687 if (ret < 0) 3688 return ret; 3689 3690 batadv_tvlv_handler_register(bat_priv, batadv_tt_tvlv_ogm_handler_v1, 3691 batadv_tt_tvlv_unicast_handler_v1, 3692 BATADV_TVLV_TT, 1, BATADV_NO_FLAGS); 3693 3694 batadv_tvlv_handler_register(bat_priv, NULL, 3695 batadv_roam_tvlv_unicast_handler_v1, 3696 BATADV_TVLV_ROAM, 1, BATADV_NO_FLAGS); 3697 3698 INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge); 3699 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work, 3700 msecs_to_jiffies(BATADV_TT_WORK_PERIOD)); 3701 3702 return 1; 3703 } 3704 3705 /** 3706 * batadv_tt_global_is_isolated - check if a client is marked as isolated 3707 * @bat_priv: the bat priv with all the soft interface information 3708 * @addr: the mac address of the client 3709 * @vid: the identifier of the VLAN where this client is connected 3710 * 3711 * Returns true if the client is marked with the TT_CLIENT_ISOLA flag, false 3712 * otherwise 3713 */ 3714 bool batadv_tt_global_is_isolated(struct batadv_priv *bat_priv, 3715 const uint8_t *addr, unsigned short vid) 3716 { 3717 struct batadv_tt_global_entry *tt; 3718 bool ret; 3719 3720 tt = batadv_tt_global_hash_find(bat_priv, addr, vid); 3721 if (!tt) 3722 return false; 3723 3724 ret = tt->common.flags & BATADV_TT_CLIENT_ISOLA; 3725 3726 batadv_tt_global_entry_free_ref(tt); 3727 3728 return ret; 3729 } 3730