Lines Matching +full:bat +full:- +full:temp

1 // SPDX-License-Identifier: GPL-2.0
7 #include "translation-table.h"
46 #include "hard-interface.h"
51 #include "soft-interface.h"
78 * batadv_compare_tt() - check if two TT entries are the same
93 return (tt1->vid == tt2->vid) && batadv_compare_eth(data1, data2); in batadv_compare_tt()
97 * batadv_choose_tt() - return the index of the tt entry in the hash table
110 hash = jhash(&tt->addr, ETH_ALEN, hash); in batadv_choose_tt()
111 hash = jhash(&tt->vid, sizeof(tt->vid), hash); in batadv_choose_tt()
117 * batadv_tt_hash_find() - look for a client in the given hash table
139 index = batadv_choose_tt(&to_search, hash->size); in batadv_tt_hash_find()
140 head = &hash->table[index]; in batadv_tt_hash_find()
147 if (tt->vid != vid) in batadv_tt_hash_find()
150 if (!kref_get_unless_zero(&tt->refcount)) in batadv_tt_hash_find()
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
177 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, addr, in batadv_tt_local_hash_find()
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
202 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, addr, in batadv_tt_global_hash_find()
212 * batadv_tt_local_entry_free_rcu() - free the tt_local_entry
226 * batadv_tt_local_entry_release() - release tt_local_entry from lists and queue
237 batadv_softif_vlan_put(tt_local_entry->vlan); in batadv_tt_local_entry_release()
239 call_rcu(&tt_local_entry->common.rcu, batadv_tt_local_entry_free_rcu); in batadv_tt_local_entry_release()
243 * batadv_tt_local_entry_put() - decrement the tt_local_entry refcounter and
253 kref_put(&tt_local_entry->common.refcount, in batadv_tt_local_entry_put()
258 * batadv_tt_global_entry_free_rcu() - free the tt_global_entry
272 * batadv_tt_global_entry_release() - release tt_global_entry from lists and
285 call_rcu(&tt_global_entry->common.rcu, batadv_tt_global_entry_free_rcu); in batadv_tt_global_entry_release()
289 * batadv_tt_global_hash_count() - count the number of orig entries
290 * @bat_priv: the bat priv with all the soft interface information
307 count = atomic_read(&tt_global_entry->orig_list_count); in batadv_tt_global_hash_count()
314 * batadv_tt_local_size_mod() - change the size by v of the local table
316 * @bat_priv: the bat priv with all the soft interface information
317 * @vid: the VLAN identifier of the sub-table to change
329 atomic_add(v, &vlan->tt.num_entries); in batadv_tt_local_size_mod()
335 * batadv_tt_local_size_inc() - increase by one the local table size for the
337 * @bat_priv: the bat priv with all the soft interface information
347 * batadv_tt_local_size_dec() - decrease by one the local table size for the
349 * @bat_priv: the bat priv with all the soft interface information
355 batadv_tt_local_size_mod(bat_priv, vid, -1); in batadv_tt_local_size_dec()
359 * batadv_tt_global_size_mod() - change the size by v of the global table
374 if (atomic_add_return(v, &vlan->tt.num_entries) == 0) { in batadv_tt_global_size_mod()
375 spin_lock_bh(&orig_node->vlan_list_lock); in batadv_tt_global_size_mod()
376 if (!hlist_unhashed(&vlan->list)) { in batadv_tt_global_size_mod()
377 hlist_del_init_rcu(&vlan->list); in batadv_tt_global_size_mod()
380 spin_unlock_bh(&orig_node->vlan_list_lock); in batadv_tt_global_size_mod()
387 * batadv_tt_global_size_inc() - increase by one the global table size for the
399 * batadv_tt_global_size_dec() - decrease by one the global table size for the
407 batadv_tt_global_size_mod(orig_node, vid, -1); in batadv_tt_global_size_dec()
411 * batadv_tt_orig_list_entry_free_rcu() - free the orig_entry
424 * batadv_tt_orig_list_entry_release() - release tt orig entry from lists and
435 batadv_orig_node_put(orig_entry->orig_node); in batadv_tt_orig_list_entry_release()
436 call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu); in batadv_tt_orig_list_entry_release()
440 * batadv_tt_orig_list_entry_put() - decrement the tt orig entry refcounter and
450 kref_put(&orig_entry->refcount, batadv_tt_orig_list_entry_release); in batadv_tt_orig_list_entry_put()
454 * batadv_tt_local_event() - store a local TT event (ADD/DEL)
455 * @bat_priv: the bat priv with all the soft interface information
464 struct batadv_tt_common_entry *common = &tt_local_entry->common; in batadv_tt_local_event()
465 u8 flags = common->flags | event_flags; in batadv_tt_local_event()
473 tt_change_node->change.flags = flags; in batadv_tt_local_event()
474 memset(tt_change_node->change.reserved, 0, in batadv_tt_local_event()
475 sizeof(tt_change_node->change.reserved)); in batadv_tt_local_event()
476 ether_addr_copy(tt_change_node->change.addr, common->addr); in batadv_tt_local_event()
477 tt_change_node->change.vid = htons(common->vid); in batadv_tt_local_event()
482 spin_lock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_local_event()
483 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, in batadv_tt_local_event()
485 if (!batadv_compare_eth(entry->change.addr, common->addr)) in batadv_tt_local_event()
495 del_op_entry = entry->change.flags & BATADV_TT_CLIENT_DEL; in batadv_tt_local_event()
505 entry->change.flags = flags; in batadv_tt_local_event()
509 list_del(&entry->list); in batadv_tt_local_event()
517 list_add_tail(&tt_change_node->list, &bat_priv->tt.changes_list); in batadv_tt_local_event()
520 spin_unlock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_local_event()
523 atomic_dec(&bat_priv->tt.local_changes); in batadv_tt_local_event()
525 atomic_inc(&bat_priv->tt.local_changes); in batadv_tt_local_event()
529 * batadv_tt_len() - compute length in bytes of given number of tt changes
540 * batadv_tt_entries() - compute the number of entries fitting in tt_len bytes
551 * batadv_tt_local_table_transmit_size() - calculates the local translation
553 * @bat_priv: the bat priv with all the soft interface information
565 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { in batadv_tt_local_table_transmit_size()
567 tt_local_entries += atomic_read(&vlan->tt.num_entries); in batadv_tt_local_table_transmit_size()
582 if (bat_priv->tt.local_hash) in batadv_tt_local_init()
585 bat_priv->tt.local_hash = batadv_hash_new(1024); in batadv_tt_local_init()
587 if (!bat_priv->tt.local_hash) in batadv_tt_local_init()
588 return -ENOMEM; in batadv_tt_local_init()
590 batadv_hash_set_lock_class(bat_priv->tt.local_hash, in batadv_tt_local_init()
605 tt_global->common.addr, in batadv_tt_global_free()
606 batadv_print_vid(tt_global->common.vid), message); in batadv_tt_global_free()
608 tt_removed_node = batadv_hash_remove(bat_priv->tt.global_hash, in batadv_tt_global_free()
611 &tt_global->common); in batadv_tt_global_free()
623 * batadv_tt_local_add() - add a new client to the local table or update an
630 * @mark: the value contained in the skb->mark field of the received packet (if
665 tt_local->last_seen = jiffies; in batadv_tt_local_add()
666 if (tt_local->common.flags & BATADV_TT_CLIENT_PENDING) { in batadv_tt_local_add()
668 "Re-adding pending client %pM (vid: %d)\n", in batadv_tt_local_add()
675 tt_local->common.flags &= ~BATADV_TT_CLIENT_PENDING; in batadv_tt_local_add()
679 if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) { in batadv_tt_local_add()
688 tt_local->common.flags &= ~BATADV_TT_CLIENT_ROAM; in batadv_tt_local_add()
697 packet_size_max = atomic_read(&bat_priv->packet_size_max); in batadv_tt_local_add()
713 "adding TT local entry %pM to non-existent VLAN %d\n", in batadv_tt_local_add()
723 (u8)atomic_read(&bat_priv->tt.vn)); in batadv_tt_local_add()
725 ether_addr_copy(tt_local->common.addr, addr); in batadv_tt_local_add()
730 tt_local->common.flags = BATADV_TT_CLIENT_NEW; in batadv_tt_local_add()
731 tt_local->common.vid = vid; in batadv_tt_local_add()
733 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI; in batadv_tt_local_add()
734 kref_init(&tt_local->common.refcount); in batadv_tt_local_add()
735 tt_local->last_seen = jiffies; in batadv_tt_local_add()
736 tt_local->common.added_at = tt_local->last_seen; in batadv_tt_local_add()
737 tt_local->vlan = vlan; in batadv_tt_local_add()
742 if (batadv_compare_eth(addr, soft_iface->dev_addr) || in batadv_tt_local_add()
744 tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE; in batadv_tt_local_add()
746 kref_get(&tt_local->common.refcount); in batadv_tt_local_add()
747 hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt, in batadv_tt_local_add()
748 batadv_choose_tt, &tt_local->common, in batadv_tt_local_add()
749 &tt_local->common.hash_entry); in batadv_tt_local_add()
764 if (tt_global && !(tt_global->common.flags & BATADV_TT_CLIENT_ROAM)) { in batadv_tt_local_add()
766 head = &tt_global->orig_list; in batadv_tt_local_add()
769 batadv_send_roam_adv(bat_priv, tt_global->common.addr, in batadv_tt_local_add()
770 tt_global->common.vid, in batadv_tt_local_add()
771 orig_entry->orig_node); in batadv_tt_local_add()
781 tt_global->common.flags |= BATADV_TT_CLIENT_ROAM; in batadv_tt_local_add()
782 tt_global->roam_at = jiffies; in batadv_tt_local_add()
789 remote_flags = tt_local->common.flags & BATADV_TT_REMOTE_MASK; in batadv_tt_local_add()
792 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI; in batadv_tt_local_add()
794 tt_local->common.flags &= ~BATADV_TT_CLIENT_WIFI; in batadv_tt_local_add()
798 * non-mesh client in batadv_tt_local_add()
800 match_mark = (mark & bat_priv->isolation_mark_mask); in batadv_tt_local_add()
801 if (bat_priv->isolation_mark_mask && in batadv_tt_local_add()
802 match_mark == bat_priv->isolation_mark) in batadv_tt_local_add()
803 tt_local->common.flags |= BATADV_TT_CLIENT_ISOLA; in batadv_tt_local_add()
805 tt_local->common.flags &= ~BATADV_TT_CLIENT_ISOLA; in batadv_tt_local_add()
810 if (remote_flags ^ (tt_local->common.flags & BATADV_TT_REMOTE_MASK)) in batadv_tt_local_add()
823 * batadv_tt_prepare_tvlv_global_data() - prepare the TVLV TT header to send
829 * @tt_len: pointer to the length to reserve to the tt_change. if -1 this
853 spin_lock_bh(&orig_node->vlan_list_lock); in batadv_tt_prepare_tvlv_global_data()
854 hlist_for_each_entry(vlan, &orig_node->vlan_list, list) { in batadv_tt_prepare_tvlv_global_data()
856 num_entries += atomic_read(&vlan->tt.num_entries); in batadv_tt_prepare_tvlv_global_data()
875 (*tt_data)->flags = BATADV_NO_FLAGS; in batadv_tt_prepare_tvlv_global_data()
876 (*tt_data)->ttvn = atomic_read(&orig_node->last_ttvn); in batadv_tt_prepare_tvlv_global_data()
877 (*tt_data)->num_vlan = htons(num_vlan); in batadv_tt_prepare_tvlv_global_data()
880 hlist_for_each_entry(vlan, &orig_node->vlan_list, list) { in batadv_tt_prepare_tvlv_global_data()
881 tt_vlan->vid = htons(vlan->vid); in batadv_tt_prepare_tvlv_global_data()
882 tt_vlan->crc = htonl(vlan->tt.crc); in batadv_tt_prepare_tvlv_global_data()
883 tt_vlan->reserved = 0; in batadv_tt_prepare_tvlv_global_data()
892 spin_unlock_bh(&orig_node->vlan_list_lock); in batadv_tt_prepare_tvlv_global_data()
897 * batadv_tt_prepare_tvlv_local_data() - allocate and prepare the TT TVLV for
899 * @bat_priv: the bat priv with all the soft interface information
903 * @tt_len: pointer to the length to reserve to the tt_change. if -1 this
929 spin_lock_bh(&bat_priv->softif_vlan_list_lock); in batadv_tt_prepare_tvlv_local_data()
930 hlist_for_each_entry(vlan, &bat_priv->softif_vlan_list, list) { in batadv_tt_prepare_tvlv_local_data()
931 vlan_entries = atomic_read(&vlan->tt.num_entries); in batadv_tt_prepare_tvlv_local_data()
955 (*tt_data)->flags = BATADV_NO_FLAGS; in batadv_tt_prepare_tvlv_local_data()
956 (*tt_data)->ttvn = atomic_read(&bat_priv->tt.vn); in batadv_tt_prepare_tvlv_local_data()
957 (*tt_data)->num_vlan = htons(num_vlan); in batadv_tt_prepare_tvlv_local_data()
960 hlist_for_each_entry(vlan, &bat_priv->softif_vlan_list, list) { in batadv_tt_prepare_tvlv_local_data()
961 vlan_entries = atomic_read(&vlan->tt.num_entries); in batadv_tt_prepare_tvlv_local_data()
965 tt_vlan->vid = htons(vlan->vid); in batadv_tt_prepare_tvlv_local_data()
966 tt_vlan->crc = htonl(vlan->tt.crc); in batadv_tt_prepare_tvlv_local_data()
967 tt_vlan->reserved = 0; in batadv_tt_prepare_tvlv_local_data()
976 spin_unlock_bh(&bat_priv->softif_vlan_list_lock); in batadv_tt_prepare_tvlv_local_data()
981 * batadv_tt_tvlv_container_update() - update the translation table tvlv
983 * @bat_priv: the bat priv with all the soft interface information
997 tt_diff_entries_num = atomic_read(&bat_priv->tt.local_changes); in batadv_tt_tvlv_container_update()
1007 if (tt_diff_len > bat_priv->soft_iface->mtu) { in batadv_tt_tvlv_container_update()
1018 tt_data->flags = BATADV_TT_OGM_DIFF; in batadv_tt_tvlv_container_update()
1023 spin_lock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_tvlv_container_update()
1024 atomic_set(&bat_priv->tt.local_changes, 0); in batadv_tt_tvlv_container_update()
1026 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, in batadv_tt_tvlv_container_update()
1030 &entry->change, in batadv_tt_tvlv_container_update()
1034 list_del(&entry->list); in batadv_tt_tvlv_container_update()
1037 spin_unlock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_tvlv_container_update()
1039 tt_extra_len = batadv_tt_len(tt_diff_entries_num - in batadv_tt_tvlv_container_update()
1043 spin_lock_bh(&bat_priv->tt.last_changeset_lock); in batadv_tt_tvlv_container_update()
1044 kfree(bat_priv->tt.last_changeset); in batadv_tt_tvlv_container_update()
1045 bat_priv->tt.last_changeset_len = 0; in batadv_tt_tvlv_container_update()
1046 bat_priv->tt.last_changeset = NULL; in batadv_tt_tvlv_container_update()
1050 tt_diff_len -= tt_extra_len; in batadv_tt_tvlv_container_update()
1054 bat_priv->tt.last_changeset = kzalloc(tt_diff_len, GFP_ATOMIC); in batadv_tt_tvlv_container_update()
1055 if (bat_priv->tt.last_changeset) { in batadv_tt_tvlv_container_update()
1056 memcpy(bat_priv->tt.last_changeset, in batadv_tt_tvlv_container_update()
1058 bat_priv->tt.last_changeset_len = tt_diff_len; in batadv_tt_tvlv_container_update()
1061 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); in batadv_tt_tvlv_container_update()
1064 tvlv_len -= tt_extra_len; in batadv_tt_tvlv_container_update()
1072 * batadv_tt_local_dump_entry() - Dump one TT local entry into a message
1076 * @bat_priv: The bat priv with all the soft interface information
1094 last_seen_msecs = jiffies_to_msecs(jiffies - local->last_seen); in batadv_tt_local_dump_entry()
1096 vlan = batadv_softif_vlan_get(bat_priv, common->vid); in batadv_tt_local_dump_entry()
1100 crc = vlan->tt.crc; in batadv_tt_local_dump_entry()
1104 hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq, in batadv_tt_local_dump_entry()
1108 return -ENOBUFS; in batadv_tt_local_dump_entry()
1112 if (nla_put(msg, BATADV_ATTR_TT_ADDRESS, ETH_ALEN, common->addr) || in batadv_tt_local_dump_entry()
1114 nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) || in batadv_tt_local_dump_entry()
1115 nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, common->flags)) in batadv_tt_local_dump_entry()
1118 if (!(common->flags & BATADV_TT_CLIENT_NOPURGE) && in batadv_tt_local_dump_entry()
1127 return -EMSGSIZE; in batadv_tt_local_dump_entry()
1131 * batadv_tt_local_dump_bucket() - Dump one TT local bucket into a message
1135 * @bat_priv: The bat priv with all the soft interface information
1152 spin_lock_bh(&hash->list_locks[bucket]); in batadv_tt_local_dump_bucket()
1153 cb->seq = atomic_read(&hash->generation) << 1 | 1; in batadv_tt_local_dump_bucket()
1155 hlist_for_each_entry(common, &hash->table[bucket], hash_entry) { in batadv_tt_local_dump_bucket()
1161 spin_unlock_bh(&hash->list_locks[bucket]); in batadv_tt_local_dump_bucket()
1162 *idx_s = idx - 1; in batadv_tt_local_dump_bucket()
1163 return -EMSGSIZE; in batadv_tt_local_dump_bucket()
1166 spin_unlock_bh(&hash->list_locks[bucket]); in batadv_tt_local_dump_bucket()
1173 * batadv_tt_local_dump() - Dump TT local entries into a message
1181 struct net *net = sock_net(cb->skb->sk); in batadv_tt_local_dump()
1188 int bucket = cb->args[0]; in batadv_tt_local_dump()
1189 int idx = cb->args[1]; in batadv_tt_local_dump()
1190 int portid = NETLINK_CB(cb->skb).portid; in batadv_tt_local_dump()
1192 ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX); in batadv_tt_local_dump()
1194 return -EINVAL; in batadv_tt_local_dump()
1198 ret = -ENODEV; in batadv_tt_local_dump()
1205 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { in batadv_tt_local_dump()
1206 ret = -ENOENT; in batadv_tt_local_dump()
1210 hash = bat_priv->tt.local_hash; in batadv_tt_local_dump()
1212 while (bucket < hash->size) { in batadv_tt_local_dump()
1220 ret = msg->len; in batadv_tt_local_dump()
1226 cb->args[0] = bucket; in batadv_tt_local_dump()
1227 cb->args[1] = idx; in batadv_tt_local_dump()
1243 tt_local_entry->common.flags |= BATADV_TT_CLIENT_PENDING; in batadv_tt_local_set_pending()
1247 tt_local_entry->common.addr, in batadv_tt_local_set_pending()
1248 batadv_print_vid(tt_local_entry->common.vid), message); in batadv_tt_local_set_pending()
1252 * batadv_tt_local_remove() - logically remove an entry from the local table
1253 * @bat_priv: the bat priv with all the soft interface information
1274 curr_flags = tt_local_entry->common.flags; in batadv_tt_local_remove()
1284 tt_local_entry->common.flags |= BATADV_TT_CLIENT_ROAM; in batadv_tt_local_remove()
1287 if (!(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) { in batadv_tt_local_remove()
1297 tt_removed_node = batadv_hash_remove(bat_priv->tt.local_hash, in batadv_tt_local_remove()
1300 &tt_local_entry->common); in batadv_tt_local_remove()
1317 * batadv_tt_local_purge_list() - purge inactive tt local entries
1318 * @bat_priv: the bat priv with all the soft interface information
1336 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_NOPURGE) in batadv_tt_local_purge_list()
1340 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) in batadv_tt_local_purge_list()
1343 if (!batadv_has_timed_out(tt_local_entry->last_seen, timeout)) in batadv_tt_local_purge_list()
1352 * batadv_tt_local_purge() - purge inactive tt local entries
1353 * @bat_priv: the bat priv with all the soft interface information
1360 struct batadv_hashtable *hash = bat_priv->tt.local_hash; in batadv_tt_local_purge()
1365 for (i = 0; i < hash->size; i++) { in batadv_tt_local_purge()
1366 head = &hash->table[i]; in batadv_tt_local_purge()
1367 list_lock = &hash->list_locks[i]; in batadv_tt_local_purge()
1385 if (!bat_priv->tt.local_hash) in batadv_tt_local_table_free()
1388 hash = bat_priv->tt.local_hash; in batadv_tt_local_table_free()
1390 for (i = 0; i < hash->size; i++) { in batadv_tt_local_table_free()
1391 head = &hash->table[i]; in batadv_tt_local_table_free()
1392 list_lock = &hash->list_locks[i]; in batadv_tt_local_table_free()
1397 hlist_del_rcu(&tt_common_entry->hash_entry); in batadv_tt_local_table_free()
1409 bat_priv->tt.local_hash = NULL; in batadv_tt_local_table_free()
1414 if (bat_priv->tt.global_hash) in batadv_tt_global_init()
1417 bat_priv->tt.global_hash = batadv_hash_new(1024); in batadv_tt_global_init()
1419 if (!bat_priv->tt.global_hash) in batadv_tt_global_init()
1420 return -ENOMEM; in batadv_tt_global_init()
1422 batadv_hash_set_lock_class(bat_priv->tt.global_hash, in batadv_tt_global_init()
1432 spin_lock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_changes_list_free()
1434 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, in batadv_tt_changes_list_free()
1436 list_del(&entry->list); in batadv_tt_changes_list_free()
1440 atomic_set(&bat_priv->tt.local_changes, 0); in batadv_tt_changes_list_free()
1441 spin_unlock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_changes_list_free()
1445 * batadv_tt_global_orig_entry_find() - find a TT orig_list_entry
1463 head = &entry->orig_list; in batadv_tt_global_orig_entry_find()
1465 if (tmp_orig_entry->orig_node != orig_node) in batadv_tt_global_orig_entry_find()
1467 if (!kref_get_unless_zero(&tmp_orig_entry->refcount)) in batadv_tt_global_orig_entry_find()
1479 * batadv_tt_global_entry_has_orig() - check if a TT global entry is also
1503 *flags = orig_entry->flags; in batadv_tt_global_entry_has_orig()
1512 * batadv_tt_global_sync_flags() - update TT sync flags
1526 head = &tt_global->orig_list; in batadv_tt_global_sync_flags()
1528 flags |= orig_entry->flags; in batadv_tt_global_sync_flags()
1531 flags |= tt_global->common.flags & (~BATADV_TT_SYNC_MASK); in batadv_tt_global_sync_flags()
1532 tt_global->common.flags = flags; in batadv_tt_global_sync_flags()
1536 * batadv_tt_global_orig_entry_add() - add or update a TT orig entry
1549 spin_lock_bh(&tt_global->list_lock); in batadv_tt_global_orig_entry_add()
1556 orig_entry->ttvn = ttvn; in batadv_tt_global_orig_entry_add()
1557 orig_entry->flags = flags; in batadv_tt_global_orig_entry_add()
1565 INIT_HLIST_NODE(&orig_entry->list); in batadv_tt_global_orig_entry_add()
1566 kref_get(&orig_node->refcount); in batadv_tt_global_orig_entry_add()
1567 batadv_tt_global_size_inc(orig_node, tt_global->common.vid); in batadv_tt_global_orig_entry_add()
1568 orig_entry->orig_node = orig_node; in batadv_tt_global_orig_entry_add()
1569 orig_entry->ttvn = ttvn; in batadv_tt_global_orig_entry_add()
1570 orig_entry->flags = flags; in batadv_tt_global_orig_entry_add()
1571 kref_init(&orig_entry->refcount); in batadv_tt_global_orig_entry_add()
1573 kref_get(&orig_entry->refcount); in batadv_tt_global_orig_entry_add()
1574 hlist_add_head_rcu(&orig_entry->list, in batadv_tt_global_orig_entry_add()
1575 &tt_global->orig_list); in batadv_tt_global_orig_entry_add()
1576 atomic_inc(&tt_global->orig_list_count); in batadv_tt_global_orig_entry_add()
1583 spin_unlock_bh(&tt_global->list_lock); in batadv_tt_global_orig_entry_add()
1587 * batadv_tt_global_add() - add a new TT global entry or update an existing one
1588 * @bat_priv: the bat priv with all the soft interface information
1590 * @tt_addr: the mac address of the non-mesh client
1592 * @flags: TT flags that have to be set for this non-mesh client
1593 * @ttvn: the tt version number ever announcing this non-mesh client
1599 * If a TT local entry exists for this non-mesh client remove it.
1618 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) in batadv_tt_global_add()
1629 !(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) in batadv_tt_global_add()
1638 common = &tt_global_entry->common; in batadv_tt_global_add()
1639 ether_addr_copy(common->addr, tt_addr); in batadv_tt_global_add()
1640 common->vid = vid; in batadv_tt_global_add()
1642 if (!is_multicast_ether_addr(common->addr)) in batadv_tt_global_add()
1643 common->flags = flags & (~BATADV_TT_SYNC_MASK); in batadv_tt_global_add()
1645 tt_global_entry->roam_at = 0; in batadv_tt_global_add()
1651 tt_global_entry->roam_at = jiffies; in batadv_tt_global_add()
1652 kref_init(&common->refcount); in batadv_tt_global_add()
1653 common->added_at = jiffies; in batadv_tt_global_add()
1655 INIT_HLIST_HEAD(&tt_global_entry->orig_list); in batadv_tt_global_add()
1656 atomic_set(&tt_global_entry->orig_list_count, 0); in batadv_tt_global_add()
1657 spin_lock_init(&tt_global_entry->list_lock); in batadv_tt_global_add()
1659 kref_get(&common->refcount); in batadv_tt_global_add()
1660 hash_added = batadv_hash_add(bat_priv->tt.global_hash, in batadv_tt_global_add()
1663 &common->hash_entry); in batadv_tt_global_add()
1671 common = &tt_global_entry->common; in batadv_tt_global_add()
1683 if (!(common->flags & BATADV_TT_CLIENT_TEMP)) in batadv_tt_global_add()
1693 * OGM announcing it, we have to clear the TEMP flag. Also, in batadv_tt_global_add()
1694 * remove the previous temporary orig node and re-add it in batadv_tt_global_add()
1696 * is a non-temporary entry is preferred. in batadv_tt_global_add()
1698 if (common->flags & BATADV_TT_CLIENT_TEMP) { in batadv_tt_global_add()
1700 common->flags &= ~BATADV_TT_CLIENT_TEMP; in batadv_tt_global_add()
1707 if (!is_multicast_ether_addr(common->addr)) in batadv_tt_global_add()
1708 common->flags |= flags & (~BATADV_TT_SYNC_MASK); in batadv_tt_global_add()
1717 if (common->flags & BATADV_TT_CLIENT_ROAM) { in batadv_tt_global_add()
1719 common->flags &= ~BATADV_TT_CLIENT_ROAM; in batadv_tt_global_add()
1720 tt_global_entry->roam_at = 0; in batadv_tt_global_add()
1730 common->addr, batadv_print_vid(common->vid), in batadv_tt_global_add()
1731 orig_node->orig); in batadv_tt_global_add()
1745 tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI; in batadv_tt_global_add()
1751 tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM; in batadv_tt_global_add()
1760 * batadv_transtable_best_orig() - Get best originator list entry from tt entry
1761 * @bat_priv: the bat priv with all the soft interface information
1772 struct batadv_algo_ops *bao = bat_priv->algo_ops; in batadv_transtable_best_orig()
1776 head = &tt_global_entry->orig_list; in batadv_transtable_best_orig()
1778 router = batadv_orig_router_get(orig_entry->orig_node, in batadv_transtable_best_orig()
1784 bao->neigh.cmp(router, BATADV_IF_DEFAULT, best_router, in batadv_transtable_best_orig()
1803 * batadv_tt_global_dump_subentry() - Dump all TT local entries into a message
1808 * @orig: Originator node announcing a non-mesh client
1819 u16 flags = (common->flags & (~BATADV_TT_SYNC_MASK)) | orig->flags; in batadv_tt_global_dump_subentry()
1825 vlan = batadv_orig_node_vlan_get(orig->orig_node, in batadv_tt_global_dump_subentry()
1826 common->vid); in batadv_tt_global_dump_subentry()
1830 crc = vlan->tt.crc; in batadv_tt_global_dump_subentry()
1838 return -ENOBUFS; in batadv_tt_global_dump_subentry()
1840 last_ttvn = atomic_read(&orig->orig_node->last_ttvn); in batadv_tt_global_dump_subentry()
1842 if (nla_put(msg, BATADV_ATTR_TT_ADDRESS, ETH_ALEN, common->addr) || in batadv_tt_global_dump_subentry()
1844 orig->orig_node->orig) || in batadv_tt_global_dump_subentry()
1845 nla_put_u8(msg, BATADV_ATTR_TT_TTVN, orig->ttvn) || in batadv_tt_global_dump_subentry()
1848 nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) || in batadv_tt_global_dump_subentry()
1860 return -EMSGSIZE; in batadv_tt_global_dump_subentry()
1864 * batadv_tt_global_dump_entry() - Dump one TT global entry into a message
1868 * @bat_priv: The bat priv with all the soft interface information
1889 head = &global->orig_list; in batadv_tt_global_dump_entry()
1899 *sub_s = sub - 1; in batadv_tt_global_dump_entry()
1900 return -EMSGSIZE; in batadv_tt_global_dump_entry()
1909 * batadv_tt_global_dump_bucket() - Dump one TT local bucket into a message
1913 * @bat_priv: The bat priv with all the soft interface information
1936 *idx_s = idx - 1; in batadv_tt_global_dump_bucket()
1937 return -EMSGSIZE; in batadv_tt_global_dump_bucket()
1948 * batadv_tt_global_dump() - Dump TT global entries into a message
1956 struct net *net = sock_net(cb->skb->sk); in batadv_tt_global_dump()
1964 int bucket = cb->args[0]; in batadv_tt_global_dump()
1965 int idx = cb->args[1]; in batadv_tt_global_dump()
1966 int sub = cb->args[2]; in batadv_tt_global_dump()
1967 int portid = NETLINK_CB(cb->skb).portid; in batadv_tt_global_dump()
1969 ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX); in batadv_tt_global_dump()
1971 return -EINVAL; in batadv_tt_global_dump()
1975 ret = -ENODEV; in batadv_tt_global_dump()
1982 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { in batadv_tt_global_dump()
1983 ret = -ENOENT; in batadv_tt_global_dump()
1987 hash = bat_priv->tt.global_hash; in batadv_tt_global_dump()
1989 while (bucket < hash->size) { in batadv_tt_global_dump()
1990 head = &hash->table[bucket]; in batadv_tt_global_dump()
1993 cb->nlh->nlmsg_seq, bat_priv, in batadv_tt_global_dump()
2000 ret = msg->len; in batadv_tt_global_dump()
2006 cb->args[0] = bucket; in batadv_tt_global_dump()
2007 cb->args[1] = idx; in batadv_tt_global_dump()
2008 cb->args[2] = sub; in batadv_tt_global_dump()
2014 * _batadv_tt_global_del_orig_entry() - remove and free an orig_entry
2021 * Caller must hold tt_global_entry->list_lock and ensure orig_entry->list is
2028 lockdep_assert_held(&tt_global_entry->list_lock); in _batadv_tt_global_del_orig_entry()
2030 batadv_tt_global_size_dec(orig_entry->orig_node, in _batadv_tt_global_del_orig_entry()
2031 tt_global_entry->common.vid); in _batadv_tt_global_del_orig_entry()
2032 atomic_dec(&tt_global_entry->orig_list_count); in _batadv_tt_global_del_orig_entry()
2033 /* requires holding tt_global_entry->list_lock and orig_entry->list in _batadv_tt_global_del_orig_entry()
2036 hlist_del_rcu(&orig_entry->list); in _batadv_tt_global_del_orig_entry()
2048 spin_lock_bh(&tt_global_entry->list_lock); in batadv_tt_global_del_orig_list()
2049 head = &tt_global_entry->orig_list; in batadv_tt_global_del_orig_list()
2052 spin_unlock_bh(&tt_global_entry->list_lock); in batadv_tt_global_del_orig_list()
2056 * batadv_tt_global_del_orig_node() - remove orig_node from a global tt entry
2057 * @bat_priv: the bat priv with all the soft interface information
2076 spin_lock_bh(&tt_global_entry->list_lock); in batadv_tt_global_del_orig_node()
2077 head = &tt_global_entry->orig_list; in batadv_tt_global_del_orig_node()
2079 if (orig_entry->orig_node == orig_node) { in batadv_tt_global_del_orig_node()
2080 vid = tt_global_entry->common.vid; in batadv_tt_global_del_orig_node()
2083 orig_node->orig, in batadv_tt_global_del_orig_node()
2084 tt_global_entry->common.addr, in batadv_tt_global_del_orig_node()
2090 spin_unlock_bh(&tt_global_entry->list_lock); in batadv_tt_global_del_orig_node()
2112 head = &tt_global_entry->orig_list; in batadv_tt_global_del_roaming()
2114 if (orig_entry->orig_node != orig_node) { in batadv_tt_global_del_roaming()
2123 tt_global_entry->common.flags |= BATADV_TT_CLIENT_ROAM; in batadv_tt_global_del_roaming()
2124 tt_global_entry->roam_at = jiffies; in batadv_tt_global_del_roaming()
2135 * batadv_tt_global_del() - remove a client from the global table
2136 * @bat_priv: the bat priv with all the soft interface information
2160 if (hlist_empty(&tt_global_entry->orig_list)) in batadv_tt_global_del()
2181 tt_global_entry->common.addr, in batadv_tt_global_del()
2199 * batadv_tt_global_del_orig() - remove all the TT global entries belonging to
2201 * @bat_priv: the bat priv with all the soft interface information
2215 struct batadv_hashtable *hash = bat_priv->tt.global_hash; in batadv_tt_global_del_orig()
2224 for (i = 0; i < hash->size; i++) { in batadv_tt_global_del_orig()
2225 head = &hash->table[i]; in batadv_tt_global_del_orig()
2226 list_lock = &hash->list_locks[i]; in batadv_tt_global_del_orig()
2232 if (match_vid >= 0 && tt_common_entry->vid != match_vid) in batadv_tt_global_del_orig()
2242 if (hlist_empty(&tt_global->orig_list)) { in batadv_tt_global_del_orig()
2243 vid = tt_global->common.vid; in batadv_tt_global_del_orig()
2246 tt_global->common.addr, in batadv_tt_global_del_orig()
2248 hlist_del_rcu(&tt_common_entry->hash_entry); in batadv_tt_global_del_orig()
2254 clear_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized); in batadv_tt_global_del_orig()
2264 if ((tt_global->common.flags & BATADV_TT_CLIENT_ROAM) && in batadv_tt_global_to_purge()
2265 batadv_has_timed_out(tt_global->roam_at, roam_timeout)) { in batadv_tt_global_to_purge()
2270 if ((tt_global->common.flags & BATADV_TT_CLIENT_TEMP) && in batadv_tt_global_to_purge()
2271 batadv_has_timed_out(tt_global->common.added_at, temp_timeout)) { in batadv_tt_global_to_purge()
2281 struct batadv_hashtable *hash = bat_priv->tt.global_hash; in batadv_tt_global_purge()
2290 for (i = 0; i < hash->size; i++) { in batadv_tt_global_purge()
2291 head = &hash->table[i]; in batadv_tt_global_purge()
2292 list_lock = &hash->list_locks[i]; in batadv_tt_global_purge()
2306 tt_global->common.addr, in batadv_tt_global_purge()
2307 batadv_print_vid(tt_global->common.vid), in batadv_tt_global_purge()
2310 hlist_del_rcu(&tt_common->hash_entry); in batadv_tt_global_purge()
2328 if (!bat_priv->tt.global_hash) in batadv_tt_global_table_free()
2331 hash = bat_priv->tt.global_hash; in batadv_tt_global_table_free()
2333 for (i = 0; i < hash->size; i++) { in batadv_tt_global_table_free()
2334 head = &hash->table[i]; in batadv_tt_global_table_free()
2335 list_lock = &hash->list_locks[i]; in batadv_tt_global_table_free()
2340 hlist_del_rcu(&tt_common_entry->hash_entry); in batadv_tt_global_table_free()
2351 bat_priv->tt.global_hash = NULL; in batadv_tt_global_table_free()
2358 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_WIFI && in _batadv_is_ap_isolated()
2359 tt_global_entry->common.flags & BATADV_TT_CLIENT_WIFI) in _batadv_is_ap_isolated()
2363 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_ISOLA && in _batadv_is_ap_isolated()
2364 tt_global_entry->common.flags & BATADV_TT_CLIENT_ISOLA) in _batadv_is_ap_isolated()
2371 * batadv_transtable_search() - get the mesh destination for a given client
2372 * @bat_priv: the bat priv with all the soft interface information
2397 (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)) in batadv_transtable_search()
2416 orig_node = best_entry->orig_node; in batadv_transtable_search()
2417 if (orig_node && !kref_get_unless_zero(&orig_node->refcount)) in batadv_transtable_search()
2429 * batadv_tt_global_crc() - calculates the checksum of the local table belonging
2431 * @bat_priv: the bat priv with all the soft interface information
2456 struct batadv_hashtable *hash = bat_priv->tt.global_hash; in batadv_tt_global_crc()
2465 for (i = 0; i < hash->size; i++) { in batadv_tt_global_crc()
2466 head = &hash->table[i]; in batadv_tt_global_crc()
2476 if (tt_common->vid != vid) in batadv_tt_global_crc()
2484 if (tt_common->flags & BATADV_TT_CLIENT_ROAM) in batadv_tt_global_crc()
2490 if (tt_common->flags & BATADV_TT_CLIENT_TEMP) in batadv_tt_global_crc()
2504 tmp_vid = htons(tt_common->vid); in batadv_tt_global_crc()
2510 flags = tt_orig->flags; in batadv_tt_global_crc()
2513 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN); in batadv_tt_global_crc()
2524 * batadv_tt_local_crc() - calculates the checksum of the local table
2525 * @bat_priv: the bat priv with all the soft interface information
2536 struct batadv_hashtable *hash = bat_priv->tt.local_hash; in batadv_tt_local_crc()
2543 for (i = 0; i < hash->size; i++) { in batadv_tt_local_crc()
2544 head = &hash->table[i]; in batadv_tt_local_crc()
2551 if (tt_common->vid != vid) in batadv_tt_local_crc()
2557 if (tt_common->flags & BATADV_TT_CLIENT_NEW) in batadv_tt_local_crc()
2563 tmp_vid = htons(tt_common->vid); in batadv_tt_local_crc()
2569 flags = tt_common->flags & BATADV_TT_SYNC_MASK; in batadv_tt_local_crc()
2572 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN); in batadv_tt_local_crc()
2581 * batadv_tt_req_node_release() - free tt_req node entry
2594 * batadv_tt_req_node_put() - decrement the tt_req_node refcounter and
2603 kref_put(&tt_req_node->refcount, batadv_tt_req_node_release); in batadv_tt_req_node_put()
2611 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_list_free()
2613 hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { in batadv_tt_req_list_free()
2614 hlist_del_init(&node->list); in batadv_tt_req_list_free()
2618 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_list_free()
2629 spin_lock_bh(&orig_node->tt_buff_lock); in batadv_tt_save_orig_buffer()
2631 kfree(orig_node->tt_buff); in batadv_tt_save_orig_buffer()
2632 orig_node->tt_buff_len = 0; in batadv_tt_save_orig_buffer()
2633 orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC); in batadv_tt_save_orig_buffer()
2634 if (orig_node->tt_buff) { in batadv_tt_save_orig_buffer()
2635 memcpy(orig_node->tt_buff, tt_buff, tt_buff_len); in batadv_tt_save_orig_buffer()
2636 orig_node->tt_buff_len = tt_buff_len; in batadv_tt_save_orig_buffer()
2639 spin_unlock_bh(&orig_node->tt_buff_lock); in batadv_tt_save_orig_buffer()
2647 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_purge()
2648 hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { in batadv_tt_req_purge()
2649 if (batadv_has_timed_out(node->issued_at, in batadv_tt_req_purge()
2651 hlist_del_init(&node->list); in batadv_tt_req_purge()
2655 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_purge()
2659 * batadv_tt_req_node_new() - search and possibly create a tt_req_node object
2660 * @bat_priv: the bat priv with all the soft interface information
2672 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_node_new()
2673 hlist_for_each_entry(tt_req_node_tmp, &bat_priv->tt.req_list, list) { in batadv_tt_req_node_new()
2675 !batadv_has_timed_out(tt_req_node_tmp->issued_at, in batadv_tt_req_node_new()
2684 kref_init(&tt_req_node->refcount); in batadv_tt_req_node_new()
2685 ether_addr_copy(tt_req_node->addr, orig_node->orig); in batadv_tt_req_node_new()
2686 tt_req_node->issued_at = jiffies; in batadv_tt_req_node_new()
2688 kref_get(&tt_req_node->refcount); in batadv_tt_req_node_new()
2689 hlist_add_head(&tt_req_node->list, &bat_priv->tt.req_list); in batadv_tt_req_node_new()
2691 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_node_new()
2696 * batadv_tt_local_valid() - verify local tt entry and get flags
2712 if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW) in batadv_tt_local_valid()
2716 *flags = tt_common_entry->flags; in batadv_tt_local_valid()
2722 * batadv_tt_global_valid() - verify global tt entry and get flags
2741 if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM || in batadv_tt_global_valid()
2742 tt_common_entry->flags & BATADV_TT_CLIENT_TEMP) in batadv_tt_global_valid()
2754 * batadv_tt_tvlv_generate() - fill the tvlv buff with the tt entries from the
2756 * @bat_priv: the bat priv with all the soft interface information
2764 * is not provided then this becomes a no-op.
2791 for (i = 0; i < hash->size; i++) { in batadv_tt_tvlv_generate()
2792 head = &hash->table[i]; in batadv_tt_tvlv_generate()
2803 ether_addr_copy(tt_change->addr, tt_common_entry->addr); in batadv_tt_tvlv_generate()
2804 tt_change->flags = flags; in batadv_tt_tvlv_generate()
2805 tt_change->vid = htons(tt_common_entry->vid); in batadv_tt_tvlv_generate()
2806 memset(tt_change->reserved, 0, in batadv_tt_tvlv_generate()
2807 sizeof(tt_change->reserved)); in batadv_tt_tvlv_generate()
2815 return batadv_tt_len(tt_tot - tt_num_entries); in batadv_tt_tvlv_generate()
2819 * batadv_tt_global_check_crc() - check if all the CRCs are correct
2843 if (batadv_bla_is_backbone_gw_orig(orig_node->bat_priv, in batadv_tt_global_check_crc()
2844 orig_node->orig, in batadv_tt_global_check_crc()
2845 ntohs(tt_vlan_tmp->vid))) in batadv_tt_global_check_crc()
2849 ntohs(tt_vlan_tmp->vid)); in batadv_tt_global_check_crc()
2853 crc = vlan->tt.crc; in batadv_tt_global_check_crc()
2856 if (crc != ntohl(tt_vlan_tmp->crc)) in batadv_tt_global_check_crc()
2865 hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) in batadv_tt_global_check_crc()
2876 * batadv_tt_local_update_crc() - update all the local CRCs
2877 * @bat_priv: the bat priv with all the soft interface information
2885 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { in batadv_tt_local_update_crc()
2886 vlan->tt.crc = batadv_tt_local_crc(bat_priv, vlan->vid); in batadv_tt_local_update_crc()
2892 * batadv_tt_global_update_crc() - update all the global CRCs for this orig_node
2893 * @bat_priv: the bat priv with all the soft interface information
2904 hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) { in batadv_tt_global_update_crc()
2908 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, in batadv_tt_global_update_crc()
2909 vlan->vid)) in batadv_tt_global_update_crc()
2912 crc = batadv_tt_global_crc(bat_priv, orig_node, vlan->vid); in batadv_tt_global_update_crc()
2913 vlan->tt.crc = crc; in batadv_tt_global_update_crc()
2919 * batadv_send_tt_request() - send a TT Request message to a given node
2920 * @bat_priv: the bat priv with all the soft interface information
2959 tvlv_tt_data->flags = BATADV_TT_REQUEST; in batadv_send_tt_request()
2960 tvlv_tt_data->ttvn = ttvn; in batadv_send_tt_request()
2961 tvlv_tt_data->num_vlan = htons(num_vlan); in batadv_send_tt_request()
2968 tt_vlan_req->vid = tt_vlan->vid; in batadv_send_tt_request()
2969 tt_vlan_req->crc = tt_vlan->crc; in batadv_send_tt_request()
2976 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE; in batadv_send_tt_request()
2979 dst_orig_node->orig, full_table ? 'F' : '.'); in batadv_send_tt_request()
2982 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr, in batadv_send_tt_request()
2983 dst_orig_node->orig, BATADV_TVLV_TT, 1, in batadv_send_tt_request()
2991 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_send_tt_request()
2992 if (!hlist_unhashed(&tt_req_node->list)) { in batadv_send_tt_request()
2993 hlist_del_init(&tt_req_node->list); in batadv_send_tt_request()
2996 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_send_tt_request()
3006 * batadv_send_other_tt_response() - send reply to tt request concerning another
3008 * @bat_priv: the bat priv with all the soft interface information
3031 req_src, tt_data->ttvn, req_dst, in batadv_send_other_tt_response()
3032 ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.')); in batadv_send_other_tt_response()
3043 orig_ttvn = (u8)atomic_read(&req_dst_orig_node->last_ttvn); in batadv_send_other_tt_response()
3044 req_ttvn = tt_data->ttvn; in batadv_send_other_tt_response()
3050 ntohs(tt_data->num_vlan))) in batadv_send_other_tt_response()
3054 if (tt_data->flags & BATADV_TT_FULL_TABLE || in batadv_send_other_tt_response()
3055 !req_dst_orig_node->tt_buff) in batadv_send_other_tt_response()
3064 spin_lock_bh(&req_dst_orig_node->tt_buff_lock); in batadv_send_other_tt_response()
3065 tt_len = req_dst_orig_node->tt_buff_len; in batadv_send_other_tt_response()
3075 memcpy(tt_change, req_dst_orig_node->tt_buff, in batadv_send_other_tt_response()
3076 req_dst_orig_node->tt_buff_len); in batadv_send_other_tt_response()
3077 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); in batadv_send_other_tt_response()
3082 tt_len = -1; in batadv_send_other_tt_response()
3091 tvlv_len -= batadv_tt_tvlv_generate(bat_priv, in batadv_send_other_tt_response()
3092 bat_priv->tt.global_hash, in batadv_send_other_tt_response()
3100 if (tt_len > atomic_read(&bat_priv->packet_size_max)) { in batadv_send_other_tt_response()
3101 net_ratelimited_function(batadv_info, bat_priv->soft_iface, in batadv_send_other_tt_response()
3103 res_dst_orig_node->orig); in batadv_send_other_tt_response()
3107 tvlv_tt_data->flags = BATADV_TT_RESPONSE; in batadv_send_other_tt_response()
3108 tvlv_tt_data->ttvn = req_ttvn; in batadv_send_other_tt_response()
3111 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE; in batadv_send_other_tt_response()
3115 res_dst_orig_node->orig, req_dst_orig_node->orig, in batadv_send_other_tt_response()
3120 batadv_tvlv_unicast_send(bat_priv, req_dst_orig_node->orig, in batadv_send_other_tt_response()
3128 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); in batadv_send_other_tt_response()
3138 * batadv_send_my_tt_response() - send reply to tt request concerning this
3140 * @bat_priv: the bat priv with all the soft interface information
3161 req_src, tt_data->ttvn, in batadv_send_my_tt_response()
3162 ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.')); in batadv_send_my_tt_response()
3164 spin_lock_bh(&bat_priv->tt.commit_lock); in batadv_send_my_tt_response()
3166 my_ttvn = (u8)atomic_read(&bat_priv->tt.vn); in batadv_send_my_tt_response()
3167 req_ttvn = tt_data->ttvn; in batadv_send_my_tt_response()
3180 if (tt_data->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn || in batadv_send_my_tt_response()
3181 !bat_priv->tt.last_changeset) in batadv_send_my_tt_response()
3190 spin_lock_bh(&bat_priv->tt.last_changeset_lock); in batadv_send_my_tt_response()
3192 tt_len = bat_priv->tt.last_changeset_len; in batadv_send_my_tt_response()
3201 memcpy(tt_change, bat_priv->tt.last_changeset, in batadv_send_my_tt_response()
3202 bat_priv->tt.last_changeset_len); in batadv_send_my_tt_response()
3203 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); in batadv_send_my_tt_response()
3205 req_ttvn = (u8)atomic_read(&bat_priv->tt.vn); in batadv_send_my_tt_response()
3210 tt_len = -1; in batadv_send_my_tt_response()
3219 tvlv_len -= batadv_tt_tvlv_generate(bat_priv, in batadv_send_my_tt_response()
3220 bat_priv->tt.local_hash, in batadv_send_my_tt_response()
3226 tvlv_tt_data->flags = BATADV_TT_RESPONSE; in batadv_send_my_tt_response()
3227 tvlv_tt_data->ttvn = req_ttvn; in batadv_send_my_tt_response()
3230 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE; in batadv_send_my_tt_response()
3234 orig_node->orig, full_table ? 'F' : '.', req_ttvn); in batadv_send_my_tt_response()
3238 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr, in batadv_send_my_tt_response()
3245 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); in batadv_send_my_tt_response()
3247 spin_unlock_bh(&bat_priv->tt.commit_lock); in batadv_send_my_tt_response()
3251 /* The packet was for this host, so it doesn't need to be re-routed */ in batadv_send_my_tt_response()
3256 * batadv_send_tt_response() - send reply to tt request
3257 * @bat_priv: the bat priv with all the soft interface information
3283 if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) { in _batadv_tt_update_changes()
3284 roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM; in _batadv_tt_update_changes()
3286 (tt_change + i)->addr, in _batadv_tt_update_changes()
3287 ntohs((tt_change + i)->vid), in _batadv_tt_update_changes()
3292 (tt_change + i)->addr, in _batadv_tt_update_changes()
3293 ntohs((tt_change + i)->vid), in _batadv_tt_update_changes()
3294 (tt_change + i)->flags, ttvn)) in _batadv_tt_update_changes()
3304 set_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized); in _batadv_tt_update_changes()
3319 batadv_tt_global_del_orig(bat_priv, orig_node, -1, in batadv_tt_fill_gtable()
3325 spin_lock_bh(&orig_node->tt_buff_lock); in batadv_tt_fill_gtable()
3326 kfree(orig_node->tt_buff); in batadv_tt_fill_gtable()
3327 orig_node->tt_buff_len = 0; in batadv_tt_fill_gtable()
3328 orig_node->tt_buff = NULL; in batadv_tt_fill_gtable()
3329 spin_unlock_bh(&orig_node->tt_buff_lock); in batadv_tt_fill_gtable()
3331 atomic_set(&orig_node->last_ttvn, ttvn); in batadv_tt_fill_gtable()
3347 atomic_set(&orig_node->last_ttvn, ttvn); in batadv_tt_update_changes()
3351 * batadv_is_my_client() - check if a client is served by the local node
3352 * @bat_priv: the bat priv with all the soft interface information
3370 if ((tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) || in batadv_is_my_client()
3371 (tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM)) in batadv_is_my_client()
3380 * batadv_handle_tt_response() - process incoming tt reply
3381 * @bat_priv: the bat priv with all the soft interface information
3399 resp_src, tt_data->ttvn, num_entries, in batadv_handle_tt_response()
3400 ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.')); in batadv_handle_tt_response()
3406 spin_lock_bh(&orig_node->tt_lock); in batadv_handle_tt_response()
3409 change_offset *= ntohs(tt_data->num_vlan); in batadv_handle_tt_response()
3414 if (tt_data->flags & BATADV_TT_FULL_TABLE) { in batadv_handle_tt_response()
3415 batadv_tt_fill_gtable(bat_priv, tt_change, tt_data->ttvn, in batadv_handle_tt_response()
3419 tt_data->ttvn, tt_change); in batadv_handle_tt_response()
3425 spin_unlock_bh(&orig_node->tt_lock); in batadv_handle_tt_response()
3428 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_handle_tt_response()
3429 hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { in batadv_handle_tt_response()
3430 if (!batadv_compare_eth(node->addr, resp_src)) in batadv_handle_tt_response()
3432 hlist_del_init(&node->list); in batadv_handle_tt_response()
3436 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_handle_tt_response()
3445 spin_lock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_roam_list_free()
3447 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { in batadv_tt_roam_list_free()
3448 list_del(&node->list); in batadv_tt_roam_list_free()
3452 spin_unlock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_roam_list_free()
3459 spin_lock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_roam_purge()
3460 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { in batadv_tt_roam_purge()
3461 if (!batadv_has_timed_out(node->first_time, in batadv_tt_roam_purge()
3465 list_del(&node->list); in batadv_tt_roam_purge()
3468 spin_unlock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_roam_purge()
3472 * batadv_tt_check_roam_count() - check if a client has roamed too frequently
3473 * @bat_priv: the bat priv with all the soft interface information
3487 spin_lock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_check_roam_count()
3491 list_for_each_entry(tt_roam_node, &bat_priv->tt.roam_list, list) { in batadv_tt_check_roam_count()
3492 if (!batadv_compare_eth(tt_roam_node->addr, client)) in batadv_tt_check_roam_count()
3495 if (batadv_has_timed_out(tt_roam_node->first_time, in batadv_tt_check_roam_count()
3499 if (!batadv_atomic_dec_not_zero(&tt_roam_node->counter)) in batadv_tt_check_roam_count()
3512 tt_roam_node->first_time = jiffies; in batadv_tt_check_roam_count()
3513 atomic_set(&tt_roam_node->counter, in batadv_tt_check_roam_count()
3514 BATADV_ROAMING_MAX_COUNT - 1); in batadv_tt_check_roam_count()
3515 ether_addr_copy(tt_roam_node->addr, client); in batadv_tt_check_roam_count()
3517 list_add(&tt_roam_node->list, &bat_priv->tt.roam_list); in batadv_tt_check_roam_count()
3522 spin_unlock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_check_roam_count()
3527 * batadv_send_roam_adv() - send a roaming advertisement message
3528 * @bat_priv: the bat priv with all the soft interface information
3557 orig_node->orig, client, batadv_print_vid(vid)); in batadv_send_roam_adv()
3564 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr, in batadv_send_roam_adv()
3565 orig_node->orig, BATADV_TVLV_ROAM, 1, in batadv_send_roam_adv()
3587 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work, in batadv_tt_purge()
3592 * batadv_tt_free() - Free translation table of soft interface
3593 * @bat_priv: the bat priv with all the soft interface information
3602 cancel_delayed_work_sync(&bat_priv->tt.work); in batadv_tt_free()
3610 kfree(bat_priv->tt.last_changeset); in batadv_tt_free()
3614 * batadv_tt_local_set_flags() - set or unset the specified flags on the local
3616 * @bat_priv: the bat priv with all the soft interface information
3624 struct batadv_hashtable *hash = bat_priv->tt.local_hash; in batadv_tt_local_set_flags()
3632 for (i = 0; i < hash->size; i++) { in batadv_tt_local_set_flags()
3633 head = &hash->table[i]; in batadv_tt_local_set_flags()
3639 if ((tt_common_entry->flags & flags) == flags) in batadv_tt_local_set_flags()
3641 tt_common_entry->flags |= flags; in batadv_tt_local_set_flags()
3643 if (!(tt_common_entry->flags & flags)) in batadv_tt_local_set_flags()
3645 tt_common_entry->flags &= ~flags; in batadv_tt_local_set_flags()
3652 tt_common_entry->vid); in batadv_tt_local_set_flags()
3661 struct batadv_hashtable *hash = bat_priv->tt.local_hash; in batadv_tt_local_purge_pending_clients()
3672 for (i = 0; i < hash->size; i++) { in batadv_tt_local_purge_pending_clients()
3673 head = &hash->table[i]; in batadv_tt_local_purge_pending_clients()
3674 list_lock = &hash->list_locks[i]; in batadv_tt_local_purge_pending_clients()
3679 if (!(tt_common->flags & BATADV_TT_CLIENT_PENDING)) in batadv_tt_local_purge_pending_clients()
3684 tt_common->addr, in batadv_tt_local_purge_pending_clients()
3685 batadv_print_vid(tt_common->vid)); in batadv_tt_local_purge_pending_clients()
3687 batadv_tt_local_size_dec(bat_priv, tt_common->vid); in batadv_tt_local_purge_pending_clients()
3688 hlist_del_rcu(&tt_common->hash_entry); in batadv_tt_local_purge_pending_clients()
3700 * batadv_tt_local_commit_changes_nolock() - commit all pending local tt changes
3702 * @bat_priv: the bat priv with all the soft interface information
3704 * Caller must hold tt->commit_lock.
3708 lockdep_assert_held(&bat_priv->tt.commit_lock); in batadv_tt_local_commit_changes_nolock()
3710 if (atomic_read(&bat_priv->tt.local_changes) < 1) { in batadv_tt_local_commit_changes_nolock()
3711 if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt)) in batadv_tt_local_commit_changes_nolock()
3722 atomic_inc(&bat_priv->tt.vn); in batadv_tt_local_commit_changes_nolock()
3725 (u8)atomic_read(&bat_priv->tt.vn)); in batadv_tt_local_commit_changes_nolock()
3728 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); in batadv_tt_local_commit_changes_nolock()
3733 * batadv_tt_local_commit_changes() - commit all pending local tt changes which
3735 * @bat_priv: the bat priv with all the soft interface information
3739 spin_lock_bh(&bat_priv->tt.commit_lock); in batadv_tt_local_commit_changes()
3741 spin_unlock_bh(&bat_priv->tt.commit_lock); in batadv_tt_local_commit_changes()
3745 * batadv_is_ap_isolated() - Check if packet from upper layer should be dropped
3746 * @bat_priv: the bat priv with all the soft interface information
3765 if (!atomic_read(&vlan->ap_isolation)) in batadv_is_ap_isolated()
3788 * batadv_tt_update_orig() - update global translation table with new tt
3790 * @bat_priv: the bat priv with all the soft interface information
3804 u8 orig_ttvn = (u8)atomic_read(&orig_node->last_ttvn); in batadv_tt_update_orig()
3811 &orig_node->capa_initialized); in batadv_tt_update_orig()
3814 * increased by one -> we can apply the attached changes in batadv_tt_update_orig()
3816 if ((!has_tt_init && ttvn == 1) || ttvn - orig_ttvn == 1) { in batadv_tt_update_orig()
3827 spin_lock_bh(&orig_node->tt_lock); in batadv_tt_update_orig()
3838 spin_unlock_bh(&orig_node->tt_lock); in batadv_tt_update_orig()
3854 * in sync anymore -> request fresh tt data in batadv_tt_update_orig()
3862 orig_node->orig, ttvn, orig_ttvn, in batadv_tt_update_orig()
3873 * batadv_tt_global_client_is_roaming() - check if a client is marked as roaming
3874 * @bat_priv: the bat priv with all the soft interface information
3892 ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM; in batadv_tt_global_client_is_roaming()
3899 * batadv_tt_local_client_is_roaming() - tells whether the client is roaming
3900 * @bat_priv: the bat priv with all the soft interface information
3918 ret = tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM; in batadv_tt_local_client_is_roaming()
3925 * batadv_tt_add_temporary_global_entry() - Add temporary entry to global TT
3926 * @bat_priv: the bat priv with all the soft interface information
3946 atomic_read(&orig_node->last_ttvn))) in batadv_tt_add_temporary_global_entry()
3951 addr, batadv_print_vid(vid), orig_node->orig); in batadv_tt_add_temporary_global_entry()
3957 * batadv_tt_local_resize_to_mtu() - resize the local translation table fit the
3967 int packet_size_max = atomic_read(&bat_priv->packet_size_max); in batadv_tt_local_resize_to_mtu()
3971 spin_lock_bh(&bat_priv->tt.commit_lock); in batadv_tt_local_resize_to_mtu()
3994 spin_unlock_bh(&bat_priv->tt.commit_lock); in batadv_tt_local_resize_to_mtu()
3998 * batadv_tt_tvlv_ogm_handler_v1() - process incoming tt tvlv container
3999 * @bat_priv: the bat priv with all the soft interface information
4019 tvlv_value_len -= sizeof(*tt_data); in batadv_tt_tvlv_ogm_handler_v1()
4021 num_vlan = ntohs(tt_data->num_vlan); in batadv_tt_tvlv_ogm_handler_v1()
4028 tvlv_value_len -= sizeof(*tt_vlan) * num_vlan; in batadv_tt_tvlv_ogm_handler_v1()
4033 num_entries, tt_data->ttvn); in batadv_tt_tvlv_ogm_handler_v1()
4037 * batadv_tt_tvlv_unicast_handler_v1() - process incoming (unicast) tt tvlv
4039 * @bat_priv: the bat priv with all the soft interface information
4045 * Return: NET_RX_DROP if the tt tvlv is to be re-routed, NET_RX_SUCCESS
4062 tvlv_value_len -= sizeof(*tt_data); in batadv_tt_tvlv_unicast_handler_v1()
4065 tt_vlan_len *= ntohs(tt_data->num_vlan); in batadv_tt_tvlv_unicast_handler_v1()
4070 tvlv_value_len -= tt_vlan_len; in batadv_tt_tvlv_unicast_handler_v1()
4073 switch (tt_data->flags & BATADV_TT_DATA_TYPE_MASK) { in batadv_tt_tvlv_unicast_handler_v1()
4082 if (tt_data->flags & BATADV_TT_FULL_TABLE) in batadv_tt_tvlv_unicast_handler_v1()
4090 /* tvlv API will re-route the packet */ in batadv_tt_tvlv_unicast_handler_v1()
4103 if (tt_data->flags & BATADV_TT_FULL_TABLE) in batadv_tt_tvlv_unicast_handler_v1()
4111 /* tvlv API will re-route the packet */ in batadv_tt_tvlv_unicast_handler_v1()
4119 * batadv_roam_tvlv_unicast_handler_v1() - process incoming tt roam tvlv
4121 * @bat_priv: the bat priv with all the soft interface information
4127 * Return: NET_RX_DROP if the tt roam tvlv is to be re-routed, NET_RX_SUCCESS
4140 * (the tvlv API will re-route the packet). in batadv_roam_tvlv_unicast_handler_v1()
4157 src, roaming_adv->client); in batadv_roam_tvlv_unicast_handler_v1()
4159 batadv_tt_global_add(bat_priv, orig_node, roaming_adv->client, in batadv_roam_tvlv_unicast_handler_v1()
4160 ntohs(roaming_adv->vid), BATADV_TT_CLIENT_ROAM, in batadv_roam_tvlv_unicast_handler_v1()
4161 atomic_read(&orig_node->last_ttvn) + 1); in batadv_roam_tvlv_unicast_handler_v1()
4169 * batadv_tt_init() - initialise the translation table internals
4170 * @bat_priv: the bat priv with all the soft interface information
4199 INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge); in batadv_tt_init()
4200 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work, in batadv_tt_init()
4207 * batadv_tt_global_is_isolated() - check if a client is marked as isolated
4208 * @bat_priv: the bat priv with all the soft interface information
4225 ret = tt->common.flags & BATADV_TT_CLIENT_ISOLA; in batadv_tt_global_is_isolated()
4233 * batadv_tt_cache_init() - Initialize tt memory object cache
4249 return -ENOMEM; in batadv_tt_cache_init()
4298 return -ENOMEM; in batadv_tt_cache_init()
4302 * batadv_tt_cache_destroy() - Destroy tt memory object cache