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
995 tt_diff_entries_num = atomic_read(&bat_priv->tt.local_changes); in batadv_tt_tvlv_container_update()
1001 if (tt_diff_len > bat_priv->soft_iface->mtu) in batadv_tt_tvlv_container_update()
1009 tt_data->flags = BATADV_TT_OGM_DIFF; in batadv_tt_tvlv_container_update()
1014 spin_lock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_tvlv_container_update()
1015 atomic_set(&bat_priv->tt.local_changes, 0); in batadv_tt_tvlv_container_update()
1017 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, in batadv_tt_tvlv_container_update()
1021 &entry->change, in batadv_tt_tvlv_container_update()
1025 list_del(&entry->list); in batadv_tt_tvlv_container_update()
1028 spin_unlock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_tvlv_container_update()
1031 spin_lock_bh(&bat_priv->tt.last_changeset_lock); in batadv_tt_tvlv_container_update()
1032 kfree(bat_priv->tt.last_changeset); in batadv_tt_tvlv_container_update()
1033 bat_priv->tt.last_changeset_len = 0; in batadv_tt_tvlv_container_update()
1034 bat_priv->tt.last_changeset = NULL; in batadv_tt_tvlv_container_update()
1041 bat_priv->tt.last_changeset = kzalloc(tt_diff_len, GFP_ATOMIC); in batadv_tt_tvlv_container_update()
1042 if (bat_priv->tt.last_changeset) { in batadv_tt_tvlv_container_update()
1043 memcpy(bat_priv->tt.last_changeset, in batadv_tt_tvlv_container_update()
1045 bat_priv->tt.last_changeset_len = tt_diff_len; in batadv_tt_tvlv_container_update()
1048 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); in batadv_tt_tvlv_container_update()
1057 * batadv_tt_local_dump_entry() - Dump one TT local entry into a message
1061 * @bat_priv: The bat priv with all the soft interface information
1079 last_seen_msecs = jiffies_to_msecs(jiffies - local->last_seen); in batadv_tt_local_dump_entry()
1081 vlan = batadv_softif_vlan_get(bat_priv, common->vid); in batadv_tt_local_dump_entry()
1085 crc = vlan->tt.crc; in batadv_tt_local_dump_entry()
1089 hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq, in batadv_tt_local_dump_entry()
1093 return -ENOBUFS; in batadv_tt_local_dump_entry()
1097 if (nla_put(msg, BATADV_ATTR_TT_ADDRESS, ETH_ALEN, common->addr) || in batadv_tt_local_dump_entry()
1099 nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) || in batadv_tt_local_dump_entry()
1100 nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, common->flags)) in batadv_tt_local_dump_entry()
1103 if (!(common->flags & BATADV_TT_CLIENT_NOPURGE) && in batadv_tt_local_dump_entry()
1112 return -EMSGSIZE; in batadv_tt_local_dump_entry()
1116 * batadv_tt_local_dump_bucket() - Dump one TT local bucket into a message
1120 * @bat_priv: The bat priv with all the soft interface information
1137 spin_lock_bh(&hash->list_locks[bucket]); in batadv_tt_local_dump_bucket()
1138 cb->seq = atomic_read(&hash->generation) << 1 | 1; in batadv_tt_local_dump_bucket()
1140 hlist_for_each_entry(common, &hash->table[bucket], hash_entry) { in batadv_tt_local_dump_bucket()
1146 spin_unlock_bh(&hash->list_locks[bucket]); in batadv_tt_local_dump_bucket()
1147 *idx_s = idx - 1; in batadv_tt_local_dump_bucket()
1148 return -EMSGSIZE; in batadv_tt_local_dump_bucket()
1151 spin_unlock_bh(&hash->list_locks[bucket]); in batadv_tt_local_dump_bucket()
1158 * batadv_tt_local_dump() - Dump TT local entries into a message
1166 struct net *net = sock_net(cb->skb->sk); in batadv_tt_local_dump()
1173 int bucket = cb->args[0]; in batadv_tt_local_dump()
1174 int idx = cb->args[1]; in batadv_tt_local_dump()
1175 int portid = NETLINK_CB(cb->skb).portid; in batadv_tt_local_dump()
1177 ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX); in batadv_tt_local_dump()
1179 return -EINVAL; in batadv_tt_local_dump()
1183 ret = -ENODEV; in batadv_tt_local_dump()
1190 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { in batadv_tt_local_dump()
1191 ret = -ENOENT; in batadv_tt_local_dump()
1195 hash = bat_priv->tt.local_hash; in batadv_tt_local_dump()
1197 while (bucket < hash->size) { in batadv_tt_local_dump()
1205 ret = msg->len; in batadv_tt_local_dump()
1211 cb->args[0] = bucket; in batadv_tt_local_dump()
1212 cb->args[1] = idx; in batadv_tt_local_dump()
1228 tt_local_entry->common.flags |= BATADV_TT_CLIENT_PENDING; in batadv_tt_local_set_pending()
1232 tt_local_entry->common.addr, in batadv_tt_local_set_pending()
1233 batadv_print_vid(tt_local_entry->common.vid), message); in batadv_tt_local_set_pending()
1237 * batadv_tt_local_remove() - logically remove an entry from the local table
1238 * @bat_priv: the bat priv with all the soft interface information
1259 curr_flags = tt_local_entry->common.flags; in batadv_tt_local_remove()
1269 tt_local_entry->common.flags |= BATADV_TT_CLIENT_ROAM; in batadv_tt_local_remove()
1272 if (!(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) { in batadv_tt_local_remove()
1282 tt_removed_node = batadv_hash_remove(bat_priv->tt.local_hash, in batadv_tt_local_remove()
1285 &tt_local_entry->common); in batadv_tt_local_remove()
1302 * batadv_tt_local_purge_list() - purge inactive tt local entries
1303 * @bat_priv: the bat priv with all the soft interface information
1321 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_NOPURGE) in batadv_tt_local_purge_list()
1325 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) in batadv_tt_local_purge_list()
1328 if (!batadv_has_timed_out(tt_local_entry->last_seen, timeout)) in batadv_tt_local_purge_list()
1337 * batadv_tt_local_purge() - purge inactive tt local entries
1338 * @bat_priv: the bat priv with all the soft interface information
1345 struct batadv_hashtable *hash = bat_priv->tt.local_hash; in batadv_tt_local_purge()
1350 for (i = 0; i < hash->size; i++) { in batadv_tt_local_purge()
1351 head = &hash->table[i]; in batadv_tt_local_purge()
1352 list_lock = &hash->list_locks[i]; in batadv_tt_local_purge()
1370 if (!bat_priv->tt.local_hash) in batadv_tt_local_table_free()
1373 hash = bat_priv->tt.local_hash; in batadv_tt_local_table_free()
1375 for (i = 0; i < hash->size; i++) { in batadv_tt_local_table_free()
1376 head = &hash->table[i]; in batadv_tt_local_table_free()
1377 list_lock = &hash->list_locks[i]; in batadv_tt_local_table_free()
1382 hlist_del_rcu(&tt_common_entry->hash_entry); in batadv_tt_local_table_free()
1394 bat_priv->tt.local_hash = NULL; in batadv_tt_local_table_free()
1399 if (bat_priv->tt.global_hash) in batadv_tt_global_init()
1402 bat_priv->tt.global_hash = batadv_hash_new(1024); in batadv_tt_global_init()
1404 if (!bat_priv->tt.global_hash) in batadv_tt_global_init()
1405 return -ENOMEM; in batadv_tt_global_init()
1407 batadv_hash_set_lock_class(bat_priv->tt.global_hash, in batadv_tt_global_init()
1417 spin_lock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_changes_list_free()
1419 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, in batadv_tt_changes_list_free()
1421 list_del(&entry->list); in batadv_tt_changes_list_free()
1425 atomic_set(&bat_priv->tt.local_changes, 0); in batadv_tt_changes_list_free()
1426 spin_unlock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_changes_list_free()
1430 * batadv_tt_global_orig_entry_find() - find a TT orig_list_entry
1448 head = &entry->orig_list; in batadv_tt_global_orig_entry_find()
1450 if (tmp_orig_entry->orig_node != orig_node) in batadv_tt_global_orig_entry_find()
1452 if (!kref_get_unless_zero(&tmp_orig_entry->refcount)) in batadv_tt_global_orig_entry_find()
1464 * batadv_tt_global_entry_has_orig() - check if a TT global entry is also
1488 *flags = orig_entry->flags; in batadv_tt_global_entry_has_orig()
1497 * batadv_tt_global_sync_flags() - update TT sync flags
1511 head = &tt_global->orig_list; in batadv_tt_global_sync_flags()
1513 flags |= orig_entry->flags; in batadv_tt_global_sync_flags()
1516 flags |= tt_global->common.flags & (~BATADV_TT_SYNC_MASK); in batadv_tt_global_sync_flags()
1517 tt_global->common.flags = flags; in batadv_tt_global_sync_flags()
1521 * batadv_tt_global_orig_entry_add() - add or update a TT orig entry
1534 spin_lock_bh(&tt_global->list_lock); in batadv_tt_global_orig_entry_add()
1541 orig_entry->ttvn = ttvn; in batadv_tt_global_orig_entry_add()
1542 orig_entry->flags = flags; in batadv_tt_global_orig_entry_add()
1550 INIT_HLIST_NODE(&orig_entry->list); in batadv_tt_global_orig_entry_add()
1551 kref_get(&orig_node->refcount); in batadv_tt_global_orig_entry_add()
1552 batadv_tt_global_size_inc(orig_node, tt_global->common.vid); in batadv_tt_global_orig_entry_add()
1553 orig_entry->orig_node = orig_node; in batadv_tt_global_orig_entry_add()
1554 orig_entry->ttvn = ttvn; in batadv_tt_global_orig_entry_add()
1555 orig_entry->flags = flags; in batadv_tt_global_orig_entry_add()
1556 kref_init(&orig_entry->refcount); in batadv_tt_global_orig_entry_add()
1558 kref_get(&orig_entry->refcount); in batadv_tt_global_orig_entry_add()
1559 hlist_add_head_rcu(&orig_entry->list, in batadv_tt_global_orig_entry_add()
1560 &tt_global->orig_list); in batadv_tt_global_orig_entry_add()
1561 atomic_inc(&tt_global->orig_list_count); in batadv_tt_global_orig_entry_add()
1568 spin_unlock_bh(&tt_global->list_lock); in batadv_tt_global_orig_entry_add()
1572 * batadv_tt_global_add() - add a new TT global entry or update an existing one
1573 * @bat_priv: the bat priv with all the soft interface information
1575 * @tt_addr: the mac address of the non-mesh client
1577 * @flags: TT flags that have to be set for this non-mesh client
1578 * @ttvn: the tt version number ever announcing this non-mesh client
1584 * If a TT local entry exists for this non-mesh client remove it.
1603 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) in batadv_tt_global_add()
1614 !(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) in batadv_tt_global_add()
1623 common = &tt_global_entry->common; in batadv_tt_global_add()
1624 ether_addr_copy(common->addr, tt_addr); in batadv_tt_global_add()
1625 common->vid = vid; in batadv_tt_global_add()
1627 if (!is_multicast_ether_addr(common->addr)) in batadv_tt_global_add()
1628 common->flags = flags & (~BATADV_TT_SYNC_MASK); in batadv_tt_global_add()
1630 tt_global_entry->roam_at = 0; in batadv_tt_global_add()
1636 tt_global_entry->roam_at = jiffies; in batadv_tt_global_add()
1637 kref_init(&common->refcount); in batadv_tt_global_add()
1638 common->added_at = jiffies; in batadv_tt_global_add()
1640 INIT_HLIST_HEAD(&tt_global_entry->orig_list); in batadv_tt_global_add()
1641 atomic_set(&tt_global_entry->orig_list_count, 0); in batadv_tt_global_add()
1642 spin_lock_init(&tt_global_entry->list_lock); in batadv_tt_global_add()
1644 kref_get(&common->refcount); in batadv_tt_global_add()
1645 hash_added = batadv_hash_add(bat_priv->tt.global_hash, in batadv_tt_global_add()
1648 &common->hash_entry); in batadv_tt_global_add()
1656 common = &tt_global_entry->common; in batadv_tt_global_add()
1668 if (!(common->flags & BATADV_TT_CLIENT_TEMP)) in batadv_tt_global_add()
1678 * OGM announcing it, we have to clear the TEMP flag. Also, in batadv_tt_global_add()
1679 * remove the previous temporary orig node and re-add it in batadv_tt_global_add()
1681 * is a non-temporary entry is preferred. in batadv_tt_global_add()
1683 if (common->flags & BATADV_TT_CLIENT_TEMP) { in batadv_tt_global_add()
1685 common->flags &= ~BATADV_TT_CLIENT_TEMP; in batadv_tt_global_add()
1692 if (!is_multicast_ether_addr(common->addr)) in batadv_tt_global_add()
1693 common->flags |= flags & (~BATADV_TT_SYNC_MASK); in batadv_tt_global_add()
1702 if (common->flags & BATADV_TT_CLIENT_ROAM) { in batadv_tt_global_add()
1704 common->flags &= ~BATADV_TT_CLIENT_ROAM; in batadv_tt_global_add()
1705 tt_global_entry->roam_at = 0; in batadv_tt_global_add()
1715 common->addr, batadv_print_vid(common->vid), in batadv_tt_global_add()
1716 orig_node->orig); in batadv_tt_global_add()
1730 tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI; in batadv_tt_global_add()
1736 tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM; in batadv_tt_global_add()
1745 * batadv_transtable_best_orig() - Get best originator list entry from tt entry
1746 * @bat_priv: the bat priv with all the soft interface information
1757 struct batadv_algo_ops *bao = bat_priv->algo_ops; in batadv_transtable_best_orig()
1761 head = &tt_global_entry->orig_list; in batadv_transtable_best_orig()
1763 router = batadv_orig_router_get(orig_entry->orig_node, in batadv_transtable_best_orig()
1769 bao->neigh.cmp(router, BATADV_IF_DEFAULT, best_router, in batadv_transtable_best_orig()
1788 * batadv_tt_global_dump_subentry() - Dump all TT local entries into a message
1793 * @orig: Originator node announcing a non-mesh client
1804 u16 flags = (common->flags & (~BATADV_TT_SYNC_MASK)) | orig->flags; in batadv_tt_global_dump_subentry()
1810 vlan = batadv_orig_node_vlan_get(orig->orig_node, in batadv_tt_global_dump_subentry()
1811 common->vid); in batadv_tt_global_dump_subentry()
1815 crc = vlan->tt.crc; in batadv_tt_global_dump_subentry()
1823 return -ENOBUFS; in batadv_tt_global_dump_subentry()
1825 last_ttvn = atomic_read(&orig->orig_node->last_ttvn); in batadv_tt_global_dump_subentry()
1827 if (nla_put(msg, BATADV_ATTR_TT_ADDRESS, ETH_ALEN, common->addr) || in batadv_tt_global_dump_subentry()
1829 orig->orig_node->orig) || in batadv_tt_global_dump_subentry()
1830 nla_put_u8(msg, BATADV_ATTR_TT_TTVN, orig->ttvn) || in batadv_tt_global_dump_subentry()
1833 nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) || in batadv_tt_global_dump_subentry()
1845 return -EMSGSIZE; in batadv_tt_global_dump_subentry()
1849 * batadv_tt_global_dump_entry() - Dump one TT global entry into a message
1853 * @bat_priv: The bat priv with all the soft interface information
1874 head = &global->orig_list; in batadv_tt_global_dump_entry()
1884 *sub_s = sub - 1; in batadv_tt_global_dump_entry()
1885 return -EMSGSIZE; in batadv_tt_global_dump_entry()
1894 * batadv_tt_global_dump_bucket() - Dump one TT local bucket into a message
1898 * @bat_priv: The bat priv with all the soft interface information
1921 *idx_s = idx - 1; in batadv_tt_global_dump_bucket()
1922 return -EMSGSIZE; in batadv_tt_global_dump_bucket()
1933 * batadv_tt_global_dump() - Dump TT global entries into a message
1941 struct net *net = sock_net(cb->skb->sk); in batadv_tt_global_dump()
1949 int bucket = cb->args[0]; in batadv_tt_global_dump()
1950 int idx = cb->args[1]; in batadv_tt_global_dump()
1951 int sub = cb->args[2]; in batadv_tt_global_dump()
1952 int portid = NETLINK_CB(cb->skb).portid; in batadv_tt_global_dump()
1954 ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX); in batadv_tt_global_dump()
1956 return -EINVAL; in batadv_tt_global_dump()
1960 ret = -ENODEV; in batadv_tt_global_dump()
1967 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { in batadv_tt_global_dump()
1968 ret = -ENOENT; in batadv_tt_global_dump()
1972 hash = bat_priv->tt.global_hash; in batadv_tt_global_dump()
1974 while (bucket < hash->size) { in batadv_tt_global_dump()
1975 head = &hash->table[bucket]; in batadv_tt_global_dump()
1978 cb->nlh->nlmsg_seq, bat_priv, in batadv_tt_global_dump()
1985 ret = msg->len; in batadv_tt_global_dump()
1991 cb->args[0] = bucket; in batadv_tt_global_dump()
1992 cb->args[1] = idx; in batadv_tt_global_dump()
1993 cb->args[2] = sub; in batadv_tt_global_dump()
1999 * _batadv_tt_global_del_orig_entry() - remove and free an orig_entry
2006 * Caller must hold tt_global_entry->list_lock and ensure orig_entry->list is
2013 lockdep_assert_held(&tt_global_entry->list_lock); in _batadv_tt_global_del_orig_entry()
2015 batadv_tt_global_size_dec(orig_entry->orig_node, in _batadv_tt_global_del_orig_entry()
2016 tt_global_entry->common.vid); in _batadv_tt_global_del_orig_entry()
2017 atomic_dec(&tt_global_entry->orig_list_count); in _batadv_tt_global_del_orig_entry()
2018 /* requires holding tt_global_entry->list_lock and orig_entry->list in _batadv_tt_global_del_orig_entry()
2021 hlist_del_rcu(&orig_entry->list); in _batadv_tt_global_del_orig_entry()
2033 spin_lock_bh(&tt_global_entry->list_lock); in batadv_tt_global_del_orig_list()
2034 head = &tt_global_entry->orig_list; in batadv_tt_global_del_orig_list()
2037 spin_unlock_bh(&tt_global_entry->list_lock); in batadv_tt_global_del_orig_list()
2041 * batadv_tt_global_del_orig_node() - remove orig_node from a global tt entry
2042 * @bat_priv: the bat priv with all the soft interface information
2061 spin_lock_bh(&tt_global_entry->list_lock); in batadv_tt_global_del_orig_node()
2062 head = &tt_global_entry->orig_list; in batadv_tt_global_del_orig_node()
2064 if (orig_entry->orig_node == orig_node) { in batadv_tt_global_del_orig_node()
2065 vid = tt_global_entry->common.vid; in batadv_tt_global_del_orig_node()
2068 orig_node->orig, in batadv_tt_global_del_orig_node()
2069 tt_global_entry->common.addr, in batadv_tt_global_del_orig_node()
2075 spin_unlock_bh(&tt_global_entry->list_lock); in batadv_tt_global_del_orig_node()
2097 head = &tt_global_entry->orig_list; in batadv_tt_global_del_roaming()
2099 if (orig_entry->orig_node != orig_node) { in batadv_tt_global_del_roaming()
2108 tt_global_entry->common.flags |= BATADV_TT_CLIENT_ROAM; in batadv_tt_global_del_roaming()
2109 tt_global_entry->roam_at = jiffies; in batadv_tt_global_del_roaming()
2120 * batadv_tt_global_del() - remove a client from the global table
2121 * @bat_priv: the bat priv with all the soft interface information
2145 if (hlist_empty(&tt_global_entry->orig_list)) in batadv_tt_global_del()
2166 tt_global_entry->common.addr, in batadv_tt_global_del()
2184 * batadv_tt_global_del_orig() - remove all the TT global entries belonging to
2186 * @bat_priv: the bat priv with all the soft interface information
2200 struct batadv_hashtable *hash = bat_priv->tt.global_hash; in batadv_tt_global_del_orig()
2209 for (i = 0; i < hash->size; i++) { in batadv_tt_global_del_orig()
2210 head = &hash->table[i]; in batadv_tt_global_del_orig()
2211 list_lock = &hash->list_locks[i]; in batadv_tt_global_del_orig()
2217 if (match_vid >= 0 && tt_common_entry->vid != match_vid) in batadv_tt_global_del_orig()
2227 if (hlist_empty(&tt_global->orig_list)) { in batadv_tt_global_del_orig()
2228 vid = tt_global->common.vid; in batadv_tt_global_del_orig()
2231 tt_global->common.addr, in batadv_tt_global_del_orig()
2233 hlist_del_rcu(&tt_common_entry->hash_entry); in batadv_tt_global_del_orig()
2239 clear_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized); in batadv_tt_global_del_orig()
2249 if ((tt_global->common.flags & BATADV_TT_CLIENT_ROAM) && in batadv_tt_global_to_purge()
2250 batadv_has_timed_out(tt_global->roam_at, roam_timeout)) { in batadv_tt_global_to_purge()
2255 if ((tt_global->common.flags & BATADV_TT_CLIENT_TEMP) && in batadv_tt_global_to_purge()
2256 batadv_has_timed_out(tt_global->common.added_at, temp_timeout)) { in batadv_tt_global_to_purge()
2266 struct batadv_hashtable *hash = bat_priv->tt.global_hash; in batadv_tt_global_purge()
2275 for (i = 0; i < hash->size; i++) { in batadv_tt_global_purge()
2276 head = &hash->table[i]; in batadv_tt_global_purge()
2277 list_lock = &hash->list_locks[i]; in batadv_tt_global_purge()
2291 tt_global->common.addr, in batadv_tt_global_purge()
2292 batadv_print_vid(tt_global->common.vid), in batadv_tt_global_purge()
2295 hlist_del_rcu(&tt_common->hash_entry); in batadv_tt_global_purge()
2313 if (!bat_priv->tt.global_hash) in batadv_tt_global_table_free()
2316 hash = bat_priv->tt.global_hash; in batadv_tt_global_table_free()
2318 for (i = 0; i < hash->size; i++) { in batadv_tt_global_table_free()
2319 head = &hash->table[i]; in batadv_tt_global_table_free()
2320 list_lock = &hash->list_locks[i]; in batadv_tt_global_table_free()
2325 hlist_del_rcu(&tt_common_entry->hash_entry); in batadv_tt_global_table_free()
2336 bat_priv->tt.global_hash = NULL; in batadv_tt_global_table_free()
2343 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_WIFI && in _batadv_is_ap_isolated()
2344 tt_global_entry->common.flags & BATADV_TT_CLIENT_WIFI) in _batadv_is_ap_isolated()
2348 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_ISOLA && in _batadv_is_ap_isolated()
2349 tt_global_entry->common.flags & BATADV_TT_CLIENT_ISOLA) in _batadv_is_ap_isolated()
2356 * batadv_transtable_search() - get the mesh destination for a given client
2357 * @bat_priv: the bat priv with all the soft interface information
2382 (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)) in batadv_transtable_search()
2401 orig_node = best_entry->orig_node; in batadv_transtable_search()
2402 if (orig_node && !kref_get_unless_zero(&orig_node->refcount)) in batadv_transtable_search()
2414 * batadv_tt_global_crc() - calculates the checksum of the local table belonging
2416 * @bat_priv: the bat priv with all the soft interface information
2441 struct batadv_hashtable *hash = bat_priv->tt.global_hash; in batadv_tt_global_crc()
2450 for (i = 0; i < hash->size; i++) { in batadv_tt_global_crc()
2451 head = &hash->table[i]; in batadv_tt_global_crc()
2461 if (tt_common->vid != vid) in batadv_tt_global_crc()
2469 if (tt_common->flags & BATADV_TT_CLIENT_ROAM) in batadv_tt_global_crc()
2475 if (tt_common->flags & BATADV_TT_CLIENT_TEMP) in batadv_tt_global_crc()
2489 tmp_vid = htons(tt_common->vid); in batadv_tt_global_crc()
2495 flags = tt_orig->flags; in batadv_tt_global_crc()
2498 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN); in batadv_tt_global_crc()
2509 * batadv_tt_local_crc() - calculates the checksum of the local table
2510 * @bat_priv: the bat priv with all the soft interface information
2521 struct batadv_hashtable *hash = bat_priv->tt.local_hash; in batadv_tt_local_crc()
2528 for (i = 0; i < hash->size; i++) { in batadv_tt_local_crc()
2529 head = &hash->table[i]; in batadv_tt_local_crc()
2536 if (tt_common->vid != vid) in batadv_tt_local_crc()
2542 if (tt_common->flags & BATADV_TT_CLIENT_NEW) in batadv_tt_local_crc()
2548 tmp_vid = htons(tt_common->vid); in batadv_tt_local_crc()
2554 flags = tt_common->flags & BATADV_TT_SYNC_MASK; in batadv_tt_local_crc()
2557 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN); in batadv_tt_local_crc()
2566 * batadv_tt_req_node_release() - free tt_req node entry
2579 * batadv_tt_req_node_put() - decrement the tt_req_node refcounter and
2588 kref_put(&tt_req_node->refcount, batadv_tt_req_node_release); in batadv_tt_req_node_put()
2596 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_list_free()
2598 hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { in batadv_tt_req_list_free()
2599 hlist_del_init(&node->list); in batadv_tt_req_list_free()
2603 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_list_free()
2614 spin_lock_bh(&orig_node->tt_buff_lock); in batadv_tt_save_orig_buffer()
2616 kfree(orig_node->tt_buff); in batadv_tt_save_orig_buffer()
2617 orig_node->tt_buff_len = 0; in batadv_tt_save_orig_buffer()
2618 orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC); in batadv_tt_save_orig_buffer()
2619 if (orig_node->tt_buff) { in batadv_tt_save_orig_buffer()
2620 memcpy(orig_node->tt_buff, tt_buff, tt_buff_len); in batadv_tt_save_orig_buffer()
2621 orig_node->tt_buff_len = tt_buff_len; in batadv_tt_save_orig_buffer()
2624 spin_unlock_bh(&orig_node->tt_buff_lock); in batadv_tt_save_orig_buffer()
2632 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_purge()
2633 hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { in batadv_tt_req_purge()
2634 if (batadv_has_timed_out(node->issued_at, in batadv_tt_req_purge()
2636 hlist_del_init(&node->list); in batadv_tt_req_purge()
2640 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_purge()
2644 * batadv_tt_req_node_new() - search and possibly create a tt_req_node object
2645 * @bat_priv: the bat priv with all the soft interface information
2657 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_node_new()
2658 hlist_for_each_entry(tt_req_node_tmp, &bat_priv->tt.req_list, list) { in batadv_tt_req_node_new()
2660 !batadv_has_timed_out(tt_req_node_tmp->issued_at, in batadv_tt_req_node_new()
2669 kref_init(&tt_req_node->refcount); in batadv_tt_req_node_new()
2670 ether_addr_copy(tt_req_node->addr, orig_node->orig); in batadv_tt_req_node_new()
2671 tt_req_node->issued_at = jiffies; in batadv_tt_req_node_new()
2673 kref_get(&tt_req_node->refcount); in batadv_tt_req_node_new()
2674 hlist_add_head(&tt_req_node->list, &bat_priv->tt.req_list); in batadv_tt_req_node_new()
2676 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_node_new()
2681 * batadv_tt_local_valid() - verify local tt entry and get flags
2697 if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW) in batadv_tt_local_valid()
2701 *flags = tt_common_entry->flags; in batadv_tt_local_valid()
2707 * batadv_tt_global_valid() - verify global tt entry and get flags
2726 if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM || in batadv_tt_global_valid()
2727 tt_common_entry->flags & BATADV_TT_CLIENT_TEMP) in batadv_tt_global_valid()
2739 * batadv_tt_tvlv_generate() - fill the tvlv buff with the tt entries from the
2741 * @bat_priv: the bat priv with all the soft interface information
2749 * is not provided then this becomes a no-op.
2774 for (i = 0; i < hash->size; i++) { in batadv_tt_tvlv_generate()
2775 head = &hash->table[i]; in batadv_tt_tvlv_generate()
2786 ether_addr_copy(tt_change->addr, tt_common_entry->addr); in batadv_tt_tvlv_generate()
2787 tt_change->flags = flags; in batadv_tt_tvlv_generate()
2788 tt_change->vid = htons(tt_common_entry->vid); in batadv_tt_tvlv_generate()
2789 memset(tt_change->reserved, 0, in batadv_tt_tvlv_generate()
2790 sizeof(tt_change->reserved)); in batadv_tt_tvlv_generate()
2800 * batadv_tt_global_check_crc() - check if all the CRCs are correct
2824 if (batadv_bla_is_backbone_gw_orig(orig_node->bat_priv, in batadv_tt_global_check_crc()
2825 orig_node->orig, in batadv_tt_global_check_crc()
2826 ntohs(tt_vlan_tmp->vid))) in batadv_tt_global_check_crc()
2830 ntohs(tt_vlan_tmp->vid)); in batadv_tt_global_check_crc()
2834 crc = vlan->tt.crc; in batadv_tt_global_check_crc()
2837 if (crc != ntohl(tt_vlan_tmp->crc)) in batadv_tt_global_check_crc()
2846 hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) in batadv_tt_global_check_crc()
2857 * batadv_tt_local_update_crc() - update all the local CRCs
2858 * @bat_priv: the bat priv with all the soft interface information
2866 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { in batadv_tt_local_update_crc()
2867 vlan->tt.crc = batadv_tt_local_crc(bat_priv, vlan->vid); in batadv_tt_local_update_crc()
2873 * batadv_tt_global_update_crc() - update all the global CRCs for this orig_node
2874 * @bat_priv: the bat priv with all the soft interface information
2885 hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) { in batadv_tt_global_update_crc()
2889 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, in batadv_tt_global_update_crc()
2890 vlan->vid)) in batadv_tt_global_update_crc()
2893 crc = batadv_tt_global_crc(bat_priv, orig_node, vlan->vid); in batadv_tt_global_update_crc()
2894 vlan->tt.crc = crc; in batadv_tt_global_update_crc()
2900 * batadv_send_tt_request() - send a TT Request message to a given node
2901 * @bat_priv: the bat priv with all the soft interface information
2940 tvlv_tt_data->flags = BATADV_TT_REQUEST; in batadv_send_tt_request()
2941 tvlv_tt_data->ttvn = ttvn; in batadv_send_tt_request()
2942 tvlv_tt_data->num_vlan = htons(num_vlan); in batadv_send_tt_request()
2949 tt_vlan_req->vid = tt_vlan->vid; in batadv_send_tt_request()
2950 tt_vlan_req->crc = tt_vlan->crc; in batadv_send_tt_request()
2957 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE; in batadv_send_tt_request()
2960 dst_orig_node->orig, full_table ? 'F' : '.'); in batadv_send_tt_request()
2963 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr, in batadv_send_tt_request()
2964 dst_orig_node->orig, BATADV_TVLV_TT, 1, in batadv_send_tt_request()
2972 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_send_tt_request()
2973 if (!hlist_unhashed(&tt_req_node->list)) { in batadv_send_tt_request()
2974 hlist_del_init(&tt_req_node->list); in batadv_send_tt_request()
2977 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_send_tt_request()
2987 * batadv_send_other_tt_response() - send reply to tt request concerning another
2989 * @bat_priv: the bat priv with all the soft interface information
3012 req_src, tt_data->ttvn, req_dst, in batadv_send_other_tt_response()
3013 ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.')); in batadv_send_other_tt_response()
3024 orig_ttvn = (u8)atomic_read(&req_dst_orig_node->last_ttvn); in batadv_send_other_tt_response()
3025 req_ttvn = tt_data->ttvn; in batadv_send_other_tt_response()
3031 ntohs(tt_data->num_vlan))) in batadv_send_other_tt_response()
3035 if (tt_data->flags & BATADV_TT_FULL_TABLE || in batadv_send_other_tt_response()
3036 !req_dst_orig_node->tt_buff) in batadv_send_other_tt_response()
3045 spin_lock_bh(&req_dst_orig_node->tt_buff_lock); in batadv_send_other_tt_response()
3046 tt_len = req_dst_orig_node->tt_buff_len; in batadv_send_other_tt_response()
3056 memcpy(tt_change, req_dst_orig_node->tt_buff, in batadv_send_other_tt_response()
3057 req_dst_orig_node->tt_buff_len); in batadv_send_other_tt_response()
3058 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); in batadv_send_other_tt_response()
3063 tt_len = -1; in batadv_send_other_tt_response()
3072 batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.global_hash, in batadv_send_other_tt_response()
3080 if (tt_len > atomic_read(&bat_priv->packet_size_max)) { in batadv_send_other_tt_response()
3081 net_ratelimited_function(batadv_info, bat_priv->soft_iface, in batadv_send_other_tt_response()
3083 res_dst_orig_node->orig); in batadv_send_other_tt_response()
3087 tvlv_tt_data->flags = BATADV_TT_RESPONSE; in batadv_send_other_tt_response()
3088 tvlv_tt_data->ttvn = req_ttvn; in batadv_send_other_tt_response()
3091 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE; in batadv_send_other_tt_response()
3095 res_dst_orig_node->orig, req_dst_orig_node->orig, in batadv_send_other_tt_response()
3100 batadv_tvlv_unicast_send(bat_priv, req_dst_orig_node->orig, in batadv_send_other_tt_response()
3108 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); in batadv_send_other_tt_response()
3118 * batadv_send_my_tt_response() - send reply to tt request concerning this
3120 * @bat_priv: the bat priv with all the soft interface information
3141 req_src, tt_data->ttvn, in batadv_send_my_tt_response()
3142 ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.')); in batadv_send_my_tt_response()
3144 spin_lock_bh(&bat_priv->tt.commit_lock); in batadv_send_my_tt_response()
3146 my_ttvn = (u8)atomic_read(&bat_priv->tt.vn); in batadv_send_my_tt_response()
3147 req_ttvn = tt_data->ttvn; in batadv_send_my_tt_response()
3160 if (tt_data->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn || in batadv_send_my_tt_response()
3161 !bat_priv->tt.last_changeset) in batadv_send_my_tt_response()
3170 spin_lock_bh(&bat_priv->tt.last_changeset_lock); in batadv_send_my_tt_response()
3172 tt_len = bat_priv->tt.last_changeset_len; in batadv_send_my_tt_response()
3181 memcpy(tt_change, bat_priv->tt.last_changeset, in batadv_send_my_tt_response()
3182 bat_priv->tt.last_changeset_len); in batadv_send_my_tt_response()
3183 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); in batadv_send_my_tt_response()
3185 req_ttvn = (u8)atomic_read(&bat_priv->tt.vn); in batadv_send_my_tt_response()
3190 tt_len = -1; in batadv_send_my_tt_response()
3199 batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.local_hash, in batadv_send_my_tt_response()
3204 tvlv_tt_data->flags = BATADV_TT_RESPONSE; in batadv_send_my_tt_response()
3205 tvlv_tt_data->ttvn = req_ttvn; in batadv_send_my_tt_response()
3208 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE; in batadv_send_my_tt_response()
3212 orig_node->orig, full_table ? 'F' : '.', req_ttvn); in batadv_send_my_tt_response()
3216 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr, in batadv_send_my_tt_response()
3223 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); in batadv_send_my_tt_response()
3225 spin_unlock_bh(&bat_priv->tt.commit_lock); in batadv_send_my_tt_response()
3229 /* The packet was for this host, so it doesn't need to be re-routed */ in batadv_send_my_tt_response()
3234 * batadv_send_tt_response() - send reply to tt request
3235 * @bat_priv: the bat priv with all the soft interface information
3261 if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) { in _batadv_tt_update_changes()
3262 roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM; in _batadv_tt_update_changes()
3264 (tt_change + i)->addr, in _batadv_tt_update_changes()
3265 ntohs((tt_change + i)->vid), in _batadv_tt_update_changes()
3270 (tt_change + i)->addr, in _batadv_tt_update_changes()
3271 ntohs((tt_change + i)->vid), in _batadv_tt_update_changes()
3272 (tt_change + i)->flags, ttvn)) in _batadv_tt_update_changes()
3282 set_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized); in _batadv_tt_update_changes()
3297 batadv_tt_global_del_orig(bat_priv, orig_node, -1, in batadv_tt_fill_gtable()
3303 spin_lock_bh(&orig_node->tt_buff_lock); in batadv_tt_fill_gtable()
3304 kfree(orig_node->tt_buff); in batadv_tt_fill_gtable()
3305 orig_node->tt_buff_len = 0; in batadv_tt_fill_gtable()
3306 orig_node->tt_buff = NULL; in batadv_tt_fill_gtable()
3307 spin_unlock_bh(&orig_node->tt_buff_lock); in batadv_tt_fill_gtable()
3309 atomic_set(&orig_node->last_ttvn, ttvn); in batadv_tt_fill_gtable()
3325 atomic_set(&orig_node->last_ttvn, ttvn); in batadv_tt_update_changes()
3329 * batadv_is_my_client() - check if a client is served by the local node
3330 * @bat_priv: the bat priv with all the soft interface information
3348 if ((tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) || in batadv_is_my_client()
3349 (tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM)) in batadv_is_my_client()
3358 * batadv_handle_tt_response() - process incoming tt reply
3359 * @bat_priv: the bat priv with all the soft interface information
3377 resp_src, tt_data->ttvn, num_entries, in batadv_handle_tt_response()
3378 ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.')); in batadv_handle_tt_response()
3384 spin_lock_bh(&orig_node->tt_lock); in batadv_handle_tt_response()
3387 change_offset *= ntohs(tt_data->num_vlan); in batadv_handle_tt_response()
3392 if (tt_data->flags & BATADV_TT_FULL_TABLE) { in batadv_handle_tt_response()
3393 batadv_tt_fill_gtable(bat_priv, tt_change, tt_data->ttvn, in batadv_handle_tt_response()
3397 tt_data->ttvn, tt_change); in batadv_handle_tt_response()
3403 spin_unlock_bh(&orig_node->tt_lock); in batadv_handle_tt_response()
3406 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_handle_tt_response()
3407 hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { in batadv_handle_tt_response()
3408 if (!batadv_compare_eth(node->addr, resp_src)) in batadv_handle_tt_response()
3410 hlist_del_init(&node->list); in batadv_handle_tt_response()
3414 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_handle_tt_response()
3423 spin_lock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_roam_list_free()
3425 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { in batadv_tt_roam_list_free()
3426 list_del(&node->list); in batadv_tt_roam_list_free()
3430 spin_unlock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_roam_list_free()
3437 spin_lock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_roam_purge()
3438 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { in batadv_tt_roam_purge()
3439 if (!batadv_has_timed_out(node->first_time, in batadv_tt_roam_purge()
3443 list_del(&node->list); in batadv_tt_roam_purge()
3446 spin_unlock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_roam_purge()
3450 * batadv_tt_check_roam_count() - check if a client has roamed too frequently
3451 * @bat_priv: the bat priv with all the soft interface information
3465 spin_lock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_check_roam_count()
3469 list_for_each_entry(tt_roam_node, &bat_priv->tt.roam_list, list) { in batadv_tt_check_roam_count()
3470 if (!batadv_compare_eth(tt_roam_node->addr, client)) in batadv_tt_check_roam_count()
3473 if (batadv_has_timed_out(tt_roam_node->first_time, in batadv_tt_check_roam_count()
3477 if (!batadv_atomic_dec_not_zero(&tt_roam_node->counter)) in batadv_tt_check_roam_count()
3490 tt_roam_node->first_time = jiffies; in batadv_tt_check_roam_count()
3491 atomic_set(&tt_roam_node->counter, in batadv_tt_check_roam_count()
3492 BATADV_ROAMING_MAX_COUNT - 1); in batadv_tt_check_roam_count()
3493 ether_addr_copy(tt_roam_node->addr, client); in batadv_tt_check_roam_count()
3495 list_add(&tt_roam_node->list, &bat_priv->tt.roam_list); in batadv_tt_check_roam_count()
3500 spin_unlock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_check_roam_count()
3505 * batadv_send_roam_adv() - send a roaming advertisement message
3506 * @bat_priv: the bat priv with all the soft interface information
3535 orig_node->orig, client, batadv_print_vid(vid)); in batadv_send_roam_adv()
3542 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr, in batadv_send_roam_adv()
3543 orig_node->orig, BATADV_TVLV_ROAM, 1, in batadv_send_roam_adv()
3565 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work, in batadv_tt_purge()
3570 * batadv_tt_free() - Free translation table of soft interface
3571 * @bat_priv: the bat priv with all the soft interface information
3580 cancel_delayed_work_sync(&bat_priv->tt.work); in batadv_tt_free()
3588 kfree(bat_priv->tt.last_changeset); in batadv_tt_free()
3592 * batadv_tt_local_set_flags() - set or unset the specified flags on the local
3594 * @bat_priv: the bat priv with all the soft interface information
3602 struct batadv_hashtable *hash = bat_priv->tt.local_hash; in batadv_tt_local_set_flags()
3610 for (i = 0; i < hash->size; i++) { in batadv_tt_local_set_flags()
3611 head = &hash->table[i]; in batadv_tt_local_set_flags()
3617 if ((tt_common_entry->flags & flags) == flags) in batadv_tt_local_set_flags()
3619 tt_common_entry->flags |= flags; in batadv_tt_local_set_flags()
3621 if (!(tt_common_entry->flags & flags)) in batadv_tt_local_set_flags()
3623 tt_common_entry->flags &= ~flags; in batadv_tt_local_set_flags()
3630 tt_common_entry->vid); in batadv_tt_local_set_flags()
3639 struct batadv_hashtable *hash = bat_priv->tt.local_hash; in batadv_tt_local_purge_pending_clients()
3650 for (i = 0; i < hash->size; i++) { in batadv_tt_local_purge_pending_clients()
3651 head = &hash->table[i]; in batadv_tt_local_purge_pending_clients()
3652 list_lock = &hash->list_locks[i]; in batadv_tt_local_purge_pending_clients()
3657 if (!(tt_common->flags & BATADV_TT_CLIENT_PENDING)) in batadv_tt_local_purge_pending_clients()
3662 tt_common->addr, in batadv_tt_local_purge_pending_clients()
3663 batadv_print_vid(tt_common->vid)); in batadv_tt_local_purge_pending_clients()
3665 batadv_tt_local_size_dec(bat_priv, tt_common->vid); in batadv_tt_local_purge_pending_clients()
3666 hlist_del_rcu(&tt_common->hash_entry); in batadv_tt_local_purge_pending_clients()
3678 * batadv_tt_local_commit_changes_nolock() - commit all pending local tt changes
3680 * @bat_priv: the bat priv with all the soft interface information
3682 * Caller must hold tt->commit_lock.
3686 lockdep_assert_held(&bat_priv->tt.commit_lock); in batadv_tt_local_commit_changes_nolock()
3688 if (atomic_read(&bat_priv->tt.local_changes) < 1) { in batadv_tt_local_commit_changes_nolock()
3689 if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt)) in batadv_tt_local_commit_changes_nolock()
3700 atomic_inc(&bat_priv->tt.vn); in batadv_tt_local_commit_changes_nolock()
3703 (u8)atomic_read(&bat_priv->tt.vn)); in batadv_tt_local_commit_changes_nolock()
3706 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); in batadv_tt_local_commit_changes_nolock()
3711 * batadv_tt_local_commit_changes() - commit all pending local tt changes which
3713 * @bat_priv: the bat priv with all the soft interface information
3717 spin_lock_bh(&bat_priv->tt.commit_lock); in batadv_tt_local_commit_changes()
3719 spin_unlock_bh(&bat_priv->tt.commit_lock); in batadv_tt_local_commit_changes()
3723 * batadv_is_ap_isolated() - Check if packet from upper layer should be dropped
3724 * @bat_priv: the bat priv with all the soft interface information
3743 if (!atomic_read(&vlan->ap_isolation)) in batadv_is_ap_isolated()
3766 * batadv_tt_update_orig() - update global translation table with new tt
3768 * @bat_priv: the bat priv with all the soft interface information
3782 u8 orig_ttvn = (u8)atomic_read(&orig_node->last_ttvn); in batadv_tt_update_orig()
3789 &orig_node->capa_initialized); in batadv_tt_update_orig()
3792 * increased by one -> we can apply the attached changes in batadv_tt_update_orig()
3794 if ((!has_tt_init && ttvn == 1) || ttvn - orig_ttvn == 1) { in batadv_tt_update_orig()
3805 spin_lock_bh(&orig_node->tt_lock); in batadv_tt_update_orig()
3816 spin_unlock_bh(&orig_node->tt_lock); in batadv_tt_update_orig()
3832 * in sync anymore -> request fresh tt data in batadv_tt_update_orig()
3840 orig_node->orig, ttvn, orig_ttvn, in batadv_tt_update_orig()
3851 * batadv_tt_global_client_is_roaming() - check if a client is marked as roaming
3852 * @bat_priv: the bat priv with all the soft interface information
3870 ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM; in batadv_tt_global_client_is_roaming()
3877 * batadv_tt_local_client_is_roaming() - tells whether the client is roaming
3878 * @bat_priv: the bat priv with all the soft interface information
3896 ret = tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM; in batadv_tt_local_client_is_roaming()
3903 * batadv_tt_add_temporary_global_entry() - Add temporary entry to global TT
3904 * @bat_priv: the bat priv with all the soft interface information
3924 atomic_read(&orig_node->last_ttvn))) in batadv_tt_add_temporary_global_entry()
3929 addr, batadv_print_vid(vid), orig_node->orig); in batadv_tt_add_temporary_global_entry()
3935 * batadv_tt_local_resize_to_mtu() - resize the local translation table fit the
3945 int packet_size_max = atomic_read(&bat_priv->packet_size_max); in batadv_tt_local_resize_to_mtu()
3949 spin_lock_bh(&bat_priv->tt.commit_lock); in batadv_tt_local_resize_to_mtu()
3972 spin_unlock_bh(&bat_priv->tt.commit_lock); in batadv_tt_local_resize_to_mtu()
3976 * batadv_tt_tvlv_ogm_handler_v1() - process incoming tt tvlv container
3977 * @bat_priv: the bat priv with all the soft interface information
3997 tvlv_value_len -= sizeof(*tt_data); in batadv_tt_tvlv_ogm_handler_v1()
3999 num_vlan = ntohs(tt_data->num_vlan); in batadv_tt_tvlv_ogm_handler_v1()
4006 tvlv_value_len -= sizeof(*tt_vlan) * num_vlan; in batadv_tt_tvlv_ogm_handler_v1()
4011 num_entries, tt_data->ttvn); in batadv_tt_tvlv_ogm_handler_v1()
4015 * batadv_tt_tvlv_unicast_handler_v1() - process incoming (unicast) tt tvlv
4017 * @bat_priv: the bat priv with all the soft interface information
4023 * Return: NET_RX_DROP if the tt tvlv is to be re-routed, NET_RX_SUCCESS
4040 tvlv_value_len -= sizeof(*tt_data); in batadv_tt_tvlv_unicast_handler_v1()
4043 tt_vlan_len *= ntohs(tt_data->num_vlan); in batadv_tt_tvlv_unicast_handler_v1()
4048 tvlv_value_len -= tt_vlan_len; in batadv_tt_tvlv_unicast_handler_v1()
4051 switch (tt_data->flags & BATADV_TT_DATA_TYPE_MASK) { in batadv_tt_tvlv_unicast_handler_v1()
4060 if (tt_data->flags & BATADV_TT_FULL_TABLE) in batadv_tt_tvlv_unicast_handler_v1()
4068 /* tvlv API will re-route the packet */ in batadv_tt_tvlv_unicast_handler_v1()
4081 if (tt_data->flags & BATADV_TT_FULL_TABLE) in batadv_tt_tvlv_unicast_handler_v1()
4089 /* tvlv API will re-route the packet */ in batadv_tt_tvlv_unicast_handler_v1()
4097 * batadv_roam_tvlv_unicast_handler_v1() - process incoming tt roam tvlv
4099 * @bat_priv: the bat priv with all the soft interface information
4105 * Return: NET_RX_DROP if the tt roam tvlv is to be re-routed, NET_RX_SUCCESS
4118 * (the tvlv API will re-route the packet). in batadv_roam_tvlv_unicast_handler_v1()
4135 src, roaming_adv->client); in batadv_roam_tvlv_unicast_handler_v1()
4137 batadv_tt_global_add(bat_priv, orig_node, roaming_adv->client, in batadv_roam_tvlv_unicast_handler_v1()
4138 ntohs(roaming_adv->vid), BATADV_TT_CLIENT_ROAM, in batadv_roam_tvlv_unicast_handler_v1()
4139 atomic_read(&orig_node->last_ttvn) + 1); in batadv_roam_tvlv_unicast_handler_v1()
4147 * batadv_tt_init() - initialise the translation table internals
4148 * @bat_priv: the bat priv with all the soft interface information
4177 INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge); in batadv_tt_init()
4178 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work, in batadv_tt_init()
4185 * batadv_tt_global_is_isolated() - check if a client is marked as isolated
4186 * @bat_priv: the bat priv with all the soft interface information
4203 ret = tt->common.flags & BATADV_TT_CLIENT_ISOLA; in batadv_tt_global_is_isolated()
4211 * batadv_tt_cache_init() - Initialize tt memory object cache
4227 return -ENOMEM; in batadv_tt_cache_init()
4276 return -ENOMEM; in batadv_tt_cache_init()
4280 * batadv_tt_cache_destroy() - Destroy tt memory object cache