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