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