Lines Matching +full:bat +full:- +full:present
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()
782 tt_global->common.flags |= BATADV_TT_CLIENT_ROAM; in batadv_tt_local_add()
783 tt_global->roam_at = jiffies; in batadv_tt_local_add()
790 remote_flags = tt_local->common.flags & BATADV_TT_REMOTE_MASK; in batadv_tt_local_add()
793 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI; in batadv_tt_local_add()
795 tt_local->common.flags &= ~BATADV_TT_CLIENT_WIFI; in batadv_tt_local_add()
799 * non-mesh client in batadv_tt_local_add()
801 match_mark = (mark & bat_priv->isolation_mark_mask); in batadv_tt_local_add()
802 if (bat_priv->isolation_mark_mask && in batadv_tt_local_add()
803 match_mark == bat_priv->isolation_mark) in batadv_tt_local_add()
804 tt_local->common.flags |= BATADV_TT_CLIENT_ISOLA; in batadv_tt_local_add()
806 tt_local->common.flags &= ~BATADV_TT_CLIENT_ISOLA; in batadv_tt_local_add()
811 if (remote_flags ^ (tt_local->common.flags & BATADV_TT_REMOTE_MASK)) in batadv_tt_local_add()
824 * batadv_tt_prepare_tvlv_global_data() - prepare the TVLV TT header to send
830 * @tt_len: pointer to the length to reserve to the tt_change. if -1 this
854 spin_lock_bh(&orig_node->vlan_list_lock); in batadv_tt_prepare_tvlv_global_data()
855 hlist_for_each_entry(vlan, &orig_node->vlan_list, list) { in batadv_tt_prepare_tvlv_global_data()
857 num_entries += atomic_read(&vlan->tt.num_entries); in batadv_tt_prepare_tvlv_global_data()
876 (*tt_data)->flags = BATADV_NO_FLAGS; in batadv_tt_prepare_tvlv_global_data()
877 (*tt_data)->ttvn = atomic_read(&orig_node->last_ttvn); in batadv_tt_prepare_tvlv_global_data()
878 (*tt_data)->num_vlan = htons(num_vlan); in batadv_tt_prepare_tvlv_global_data()
881 hlist_for_each_entry(vlan, &orig_node->vlan_list, list) { in batadv_tt_prepare_tvlv_global_data()
882 tt_vlan->vid = htons(vlan->vid); in batadv_tt_prepare_tvlv_global_data()
883 tt_vlan->crc = htonl(vlan->tt.crc); in batadv_tt_prepare_tvlv_global_data()
884 tt_vlan->reserved = 0; in batadv_tt_prepare_tvlv_global_data()
893 spin_unlock_bh(&orig_node->vlan_list_lock); in batadv_tt_prepare_tvlv_global_data()
898 * batadv_tt_prepare_tvlv_local_data() - allocate and prepare the TT TVLV for
900 * @bat_priv: the bat priv with all the soft interface information
904 * @tt_len: pointer to the length to reserve to the tt_change. if -1 this
930 spin_lock_bh(&bat_priv->softif_vlan_list_lock); in batadv_tt_prepare_tvlv_local_data()
931 hlist_for_each_entry(vlan, &bat_priv->softif_vlan_list, list) { in batadv_tt_prepare_tvlv_local_data()
932 vlan_entries = atomic_read(&vlan->tt.num_entries); in batadv_tt_prepare_tvlv_local_data()
956 (*tt_data)->flags = BATADV_NO_FLAGS; in batadv_tt_prepare_tvlv_local_data()
957 (*tt_data)->ttvn = atomic_read(&bat_priv->tt.vn); in batadv_tt_prepare_tvlv_local_data()
958 (*tt_data)->num_vlan = htons(num_vlan); in batadv_tt_prepare_tvlv_local_data()
961 hlist_for_each_entry(vlan, &bat_priv->softif_vlan_list, list) { in batadv_tt_prepare_tvlv_local_data()
962 vlan_entries = atomic_read(&vlan->tt.num_entries); in batadv_tt_prepare_tvlv_local_data()
966 tt_vlan->vid = htons(vlan->vid); in batadv_tt_prepare_tvlv_local_data()
967 tt_vlan->crc = htonl(vlan->tt.crc); in batadv_tt_prepare_tvlv_local_data()
968 tt_vlan->reserved = 0; in batadv_tt_prepare_tvlv_local_data()
977 spin_unlock_bh(&bat_priv->softif_vlan_list_lock); in batadv_tt_prepare_tvlv_local_data()
982 * batadv_tt_tvlv_container_update() - update the translation table tvlv
984 * @bat_priv: the bat priv with all the soft interface information
996 tt_diff_entries_num = atomic_read(&bat_priv->tt.local_changes); in batadv_tt_tvlv_container_update()
1002 if (tt_diff_len > bat_priv->soft_iface->mtu) in batadv_tt_tvlv_container_update()
1010 tt_data->flags = BATADV_TT_OGM_DIFF; in batadv_tt_tvlv_container_update()
1015 spin_lock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_tvlv_container_update()
1016 atomic_set(&bat_priv->tt.local_changes, 0); in batadv_tt_tvlv_container_update()
1018 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, in batadv_tt_tvlv_container_update()
1022 &entry->change, in batadv_tt_tvlv_container_update()
1026 list_del(&entry->list); in batadv_tt_tvlv_container_update()
1029 spin_unlock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_tvlv_container_update()
1032 spin_lock_bh(&bat_priv->tt.last_changeset_lock); in batadv_tt_tvlv_container_update()
1033 kfree(bat_priv->tt.last_changeset); in batadv_tt_tvlv_container_update()
1034 bat_priv->tt.last_changeset_len = 0; in batadv_tt_tvlv_container_update()
1035 bat_priv->tt.last_changeset = NULL; in batadv_tt_tvlv_container_update()
1042 bat_priv->tt.last_changeset = kzalloc(tt_diff_len, GFP_ATOMIC); in batadv_tt_tvlv_container_update()
1043 if (bat_priv->tt.last_changeset) { in batadv_tt_tvlv_container_update()
1044 memcpy(bat_priv->tt.last_changeset, in batadv_tt_tvlv_container_update()
1046 bat_priv->tt.last_changeset_len = tt_diff_len; in batadv_tt_tvlv_container_update()
1049 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); in batadv_tt_tvlv_container_update()
1058 * batadv_tt_local_dump_entry() - Dump one TT local entry into a message
1062 * @bat_priv: The bat priv with all the soft interface information
1080 last_seen_msecs = jiffies_to_msecs(jiffies - local->last_seen); in batadv_tt_local_dump_entry()
1082 vlan = batadv_softif_vlan_get(bat_priv, common->vid); in batadv_tt_local_dump_entry()
1086 crc = vlan->tt.crc; in batadv_tt_local_dump_entry()
1090 hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq, in batadv_tt_local_dump_entry()
1094 return -ENOBUFS; in batadv_tt_local_dump_entry()
1098 if (nla_put(msg, BATADV_ATTR_TT_ADDRESS, ETH_ALEN, common->addr) || in batadv_tt_local_dump_entry()
1100 nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) || in batadv_tt_local_dump_entry()
1101 nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, common->flags)) in batadv_tt_local_dump_entry()
1104 if (!(common->flags & BATADV_TT_CLIENT_NOPURGE) && in batadv_tt_local_dump_entry()
1113 return -EMSGSIZE; in batadv_tt_local_dump_entry()
1117 * batadv_tt_local_dump_bucket() - Dump one TT local bucket into a message
1121 * @bat_priv: The bat priv with all the soft interface information
1138 spin_lock_bh(&hash->list_locks[bucket]); in batadv_tt_local_dump_bucket()
1139 cb->seq = atomic_read(&hash->generation) << 1 | 1; in batadv_tt_local_dump_bucket()
1141 hlist_for_each_entry(common, &hash->table[bucket], hash_entry) { in batadv_tt_local_dump_bucket()
1147 spin_unlock_bh(&hash->list_locks[bucket]); in batadv_tt_local_dump_bucket()
1148 *idx_s = idx - 1; in batadv_tt_local_dump_bucket()
1149 return -EMSGSIZE; in batadv_tt_local_dump_bucket()
1152 spin_unlock_bh(&hash->list_locks[bucket]); in batadv_tt_local_dump_bucket()
1159 * batadv_tt_local_dump() - Dump TT local entries into a message
1167 struct net *net = sock_net(cb->skb->sk); in batadv_tt_local_dump()
1174 int bucket = cb->args[0]; in batadv_tt_local_dump()
1175 int idx = cb->args[1]; in batadv_tt_local_dump()
1176 int portid = NETLINK_CB(cb->skb).portid; in batadv_tt_local_dump()
1178 ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX); in batadv_tt_local_dump()
1180 return -EINVAL; in batadv_tt_local_dump()
1184 ret = -ENODEV; in batadv_tt_local_dump()
1191 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { in batadv_tt_local_dump()
1192 ret = -ENOENT; in batadv_tt_local_dump()
1196 hash = bat_priv->tt.local_hash; in batadv_tt_local_dump()
1198 while (bucket < hash->size) { in batadv_tt_local_dump()
1206 ret = msg->len; in batadv_tt_local_dump()
1212 cb->args[0] = bucket; in batadv_tt_local_dump()
1213 cb->args[1] = idx; in batadv_tt_local_dump()
1229 tt_local_entry->common.flags |= BATADV_TT_CLIENT_PENDING; in batadv_tt_local_set_pending()
1233 tt_local_entry->common.addr, in batadv_tt_local_set_pending()
1234 batadv_print_vid(tt_local_entry->common.vid), message); in batadv_tt_local_set_pending()
1238 * batadv_tt_local_remove() - logically remove an entry from the local table
1239 * @bat_priv: the bat priv with all the soft interface information
1260 curr_flags = tt_local_entry->common.flags; in batadv_tt_local_remove()
1270 tt_local_entry->common.flags |= BATADV_TT_CLIENT_ROAM; in batadv_tt_local_remove()
1273 if (!(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) { in batadv_tt_local_remove()
1283 tt_removed_node = batadv_hash_remove(bat_priv->tt.local_hash, in batadv_tt_local_remove()
1286 &tt_local_entry->common); in batadv_tt_local_remove()
1303 * batadv_tt_local_purge_list() - purge inactive tt local entries
1304 * @bat_priv: the bat priv with all the soft interface information
1322 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_NOPURGE) in batadv_tt_local_purge_list()
1326 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) in batadv_tt_local_purge_list()
1329 if (!batadv_has_timed_out(tt_local_entry->last_seen, timeout)) in batadv_tt_local_purge_list()
1338 * batadv_tt_local_purge() - purge inactive tt local entries
1339 * @bat_priv: the bat priv with all the soft interface information
1346 struct batadv_hashtable *hash = bat_priv->tt.local_hash; in batadv_tt_local_purge()
1351 for (i = 0; i < hash->size; i++) { in batadv_tt_local_purge()
1352 head = &hash->table[i]; in batadv_tt_local_purge()
1353 list_lock = &hash->list_locks[i]; in batadv_tt_local_purge()
1371 if (!bat_priv->tt.local_hash) in batadv_tt_local_table_free()
1374 hash = bat_priv->tt.local_hash; in batadv_tt_local_table_free()
1376 for (i = 0; i < hash->size; i++) { in batadv_tt_local_table_free()
1377 head = &hash->table[i]; in batadv_tt_local_table_free()
1378 list_lock = &hash->list_locks[i]; in batadv_tt_local_table_free()
1383 hlist_del_rcu(&tt_common_entry->hash_entry); in batadv_tt_local_table_free()
1395 bat_priv->tt.local_hash = NULL; in batadv_tt_local_table_free()
1400 if (bat_priv->tt.global_hash) in batadv_tt_global_init()
1403 bat_priv->tt.global_hash = batadv_hash_new(1024); in batadv_tt_global_init()
1405 if (!bat_priv->tt.global_hash) in batadv_tt_global_init()
1406 return -ENOMEM; in batadv_tt_global_init()
1408 batadv_hash_set_lock_class(bat_priv->tt.global_hash, in batadv_tt_global_init()
1418 spin_lock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_changes_list_free()
1420 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, in batadv_tt_changes_list_free()
1422 list_del(&entry->list); in batadv_tt_changes_list_free()
1426 atomic_set(&bat_priv->tt.local_changes, 0); in batadv_tt_changes_list_free()
1427 spin_unlock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_changes_list_free()
1431 * batadv_tt_global_orig_entry_find() - find a TT orig_list_entry
1449 head = &entry->orig_list; in batadv_tt_global_orig_entry_find()
1451 if (tmp_orig_entry->orig_node != orig_node) in batadv_tt_global_orig_entry_find()
1453 if (!kref_get_unless_zero(&tmp_orig_entry->refcount)) in batadv_tt_global_orig_entry_find()
1465 * batadv_tt_global_entry_has_orig() - check if a TT global entry is also
1489 *flags = orig_entry->flags; in batadv_tt_global_entry_has_orig()
1498 * batadv_tt_global_sync_flags() - update TT sync flags
1512 head = &tt_global->orig_list; in batadv_tt_global_sync_flags()
1514 flags |= orig_entry->flags; in batadv_tt_global_sync_flags()
1517 flags |= tt_global->common.flags & (~BATADV_TT_SYNC_MASK); in batadv_tt_global_sync_flags()
1518 tt_global->common.flags = flags; in batadv_tt_global_sync_flags()
1522 * batadv_tt_global_orig_entry_add() - add or update a TT orig entry
1535 spin_lock_bh(&tt_global->list_lock); in batadv_tt_global_orig_entry_add()
1542 orig_entry->ttvn = ttvn; in batadv_tt_global_orig_entry_add()
1543 orig_entry->flags = flags; in batadv_tt_global_orig_entry_add()
1551 INIT_HLIST_NODE(&orig_entry->list); in batadv_tt_global_orig_entry_add()
1552 kref_get(&orig_node->refcount); in batadv_tt_global_orig_entry_add()
1553 batadv_tt_global_size_inc(orig_node, tt_global->common.vid); in batadv_tt_global_orig_entry_add()
1554 orig_entry->orig_node = orig_node; in batadv_tt_global_orig_entry_add()
1555 orig_entry->ttvn = ttvn; in batadv_tt_global_orig_entry_add()
1556 orig_entry->flags = flags; in batadv_tt_global_orig_entry_add()
1557 kref_init(&orig_entry->refcount); in batadv_tt_global_orig_entry_add()
1559 kref_get(&orig_entry->refcount); in batadv_tt_global_orig_entry_add()
1560 hlist_add_head_rcu(&orig_entry->list, in batadv_tt_global_orig_entry_add()
1561 &tt_global->orig_list); in batadv_tt_global_orig_entry_add()
1562 atomic_inc(&tt_global->orig_list_count); in batadv_tt_global_orig_entry_add()
1569 spin_unlock_bh(&tt_global->list_lock); in batadv_tt_global_orig_entry_add()
1573 * batadv_tt_global_add() - add a new TT global entry or update an existing one
1574 * @bat_priv: the bat priv with all the soft interface information
1576 * @tt_addr: the mac address of the non-mesh client
1578 * @flags: TT flags that have to be set for this non-mesh client
1579 * @ttvn: the tt version number ever announcing this non-mesh client
1585 * If a TT local entry exists for this non-mesh client remove it.
1604 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) in batadv_tt_global_add()
1615 !(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) in batadv_tt_global_add()
1624 common = &tt_global_entry->common; in batadv_tt_global_add()
1625 ether_addr_copy(common->addr, tt_addr); in batadv_tt_global_add()
1626 common->vid = vid; in batadv_tt_global_add()
1628 if (!is_multicast_ether_addr(common->addr)) in batadv_tt_global_add()
1629 common->flags = flags & (~BATADV_TT_SYNC_MASK); in batadv_tt_global_add()
1631 tt_global_entry->roam_at = 0; in batadv_tt_global_add()
1637 tt_global_entry->roam_at = jiffies; in batadv_tt_global_add()
1638 kref_init(&common->refcount); in batadv_tt_global_add()
1639 common->added_at = jiffies; in batadv_tt_global_add()
1641 INIT_HLIST_HEAD(&tt_global_entry->orig_list); in batadv_tt_global_add()
1642 atomic_set(&tt_global_entry->orig_list_count, 0); in batadv_tt_global_add()
1643 spin_lock_init(&tt_global_entry->list_lock); in batadv_tt_global_add()
1645 kref_get(&common->refcount); in batadv_tt_global_add()
1646 hash_added = batadv_hash_add(bat_priv->tt.global_hash, in batadv_tt_global_add()
1649 &common->hash_entry); in batadv_tt_global_add()
1657 common = &tt_global_entry->common; in batadv_tt_global_add()
1669 if (!(common->flags & BATADV_TT_CLIENT_TEMP)) in batadv_tt_global_add()
1680 * remove the previous temporary orig node and re-add it in batadv_tt_global_add()
1682 * is a non-temporary entry is preferred. in batadv_tt_global_add()
1684 if (common->flags & BATADV_TT_CLIENT_TEMP) { in batadv_tt_global_add()
1686 common->flags &= ~BATADV_TT_CLIENT_TEMP; in batadv_tt_global_add()
1693 if (!is_multicast_ether_addr(common->addr)) in batadv_tt_global_add()
1694 common->flags |= flags & (~BATADV_TT_SYNC_MASK); in batadv_tt_global_add()
1703 if (common->flags & BATADV_TT_CLIENT_ROAM) { in batadv_tt_global_add()
1705 common->flags &= ~BATADV_TT_CLIENT_ROAM; in batadv_tt_global_add()
1706 tt_global_entry->roam_at = 0; in batadv_tt_global_add()
1716 common->addr, batadv_print_vid(common->vid), in batadv_tt_global_add()
1717 orig_node->orig); in batadv_tt_global_add()
1727 /* remove address from local hash if present */ in batadv_tt_global_add()
1731 tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI; in batadv_tt_global_add()
1737 tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM; in batadv_tt_global_add()
1746 * batadv_transtable_best_orig() - Get best originator list entry from tt entry
1747 * @bat_priv: the bat priv with all the soft interface information
1758 struct batadv_algo_ops *bao = bat_priv->algo_ops; in batadv_transtable_best_orig()
1762 head = &tt_global_entry->orig_list; in batadv_transtable_best_orig()
1764 router = batadv_orig_router_get(orig_entry->orig_node, in batadv_transtable_best_orig()
1770 bao->neigh.cmp(router, BATADV_IF_DEFAULT, best_router, in batadv_transtable_best_orig()
1789 * batadv_tt_global_dump_subentry() - Dump all TT local entries into a message
1794 * @orig: Originator node announcing a non-mesh client
1805 u16 flags = (common->flags & (~BATADV_TT_SYNC_MASK)) | orig->flags; in batadv_tt_global_dump_subentry()
1811 vlan = batadv_orig_node_vlan_get(orig->orig_node, in batadv_tt_global_dump_subentry()
1812 common->vid); in batadv_tt_global_dump_subentry()
1816 crc = vlan->tt.crc; in batadv_tt_global_dump_subentry()
1824 return -ENOBUFS; in batadv_tt_global_dump_subentry()
1826 last_ttvn = atomic_read(&orig->orig_node->last_ttvn); in batadv_tt_global_dump_subentry()
1828 if (nla_put(msg, BATADV_ATTR_TT_ADDRESS, ETH_ALEN, common->addr) || in batadv_tt_global_dump_subentry()
1830 orig->orig_node->orig) || in batadv_tt_global_dump_subentry()
1831 nla_put_u8(msg, BATADV_ATTR_TT_TTVN, orig->ttvn) || in batadv_tt_global_dump_subentry()
1834 nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) || in batadv_tt_global_dump_subentry()
1846 return -EMSGSIZE; in batadv_tt_global_dump_subentry()
1850 * batadv_tt_global_dump_entry() - Dump one TT global entry into a message
1854 * @bat_priv: The bat priv with all the soft interface information
1875 head = &global->orig_list; in batadv_tt_global_dump_entry()
1885 *sub_s = sub - 1; in batadv_tt_global_dump_entry()
1886 return -EMSGSIZE; in batadv_tt_global_dump_entry()
1895 * batadv_tt_global_dump_bucket() - Dump one TT local bucket into a message
1899 * @bat_priv: The bat priv with all the soft interface information
1922 *idx_s = idx - 1; in batadv_tt_global_dump_bucket()
1923 return -EMSGSIZE; in batadv_tt_global_dump_bucket()
1934 * batadv_tt_global_dump() - Dump TT global entries into a message
1942 struct net *net = sock_net(cb->skb->sk); in batadv_tt_global_dump()
1950 int bucket = cb->args[0]; in batadv_tt_global_dump()
1951 int idx = cb->args[1]; in batadv_tt_global_dump()
1952 int sub = cb->args[2]; in batadv_tt_global_dump()
1953 int portid = NETLINK_CB(cb->skb).portid; in batadv_tt_global_dump()
1955 ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX); in batadv_tt_global_dump()
1957 return -EINVAL; in batadv_tt_global_dump()
1961 ret = -ENODEV; in batadv_tt_global_dump()
1968 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { in batadv_tt_global_dump()
1969 ret = -ENOENT; in batadv_tt_global_dump()
1973 hash = bat_priv->tt.global_hash; in batadv_tt_global_dump()
1975 while (bucket < hash->size) { in batadv_tt_global_dump()
1976 head = &hash->table[bucket]; in batadv_tt_global_dump()
1979 cb->nlh->nlmsg_seq, bat_priv, in batadv_tt_global_dump()
1986 ret = msg->len; in batadv_tt_global_dump()
1992 cb->args[0] = bucket; in batadv_tt_global_dump()
1993 cb->args[1] = idx; in batadv_tt_global_dump()
1994 cb->args[2] = sub; in batadv_tt_global_dump()
2000 * _batadv_tt_global_del_orig_entry() - remove and free an orig_entry
2007 * Caller must hold tt_global_entry->list_lock and ensure orig_entry->list is
2014 lockdep_assert_held(&tt_global_entry->list_lock); in _batadv_tt_global_del_orig_entry()
2016 batadv_tt_global_size_dec(orig_entry->orig_node, in _batadv_tt_global_del_orig_entry()
2017 tt_global_entry->common.vid); in _batadv_tt_global_del_orig_entry()
2018 atomic_dec(&tt_global_entry->orig_list_count); in _batadv_tt_global_del_orig_entry()
2019 /* requires holding tt_global_entry->list_lock and orig_entry->list in _batadv_tt_global_del_orig_entry()
2022 hlist_del_rcu(&orig_entry->list); in _batadv_tt_global_del_orig_entry()
2034 spin_lock_bh(&tt_global_entry->list_lock); in batadv_tt_global_del_orig_list()
2035 head = &tt_global_entry->orig_list; in batadv_tt_global_del_orig_list()
2038 spin_unlock_bh(&tt_global_entry->list_lock); in batadv_tt_global_del_orig_list()
2042 * batadv_tt_global_del_orig_node() - remove orig_node from a global tt entry
2043 * @bat_priv: the bat priv with all the soft interface information
2062 spin_lock_bh(&tt_global_entry->list_lock); in batadv_tt_global_del_orig_node()
2063 head = &tt_global_entry->orig_list; in batadv_tt_global_del_orig_node()
2065 if (orig_entry->orig_node == orig_node) { in batadv_tt_global_del_orig_node()
2066 vid = tt_global_entry->common.vid; in batadv_tt_global_del_orig_node()
2069 orig_node->orig, in batadv_tt_global_del_orig_node()
2070 tt_global_entry->common.addr, in batadv_tt_global_del_orig_node()
2076 spin_unlock_bh(&tt_global_entry->list_lock); in batadv_tt_global_del_orig_node()
2098 head = &tt_global_entry->orig_list; in batadv_tt_global_del_roaming()
2100 if (orig_entry->orig_node != orig_node) { in batadv_tt_global_del_roaming()
2109 tt_global_entry->common.flags |= BATADV_TT_CLIENT_ROAM; in batadv_tt_global_del_roaming()
2110 tt_global_entry->roam_at = jiffies; in batadv_tt_global_del_roaming()
2121 * batadv_tt_global_del() - remove a client from the global table
2122 * @bat_priv: the bat priv with all the soft interface information
2146 if (hlist_empty(&tt_global_entry->orig_list)) in batadv_tt_global_del()
2167 tt_global_entry->common.addr, in batadv_tt_global_del()
2185 * batadv_tt_global_del_orig() - remove all the TT global entries belonging to
2187 * @bat_priv: the bat priv with all the soft interface information
2201 struct batadv_hashtable *hash = bat_priv->tt.global_hash; in batadv_tt_global_del_orig()
2210 for (i = 0; i < hash->size; i++) { in batadv_tt_global_del_orig()
2211 head = &hash->table[i]; in batadv_tt_global_del_orig()
2212 list_lock = &hash->list_locks[i]; in batadv_tt_global_del_orig()
2218 if (match_vid >= 0 && tt_common_entry->vid != match_vid) in batadv_tt_global_del_orig()
2228 if (hlist_empty(&tt_global->orig_list)) { in batadv_tt_global_del_orig()
2229 vid = tt_global->common.vid; in batadv_tt_global_del_orig()
2232 tt_global->common.addr, in batadv_tt_global_del_orig()
2234 hlist_del_rcu(&tt_common_entry->hash_entry); in batadv_tt_global_del_orig()
2240 clear_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized); in batadv_tt_global_del_orig()
2250 if ((tt_global->common.flags & BATADV_TT_CLIENT_ROAM) && in batadv_tt_global_to_purge()
2251 batadv_has_timed_out(tt_global->roam_at, roam_timeout)) { in batadv_tt_global_to_purge()
2256 if ((tt_global->common.flags & BATADV_TT_CLIENT_TEMP) && in batadv_tt_global_to_purge()
2257 batadv_has_timed_out(tt_global->common.added_at, temp_timeout)) { in batadv_tt_global_to_purge()
2267 struct batadv_hashtable *hash = bat_priv->tt.global_hash; in batadv_tt_global_purge()
2276 for (i = 0; i < hash->size; i++) { in batadv_tt_global_purge()
2277 head = &hash->table[i]; in batadv_tt_global_purge()
2278 list_lock = &hash->list_locks[i]; in batadv_tt_global_purge()
2292 tt_global->common.addr, in batadv_tt_global_purge()
2293 batadv_print_vid(tt_global->common.vid), in batadv_tt_global_purge()
2296 hlist_del_rcu(&tt_common->hash_entry); in batadv_tt_global_purge()
2314 if (!bat_priv->tt.global_hash) in batadv_tt_global_table_free()
2317 hash = bat_priv->tt.global_hash; in batadv_tt_global_table_free()
2319 for (i = 0; i < hash->size; i++) { in batadv_tt_global_table_free()
2320 head = &hash->table[i]; in batadv_tt_global_table_free()
2321 list_lock = &hash->list_locks[i]; in batadv_tt_global_table_free()
2326 hlist_del_rcu(&tt_common_entry->hash_entry); in batadv_tt_global_table_free()
2337 bat_priv->tt.global_hash = NULL; in batadv_tt_global_table_free()
2344 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_WIFI && in _batadv_is_ap_isolated()
2345 tt_global_entry->common.flags & BATADV_TT_CLIENT_WIFI) in _batadv_is_ap_isolated()
2349 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_ISOLA && in _batadv_is_ap_isolated()
2350 tt_global_entry->common.flags & BATADV_TT_CLIENT_ISOLA) in _batadv_is_ap_isolated()
2357 * batadv_transtable_search() - get the mesh destination for a given client
2358 * @bat_priv: the bat priv with all the soft interface information
2383 (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)) in batadv_transtable_search()
2402 orig_node = best_entry->orig_node; in batadv_transtable_search()
2403 if (orig_node && !kref_get_unless_zero(&orig_node->refcount)) in batadv_transtable_search()
2415 * batadv_tt_global_crc() - calculates the checksum of the local table belonging
2417 * @bat_priv: the bat priv with all the soft interface information
2442 struct batadv_hashtable *hash = bat_priv->tt.global_hash; in batadv_tt_global_crc()
2451 for (i = 0; i < hash->size; i++) { in batadv_tt_global_crc()
2452 head = &hash->table[i]; in batadv_tt_global_crc()
2462 if (tt_common->vid != vid) in batadv_tt_global_crc()
2470 if (tt_common->flags & BATADV_TT_CLIENT_ROAM) in batadv_tt_global_crc()
2476 if (tt_common->flags & BATADV_TT_CLIENT_TEMP) in batadv_tt_global_crc()
2490 tmp_vid = htons(tt_common->vid); in batadv_tt_global_crc()
2496 flags = tt_orig->flags; in batadv_tt_global_crc()
2499 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN); in batadv_tt_global_crc()
2510 * batadv_tt_local_crc() - calculates the checksum of the local table
2511 * @bat_priv: the bat priv with all the soft interface information
2522 struct batadv_hashtable *hash = bat_priv->tt.local_hash; in batadv_tt_local_crc()
2529 for (i = 0; i < hash->size; i++) { in batadv_tt_local_crc()
2530 head = &hash->table[i]; in batadv_tt_local_crc()
2537 if (tt_common->vid != vid) in batadv_tt_local_crc()
2543 if (tt_common->flags & BATADV_TT_CLIENT_NEW) in batadv_tt_local_crc()
2549 tmp_vid = htons(tt_common->vid); in batadv_tt_local_crc()
2555 flags = tt_common->flags & BATADV_TT_SYNC_MASK; in batadv_tt_local_crc()
2558 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN); in batadv_tt_local_crc()
2567 * batadv_tt_req_node_release() - free tt_req node entry
2580 * batadv_tt_req_node_put() - decrement the tt_req_node refcounter and
2589 kref_put(&tt_req_node->refcount, batadv_tt_req_node_release); in batadv_tt_req_node_put()
2597 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_list_free()
2599 hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { in batadv_tt_req_list_free()
2600 hlist_del_init(&node->list); in batadv_tt_req_list_free()
2604 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_list_free()
2615 spin_lock_bh(&orig_node->tt_buff_lock); in batadv_tt_save_orig_buffer()
2617 kfree(orig_node->tt_buff); in batadv_tt_save_orig_buffer()
2618 orig_node->tt_buff_len = 0; in batadv_tt_save_orig_buffer()
2619 orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC); in batadv_tt_save_orig_buffer()
2620 if (orig_node->tt_buff) { in batadv_tt_save_orig_buffer()
2621 memcpy(orig_node->tt_buff, tt_buff, tt_buff_len); in batadv_tt_save_orig_buffer()
2622 orig_node->tt_buff_len = tt_buff_len; in batadv_tt_save_orig_buffer()
2625 spin_unlock_bh(&orig_node->tt_buff_lock); in batadv_tt_save_orig_buffer()
2633 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_purge()
2634 hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { in batadv_tt_req_purge()
2635 if (batadv_has_timed_out(node->issued_at, in batadv_tt_req_purge()
2637 hlist_del_init(&node->list); in batadv_tt_req_purge()
2641 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_purge()
2645 * batadv_tt_req_node_new() - search and possibly create a tt_req_node object
2646 * @bat_priv: the bat priv with all the soft interface information
2658 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_node_new()
2659 hlist_for_each_entry(tt_req_node_tmp, &bat_priv->tt.req_list, list) { in batadv_tt_req_node_new()
2661 !batadv_has_timed_out(tt_req_node_tmp->issued_at, in batadv_tt_req_node_new()
2670 kref_init(&tt_req_node->refcount); in batadv_tt_req_node_new()
2671 ether_addr_copy(tt_req_node->addr, orig_node->orig); in batadv_tt_req_node_new()
2672 tt_req_node->issued_at = jiffies; in batadv_tt_req_node_new()
2674 kref_get(&tt_req_node->refcount); in batadv_tt_req_node_new()
2675 hlist_add_head(&tt_req_node->list, &bat_priv->tt.req_list); in batadv_tt_req_node_new()
2677 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_node_new()
2682 * batadv_tt_local_valid() - verify local tt entry and get flags
2698 if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW) in batadv_tt_local_valid()
2702 *flags = tt_common_entry->flags; in batadv_tt_local_valid()
2708 * batadv_tt_global_valid() - verify global tt entry and get flags
2727 if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM || in batadv_tt_global_valid()
2728 tt_common_entry->flags & BATADV_TT_CLIENT_TEMP) in batadv_tt_global_valid()
2740 * batadv_tt_tvlv_generate() - fill the tvlv buff with the tt entries from the
2742 * @bat_priv: the bat priv with all the soft interface information
2750 * is not provided then this becomes a no-op.
2775 for (i = 0; i < hash->size; i++) { in batadv_tt_tvlv_generate()
2776 head = &hash->table[i]; in batadv_tt_tvlv_generate()
2787 ether_addr_copy(tt_change->addr, tt_common_entry->addr); in batadv_tt_tvlv_generate()
2788 tt_change->flags = flags; in batadv_tt_tvlv_generate()
2789 tt_change->vid = htons(tt_common_entry->vid); in batadv_tt_tvlv_generate()
2790 memset(tt_change->reserved, 0, in batadv_tt_tvlv_generate()
2791 sizeof(tt_change->reserved)); in batadv_tt_tvlv_generate()
2801 * batadv_tt_global_check_crc() - check if all the CRCs are correct
2825 if (batadv_bla_is_backbone_gw_orig(orig_node->bat_priv, in batadv_tt_global_check_crc()
2826 orig_node->orig, in batadv_tt_global_check_crc()
2827 ntohs(tt_vlan_tmp->vid))) in batadv_tt_global_check_crc()
2831 ntohs(tt_vlan_tmp->vid)); in batadv_tt_global_check_crc()
2835 crc = vlan->tt.crc; in batadv_tt_global_check_crc()
2838 if (crc != ntohl(tt_vlan_tmp->crc)) in batadv_tt_global_check_crc()
2847 hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) in batadv_tt_global_check_crc()
2858 * batadv_tt_local_update_crc() - update all the local CRCs
2859 * @bat_priv: the bat priv with all the soft interface information
2867 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { in batadv_tt_local_update_crc()
2868 vlan->tt.crc = batadv_tt_local_crc(bat_priv, vlan->vid); in batadv_tt_local_update_crc()
2874 * batadv_tt_global_update_crc() - update all the global CRCs for this orig_node
2875 * @bat_priv: the bat priv with all the soft interface information
2886 hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) { in batadv_tt_global_update_crc()
2890 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, in batadv_tt_global_update_crc()
2891 vlan->vid)) in batadv_tt_global_update_crc()
2894 crc = batadv_tt_global_crc(bat_priv, orig_node, vlan->vid); in batadv_tt_global_update_crc()
2895 vlan->tt.crc = crc; in batadv_tt_global_update_crc()
2901 * batadv_send_tt_request() - send a TT Request message to a given node
2902 * @bat_priv: the bat priv with all the soft interface information
2941 tvlv_tt_data->flags = BATADV_TT_REQUEST; in batadv_send_tt_request()
2942 tvlv_tt_data->ttvn = ttvn; in batadv_send_tt_request()
2943 tvlv_tt_data->num_vlan = htons(num_vlan); in batadv_send_tt_request()
2950 tt_vlan_req->vid = tt_vlan->vid; in batadv_send_tt_request()
2951 tt_vlan_req->crc = tt_vlan->crc; in batadv_send_tt_request()
2958 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE; in batadv_send_tt_request()
2961 dst_orig_node->orig, full_table ? 'F' : '.'); in batadv_send_tt_request()
2964 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr, in batadv_send_tt_request()
2965 dst_orig_node->orig, BATADV_TVLV_TT, 1, in batadv_send_tt_request()
2973 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_send_tt_request()
2974 if (!hlist_unhashed(&tt_req_node->list)) { in batadv_send_tt_request()
2975 hlist_del_init(&tt_req_node->list); in batadv_send_tt_request()
2978 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_send_tt_request()
2988 * batadv_send_other_tt_response() - send reply to tt request concerning another
2990 * @bat_priv: the bat priv with all the soft interface information
3013 req_src, tt_data->ttvn, req_dst, in batadv_send_other_tt_response()
3014 ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.')); in batadv_send_other_tt_response()
3025 orig_ttvn = (u8)atomic_read(&req_dst_orig_node->last_ttvn); in batadv_send_other_tt_response()
3026 req_ttvn = tt_data->ttvn; in batadv_send_other_tt_response()
3032 ntohs(tt_data->num_vlan))) in batadv_send_other_tt_response()
3036 if (tt_data->flags & BATADV_TT_FULL_TABLE || in batadv_send_other_tt_response()
3037 !req_dst_orig_node->tt_buff) in batadv_send_other_tt_response()
3046 spin_lock_bh(&req_dst_orig_node->tt_buff_lock); in batadv_send_other_tt_response()
3047 tt_len = req_dst_orig_node->tt_buff_len; in batadv_send_other_tt_response()
3057 memcpy(tt_change, req_dst_orig_node->tt_buff, in batadv_send_other_tt_response()
3058 req_dst_orig_node->tt_buff_len); in batadv_send_other_tt_response()
3059 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); in batadv_send_other_tt_response()
3064 tt_len = -1; in batadv_send_other_tt_response()
3073 batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.global_hash, in batadv_send_other_tt_response()
3081 if (tt_len > atomic_read(&bat_priv->packet_size_max)) { in batadv_send_other_tt_response()
3082 net_ratelimited_function(batadv_info, bat_priv->soft_iface, in batadv_send_other_tt_response()
3084 res_dst_orig_node->orig); in batadv_send_other_tt_response()
3088 tvlv_tt_data->flags = BATADV_TT_RESPONSE; in batadv_send_other_tt_response()
3089 tvlv_tt_data->ttvn = req_ttvn; in batadv_send_other_tt_response()
3092 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE; in batadv_send_other_tt_response()
3096 res_dst_orig_node->orig, req_dst_orig_node->orig, in batadv_send_other_tt_response()
3101 batadv_tvlv_unicast_send(bat_priv, req_dst_orig_node->orig, in batadv_send_other_tt_response()
3109 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); in batadv_send_other_tt_response()
3119 * batadv_send_my_tt_response() - send reply to tt request concerning this
3121 * @bat_priv: the bat priv with all the soft interface information
3142 req_src, tt_data->ttvn, in batadv_send_my_tt_response()
3143 ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.')); in batadv_send_my_tt_response()
3145 spin_lock_bh(&bat_priv->tt.commit_lock); in batadv_send_my_tt_response()
3147 my_ttvn = (u8)atomic_read(&bat_priv->tt.vn); in batadv_send_my_tt_response()
3148 req_ttvn = tt_data->ttvn; in batadv_send_my_tt_response()
3161 if (tt_data->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn || in batadv_send_my_tt_response()
3162 !bat_priv->tt.last_changeset) in batadv_send_my_tt_response()
3171 spin_lock_bh(&bat_priv->tt.last_changeset_lock); in batadv_send_my_tt_response()
3173 tt_len = bat_priv->tt.last_changeset_len; in batadv_send_my_tt_response()
3182 memcpy(tt_change, bat_priv->tt.last_changeset, in batadv_send_my_tt_response()
3183 bat_priv->tt.last_changeset_len); in batadv_send_my_tt_response()
3184 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); in batadv_send_my_tt_response()
3186 req_ttvn = (u8)atomic_read(&bat_priv->tt.vn); in batadv_send_my_tt_response()
3191 tt_len = -1; in batadv_send_my_tt_response()
3200 batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.local_hash, in batadv_send_my_tt_response()
3205 tvlv_tt_data->flags = BATADV_TT_RESPONSE; in batadv_send_my_tt_response()
3206 tvlv_tt_data->ttvn = req_ttvn; in batadv_send_my_tt_response()
3209 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE; in batadv_send_my_tt_response()
3213 orig_node->orig, full_table ? 'F' : '.', req_ttvn); in batadv_send_my_tt_response()
3217 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr, in batadv_send_my_tt_response()
3224 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); in batadv_send_my_tt_response()
3226 spin_unlock_bh(&bat_priv->tt.commit_lock); in batadv_send_my_tt_response()
3230 /* The packet was for this host, so it doesn't need to be re-routed */ in batadv_send_my_tt_response()
3235 * batadv_send_tt_response() - send reply to tt request
3236 * @bat_priv: the bat priv with all the soft interface information
3262 if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) { in _batadv_tt_update_changes()
3263 roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM; in _batadv_tt_update_changes()
3265 (tt_change + i)->addr, in _batadv_tt_update_changes()
3266 ntohs((tt_change + i)->vid), in _batadv_tt_update_changes()
3271 (tt_change + i)->addr, in _batadv_tt_update_changes()
3272 ntohs((tt_change + i)->vid), in _batadv_tt_update_changes()
3273 (tt_change + i)->flags, ttvn)) in _batadv_tt_update_changes()
3283 set_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized); in _batadv_tt_update_changes()
3298 batadv_tt_global_del_orig(bat_priv, orig_node, -1, in batadv_tt_fill_gtable()
3304 spin_lock_bh(&orig_node->tt_buff_lock); in batadv_tt_fill_gtable()
3305 kfree(orig_node->tt_buff); in batadv_tt_fill_gtable()
3306 orig_node->tt_buff_len = 0; in batadv_tt_fill_gtable()
3307 orig_node->tt_buff = NULL; in batadv_tt_fill_gtable()
3308 spin_unlock_bh(&orig_node->tt_buff_lock); in batadv_tt_fill_gtable()
3310 atomic_set(&orig_node->last_ttvn, ttvn); in batadv_tt_fill_gtable()
3326 atomic_set(&orig_node->last_ttvn, ttvn); in batadv_tt_update_changes()
3330 * batadv_is_my_client() - check if a client is served by the local node
3331 * @bat_priv: the bat priv with all the soft interface information
3349 if ((tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) || in batadv_is_my_client()
3350 (tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM)) in batadv_is_my_client()
3359 * batadv_handle_tt_response() - process incoming tt reply
3360 * @bat_priv: the bat priv with all the soft interface information
3378 resp_src, tt_data->ttvn, num_entries, in batadv_handle_tt_response()
3379 ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.')); in batadv_handle_tt_response()
3385 spin_lock_bh(&orig_node->tt_lock); in batadv_handle_tt_response()
3388 change_offset *= ntohs(tt_data->num_vlan); in batadv_handle_tt_response()
3393 if (tt_data->flags & BATADV_TT_FULL_TABLE) { in batadv_handle_tt_response()
3394 batadv_tt_fill_gtable(bat_priv, tt_change, tt_data->ttvn, in batadv_handle_tt_response()
3398 tt_data->ttvn, tt_change); in batadv_handle_tt_response()
3404 spin_unlock_bh(&orig_node->tt_lock); in batadv_handle_tt_response()
3407 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_handle_tt_response()
3408 hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { in batadv_handle_tt_response()
3409 if (!batadv_compare_eth(node->addr, resp_src)) in batadv_handle_tt_response()
3411 hlist_del_init(&node->list); in batadv_handle_tt_response()
3415 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_handle_tt_response()
3424 spin_lock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_roam_list_free()
3426 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { in batadv_tt_roam_list_free()
3427 list_del(&node->list); in batadv_tt_roam_list_free()
3431 spin_unlock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_roam_list_free()
3438 spin_lock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_roam_purge()
3439 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { in batadv_tt_roam_purge()
3440 if (!batadv_has_timed_out(node->first_time, in batadv_tt_roam_purge()
3444 list_del(&node->list); in batadv_tt_roam_purge()
3447 spin_unlock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_roam_purge()
3451 * batadv_tt_check_roam_count() - check if a client has roamed too frequently
3452 * @bat_priv: the bat priv with all the soft interface information
3466 spin_lock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_check_roam_count()
3470 list_for_each_entry(tt_roam_node, &bat_priv->tt.roam_list, list) { in batadv_tt_check_roam_count()
3471 if (!batadv_compare_eth(tt_roam_node->addr, client)) in batadv_tt_check_roam_count()
3474 if (batadv_has_timed_out(tt_roam_node->first_time, in batadv_tt_check_roam_count()
3478 if (!batadv_atomic_dec_not_zero(&tt_roam_node->counter)) in batadv_tt_check_roam_count()
3491 tt_roam_node->first_time = jiffies; in batadv_tt_check_roam_count()
3492 atomic_set(&tt_roam_node->counter, in batadv_tt_check_roam_count()
3493 BATADV_ROAMING_MAX_COUNT - 1); in batadv_tt_check_roam_count()
3494 ether_addr_copy(tt_roam_node->addr, client); in batadv_tt_check_roam_count()
3496 list_add(&tt_roam_node->list, &bat_priv->tt.roam_list); in batadv_tt_check_roam_count()
3501 spin_unlock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_check_roam_count()
3506 * batadv_send_roam_adv() - send a roaming advertisement message
3507 * @bat_priv: the bat priv with all the soft interface information
3536 orig_node->orig, client, batadv_print_vid(vid)); in batadv_send_roam_adv()
3543 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr, in batadv_send_roam_adv()
3544 orig_node->orig, BATADV_TVLV_ROAM, 1, in batadv_send_roam_adv()
3566 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work, in batadv_tt_purge()
3571 * batadv_tt_free() - Free translation table of soft interface
3572 * @bat_priv: the bat priv with all the soft interface information
3581 cancel_delayed_work_sync(&bat_priv->tt.work); in batadv_tt_free()
3589 kfree(bat_priv->tt.last_changeset); in batadv_tt_free()
3593 * batadv_tt_local_set_flags() - set or unset the specified flags on the local
3595 * @bat_priv: the bat priv with all the soft interface information
3603 struct batadv_hashtable *hash = bat_priv->tt.local_hash; in batadv_tt_local_set_flags()
3611 for (i = 0; i < hash->size; i++) { in batadv_tt_local_set_flags()
3612 head = &hash->table[i]; in batadv_tt_local_set_flags()
3618 if ((tt_common_entry->flags & flags) == flags) in batadv_tt_local_set_flags()
3620 tt_common_entry->flags |= flags; in batadv_tt_local_set_flags()
3622 if (!(tt_common_entry->flags & flags)) in batadv_tt_local_set_flags()
3624 tt_common_entry->flags &= ~flags; in batadv_tt_local_set_flags()
3631 tt_common_entry->vid); in batadv_tt_local_set_flags()
3640 struct batadv_hashtable *hash = bat_priv->tt.local_hash; in batadv_tt_local_purge_pending_clients()
3651 for (i = 0; i < hash->size; i++) { in batadv_tt_local_purge_pending_clients()
3652 head = &hash->table[i]; in batadv_tt_local_purge_pending_clients()
3653 list_lock = &hash->list_locks[i]; in batadv_tt_local_purge_pending_clients()
3658 if (!(tt_common->flags & BATADV_TT_CLIENT_PENDING)) in batadv_tt_local_purge_pending_clients()
3663 tt_common->addr, in batadv_tt_local_purge_pending_clients()
3664 batadv_print_vid(tt_common->vid)); in batadv_tt_local_purge_pending_clients()
3666 batadv_tt_local_size_dec(bat_priv, tt_common->vid); in batadv_tt_local_purge_pending_clients()
3667 hlist_del_rcu(&tt_common->hash_entry); in batadv_tt_local_purge_pending_clients()
3679 * batadv_tt_local_commit_changes_nolock() - commit all pending local tt changes
3681 * @bat_priv: the bat priv with all the soft interface information
3683 * Caller must hold tt->commit_lock.
3687 lockdep_assert_held(&bat_priv->tt.commit_lock); in batadv_tt_local_commit_changes_nolock()
3689 if (atomic_read(&bat_priv->tt.local_changes) < 1) { in batadv_tt_local_commit_changes_nolock()
3690 if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt)) in batadv_tt_local_commit_changes_nolock()
3701 atomic_inc(&bat_priv->tt.vn); in batadv_tt_local_commit_changes_nolock()
3704 (u8)atomic_read(&bat_priv->tt.vn)); in batadv_tt_local_commit_changes_nolock()
3707 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); in batadv_tt_local_commit_changes_nolock()
3712 * batadv_tt_local_commit_changes() - commit all pending local tt changes which
3714 * @bat_priv: the bat priv with all the soft interface information
3718 spin_lock_bh(&bat_priv->tt.commit_lock); in batadv_tt_local_commit_changes()
3720 spin_unlock_bh(&bat_priv->tt.commit_lock); in batadv_tt_local_commit_changes()
3724 * batadv_is_ap_isolated() - Check if packet from upper layer should be dropped
3725 * @bat_priv: the bat priv with all the soft interface information
3744 if (!atomic_read(&vlan->ap_isolation)) in batadv_is_ap_isolated()
3767 * batadv_tt_update_orig() - update global translation table with new tt
3769 * @bat_priv: the bat priv with all the soft interface information
3783 u8 orig_ttvn = (u8)atomic_read(&orig_node->last_ttvn); in batadv_tt_update_orig()
3790 &orig_node->capa_initialized); in batadv_tt_update_orig()
3793 * increased by one -> we can apply the attached changes in batadv_tt_update_orig()
3795 if ((!has_tt_init && ttvn == 1) || ttvn - orig_ttvn == 1) { in batadv_tt_update_orig()
3806 spin_lock_bh(&orig_node->tt_lock); in batadv_tt_update_orig()
3817 spin_unlock_bh(&orig_node->tt_lock); in batadv_tt_update_orig()
3833 * in sync anymore -> request fresh tt data in batadv_tt_update_orig()
3841 orig_node->orig, ttvn, orig_ttvn, in batadv_tt_update_orig()
3852 * batadv_tt_global_client_is_roaming() - check if a client is marked as roaming
3853 * @bat_priv: the bat priv with all the soft interface information
3871 ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM; in batadv_tt_global_client_is_roaming()
3878 * batadv_tt_local_client_is_roaming() - tells whether the client is roaming
3879 * @bat_priv: the bat priv with all the soft interface information
3884 * this node anymore) or not. If yes, the client is still present in the table
3897 ret = tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM; in batadv_tt_local_client_is_roaming()
3904 * batadv_tt_add_temporary_global_entry() - Add temporary entry to global TT
3905 * @bat_priv: the bat priv with all the soft interface information
3925 atomic_read(&orig_node->last_ttvn))) in batadv_tt_add_temporary_global_entry()
3930 addr, batadv_print_vid(vid), orig_node->orig); in batadv_tt_add_temporary_global_entry()
3936 * batadv_tt_local_resize_to_mtu() - resize the local translation table fit the
3946 int packet_size_max = atomic_read(&bat_priv->packet_size_max); in batadv_tt_local_resize_to_mtu()
3950 spin_lock_bh(&bat_priv->tt.commit_lock); in batadv_tt_local_resize_to_mtu()
3973 spin_unlock_bh(&bat_priv->tt.commit_lock); in batadv_tt_local_resize_to_mtu()
3977 * batadv_tt_tvlv_ogm_handler_v1() - process incoming tt tvlv container
3978 * @bat_priv: the bat priv with all the soft interface information
3998 tvlv_value_len -= sizeof(*tt_data); in batadv_tt_tvlv_ogm_handler_v1()
4000 num_vlan = ntohs(tt_data->num_vlan); in batadv_tt_tvlv_ogm_handler_v1()
4007 tvlv_value_len -= sizeof(*tt_vlan) * num_vlan; in batadv_tt_tvlv_ogm_handler_v1()
4012 num_entries, tt_data->ttvn); in batadv_tt_tvlv_ogm_handler_v1()
4016 * batadv_tt_tvlv_unicast_handler_v1() - process incoming (unicast) tt tvlv
4018 * @bat_priv: the bat priv with all the soft interface information
4024 * Return: NET_RX_DROP if the tt tvlv is to be re-routed, NET_RX_SUCCESS
4041 tvlv_value_len -= sizeof(*tt_data); in batadv_tt_tvlv_unicast_handler_v1()
4044 tt_vlan_len *= ntohs(tt_data->num_vlan); in batadv_tt_tvlv_unicast_handler_v1()
4049 tvlv_value_len -= tt_vlan_len; in batadv_tt_tvlv_unicast_handler_v1()
4052 switch (tt_data->flags & BATADV_TT_DATA_TYPE_MASK) { in batadv_tt_tvlv_unicast_handler_v1()
4061 if (tt_data->flags & BATADV_TT_FULL_TABLE) in batadv_tt_tvlv_unicast_handler_v1()
4069 /* tvlv API will re-route the packet */ 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()
4098 * batadv_roam_tvlv_unicast_handler_v1() - process incoming tt roam tvlv
4100 * @bat_priv: the bat priv with all the soft interface information
4106 * Return: NET_RX_DROP if the tt roam tvlv is to be re-routed, NET_RX_SUCCESS
4119 * (the tvlv API will re-route the packet). in batadv_roam_tvlv_unicast_handler_v1()
4136 src, roaming_adv->client); in batadv_roam_tvlv_unicast_handler_v1()
4138 batadv_tt_global_add(bat_priv, orig_node, roaming_adv->client, in batadv_roam_tvlv_unicast_handler_v1()
4139 ntohs(roaming_adv->vid), BATADV_TT_CLIENT_ROAM, in batadv_roam_tvlv_unicast_handler_v1()
4140 atomic_read(&orig_node->last_ttvn) + 1); in batadv_roam_tvlv_unicast_handler_v1()
4148 * batadv_tt_init() - initialise the translation table internals
4149 * @bat_priv: the bat priv with all the soft interface information
4178 INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge); in batadv_tt_init()
4179 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work, in batadv_tt_init()
4186 * batadv_tt_global_is_isolated() - check if a client is marked as isolated
4187 * @bat_priv: the bat priv with all the soft interface information
4204 ret = tt->common.flags & BATADV_TT_CLIENT_ISOLA; in batadv_tt_global_is_isolated()
4212 * batadv_tt_cache_init() - Initialize tt memory object cache
4228 return -ENOMEM; in batadv_tt_cache_init()
4277 return -ENOMEM; in batadv_tt_cache_init()
4281 * batadv_tt_cache_destroy() - Destroy tt memory object cache