Lines Matching +full:interface +full:- +full:node

1 // SPDX-License-Identifier: GPL-2.0
7 #include "translation-table.h"
47 #include "hard-interface.h"
52 #include "soft-interface.h"
79 * batadv_compare_tt() - check if two TT entries are the same
80 * @node: the list element pointer of the first TT entry
87 static bool batadv_compare_tt(const struct hlist_node *node, const void *data2) in batadv_compare_tt() argument
89 const void *data1 = container_of(node, struct batadv_tt_common_entry, in batadv_compare_tt()
94 return (tt1->vid == tt2->vid) && batadv_compare_eth(data1, data2); in batadv_compare_tt()
98 * batadv_choose_tt() - return the index of the tt entry in the hash table
111 hash = jhash(&tt->addr, ETH_ALEN, hash); in batadv_choose_tt()
112 hash = jhash(&tt->vid, sizeof(tt->vid), hash); in batadv_choose_tt()
118 * batadv_tt_hash_find() - look for a client in the given hash table
140 index = batadv_choose_tt(&to_search, hash->size); in batadv_tt_hash_find()
141 head = &hash->table[index]; in batadv_tt_hash_find()
148 if (tt->vid != vid) in batadv_tt_hash_find()
151 if (!kref_get_unless_zero(&tt->refcount)) in batadv_tt_hash_find()
163 * batadv_tt_local_hash_find() - search the local table for a given client
164 * @bat_priv: the bat priv with all the soft interface information
178 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, addr, in batadv_tt_local_hash_find()
188 * batadv_tt_global_hash_find() - search the global table for a given client
189 * @bat_priv: the bat priv with all the soft interface information
203 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, addr, in batadv_tt_global_hash_find()
213 * batadv_tt_local_entry_release() - release tt_local_entry from lists and queue
224 batadv_softif_vlan_put(tt_local_entry->vlan); in batadv_tt_local_entry_release()
230 * batadv_tt_local_entry_put() - decrement the tt_local_entry refcounter and
240 kref_put(&tt_local_entry->common.refcount, in batadv_tt_local_entry_put()
245 * batadv_tt_global_entry_release() - release tt_global_entry from lists and
262 * batadv_tt_global_hash_count() - count the number of orig entries
263 * @bat_priv: the bat priv with all the soft interface information
280 count = atomic_read(&tt_global_entry->orig_list_count); in batadv_tt_global_hash_count()
287 * batadv_tt_local_size_mod() - change the size by v of the local table
289 * @bat_priv: the bat priv with all the soft interface information
290 * @vid: the VLAN identifier of the sub-table to change
302 atomic_add(v, &vlan->tt.num_entries); in batadv_tt_local_size_mod()
308 * batadv_tt_local_size_inc() - increase by one the local table size for the
310 * @bat_priv: the bat priv with all the soft interface information
320 * batadv_tt_local_size_dec() - decrease by one the local table size for the
322 * @bat_priv: the bat priv with all the soft interface information
328 batadv_tt_local_size_mod(bat_priv, vid, -1); in batadv_tt_local_size_dec()
332 * batadv_tt_global_size_mod() - change the size by v of the global table
347 if (atomic_add_return(v, &vlan->tt.num_entries) == 0) { in batadv_tt_global_size_mod()
348 spin_lock_bh(&orig_node->vlan_list_lock); in batadv_tt_global_size_mod()
349 if (!hlist_unhashed(&vlan->list)) { in batadv_tt_global_size_mod()
350 hlist_del_init_rcu(&vlan->list); in batadv_tt_global_size_mod()
353 spin_unlock_bh(&orig_node->vlan_list_lock); in batadv_tt_global_size_mod()
360 * batadv_tt_global_size_inc() - increase by one the global table size for the
372 * batadv_tt_global_size_dec() - decrease by one the global table size for the
380 batadv_tt_global_size_mod(orig_node, vid, -1); in batadv_tt_global_size_dec()
384 * batadv_tt_orig_list_entry_release() - release tt orig entry from lists and
395 batadv_orig_node_put(orig_entry->orig_node); in batadv_tt_orig_list_entry_release()
400 * batadv_tt_orig_list_entry_put() - decrement the tt orig entry refcounter and
410 kref_put(&orig_entry->refcount, batadv_tt_orig_list_entry_release); in batadv_tt_orig_list_entry_put()
414 * batadv_tt_local_event() - store a local TT event (ADD/DEL)
415 * @bat_priv: the bat priv with all the soft interface information
424 struct batadv_tt_common_entry *common = &tt_local_entry->common; in batadv_tt_local_event()
425 u8 flags = common->flags | event_flags; in batadv_tt_local_event()
433 tt_change_node->change.flags = flags; in batadv_tt_local_event()
434 memset(tt_change_node->change.reserved, 0, in batadv_tt_local_event()
435 sizeof(tt_change_node->change.reserved)); in batadv_tt_local_event()
436 ether_addr_copy(tt_change_node->change.addr, common->addr); in batadv_tt_local_event()
437 tt_change_node->change.vid = htons(common->vid); in batadv_tt_local_event()
442 spin_lock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_local_event()
443 changes = READ_ONCE(bat_priv->tt.local_changes); in batadv_tt_local_event()
444 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, in batadv_tt_local_event()
446 if (!batadv_compare_eth(entry->change.addr, common->addr)) in batadv_tt_local_event()
449 del_op_entry = entry->change.flags & BATADV_TT_CLIENT_DEL; in batadv_tt_local_event()
458 list_del(&entry->list); in batadv_tt_local_event()
460 changes--; in batadv_tt_local_event()
466 entry->change.flags = flags; in batadv_tt_local_event()
474 list_add_tail(&tt_change_node->list, &bat_priv->tt.changes_list); in batadv_tt_local_event()
478 WRITE_ONCE(bat_priv->tt.local_changes, changes); in batadv_tt_local_event()
479 spin_unlock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_local_event()
483 * batadv_tt_len() - compute length in bytes of given number of tt changes
494 * batadv_tt_entries() - compute the number of entries fitting in tt_len bytes
505 * batadv_tt_local_table_transmit_size() - calculates the local translation
507 * @bat_priv: the bat priv with all the soft interface information
519 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { in batadv_tt_local_table_transmit_size()
521 tt_local_entries += atomic_read(&vlan->tt.num_entries); in batadv_tt_local_table_transmit_size()
536 if (bat_priv->tt.local_hash) in batadv_tt_local_init()
539 bat_priv->tt.local_hash = batadv_hash_new(1024); in batadv_tt_local_init()
541 if (!bat_priv->tt.local_hash) in batadv_tt_local_init()
542 return -ENOMEM; in batadv_tt_local_init()
544 batadv_hash_set_lock_class(bat_priv->tt.local_hash, in batadv_tt_local_init()
559 tt_global->common.addr, in batadv_tt_global_free()
560 batadv_print_vid(tt_global->common.vid), message); in batadv_tt_global_free()
562 tt_removed_node = batadv_hash_remove(bat_priv->tt.global_hash, in batadv_tt_global_free()
565 &tt_global->common); in batadv_tt_global_free()
577 * batadv_tt_local_add() - add a new client to the local table or update an
579 * @soft_iface: netdev struct of the mesh interface
582 * @ifindex: index of the interface where the client is connected to (useful to
584 * @mark: the value contained in the skb->mark field of the received packet (if
619 tt_local->last_seen = jiffies; in batadv_tt_local_add()
620 if (tt_local->common.flags & BATADV_TT_CLIENT_PENDING) { in batadv_tt_local_add()
622 "Re-adding pending client %pM (vid: %d)\n", in batadv_tt_local_add()
629 tt_local->common.flags &= ~BATADV_TT_CLIENT_PENDING; in batadv_tt_local_add()
633 if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) { in batadv_tt_local_add()
638 * and the node got a roaming_advertisement message. Now in batadv_tt_local_add()
642 tt_local->common.flags &= ~BATADV_TT_CLIENT_ROAM; in batadv_tt_local_add()
651 packet_size_max = atomic_read(&bat_priv->packet_size_max); in batadv_tt_local_add()
667 "adding TT local entry %pM to non-existent VLAN %d\n", in batadv_tt_local_add()
677 (u8)atomic_read(&bat_priv->tt.vn)); in batadv_tt_local_add()
679 ether_addr_copy(tt_local->common.addr, addr); in batadv_tt_local_add()
684 tt_local->common.flags = BATADV_TT_CLIENT_NEW; in batadv_tt_local_add()
685 tt_local->common.vid = vid; in batadv_tt_local_add()
687 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI; in batadv_tt_local_add()
688 kref_init(&tt_local->common.refcount); in batadv_tt_local_add()
689 tt_local->last_seen = jiffies; in batadv_tt_local_add()
690 tt_local->common.added_at = tt_local->last_seen; in batadv_tt_local_add()
691 tt_local->vlan = vlan; in batadv_tt_local_add()
693 /* the batman interface mac and multicast addresses should never be in batadv_tt_local_add()
696 if (batadv_compare_eth(addr, soft_iface->dev_addr) || in batadv_tt_local_add()
698 tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE; in batadv_tt_local_add()
700 kref_get(&tt_local->common.refcount); in batadv_tt_local_add()
701 hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt, in batadv_tt_local_add()
702 batadv_choose_tt, &tt_local->common, in batadv_tt_local_add()
703 &tt_local->common.hash_entry); in batadv_tt_local_add()
718 if (tt_global && !(tt_global->common.flags & BATADV_TT_CLIENT_ROAM)) { in batadv_tt_local_add()
719 /* These node are probably going to update their tt table */ in batadv_tt_local_add()
720 head = &tt_global->orig_list; in batadv_tt_local_add()
723 batadv_send_roam_adv(bat_priv, tt_global->common.addr, in batadv_tt_local_add()
724 tt_global->common.vid, in batadv_tt_local_add()
725 orig_entry->orig_node); in batadv_tt_local_add()
735 tt_global->common.flags |= BATADV_TT_CLIENT_ROAM; in batadv_tt_local_add()
736 tt_global->roam_at = jiffies; in batadv_tt_local_add()
743 remote_flags = tt_local->common.flags & BATADV_TT_REMOTE_MASK; in batadv_tt_local_add()
746 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI; in batadv_tt_local_add()
748 tt_local->common.flags &= ~BATADV_TT_CLIENT_WIFI; in batadv_tt_local_add()
752 * non-mesh client in batadv_tt_local_add()
754 match_mark = (mark & bat_priv->isolation_mark_mask); in batadv_tt_local_add()
755 if (bat_priv->isolation_mark_mask && in batadv_tt_local_add()
756 match_mark == bat_priv->isolation_mark) in batadv_tt_local_add()
757 tt_local->common.flags |= BATADV_TT_CLIENT_ISOLA; in batadv_tt_local_add()
759 tt_local->common.flags &= ~BATADV_TT_CLIENT_ISOLA; in batadv_tt_local_add()
764 if (remote_flags ^ (tt_local->common.flags & BATADV_TT_REMOTE_MASK)) in batadv_tt_local_add()
777 * batadv_tt_prepare_tvlv_global_data() - prepare the TVLV TT header to send
778 * within a TT Response directed to another node
783 * @tt_len: pointer to the length to reserve to the tt_change. if -1 this
789 * objects, one per active VLAN served by the originator node.
807 spin_lock_bh(&orig_node->vlan_list_lock); in batadv_tt_prepare_tvlv_global_data()
808 hlist_for_each_entry(vlan, &orig_node->vlan_list, list) { in batadv_tt_prepare_tvlv_global_data()
810 num_entries += atomic_read(&vlan->tt.num_entries); in batadv_tt_prepare_tvlv_global_data()
828 (*tt_data)->flags = BATADV_NO_FLAGS; in batadv_tt_prepare_tvlv_global_data()
829 (*tt_data)->ttvn = atomic_read(&orig_node->last_ttvn); in batadv_tt_prepare_tvlv_global_data()
830 (*tt_data)->num_vlan = htons(num_vlan); in batadv_tt_prepare_tvlv_global_data()
832 tt_vlan = (*tt_data)->vlan_data; in batadv_tt_prepare_tvlv_global_data()
833 hlist_for_each_entry(vlan, &orig_node->vlan_list, list) { in batadv_tt_prepare_tvlv_global_data()
834 tt_vlan->vid = htons(vlan->vid); in batadv_tt_prepare_tvlv_global_data()
835 tt_vlan->crc = htonl(vlan->tt.crc); in batadv_tt_prepare_tvlv_global_data()
836 tt_vlan->reserved = 0; in batadv_tt_prepare_tvlv_global_data()
845 spin_unlock_bh(&orig_node->vlan_list_lock); in batadv_tt_prepare_tvlv_global_data()
850 * batadv_tt_prepare_tvlv_local_data() - allocate and prepare the TT TVLV for
851 * this node
852 * @bat_priv: the bat priv with all the soft interface information
856 * @tt_len: pointer to the length to reserve to the tt_change. if -1 this
882 spin_lock_bh(&bat_priv->softif_vlan_list_lock); in batadv_tt_prepare_tvlv_local_data()
883 hlist_for_each_entry(vlan, &bat_priv->softif_vlan_list, list) { in batadv_tt_prepare_tvlv_local_data()
884 vlan_entries = atomic_read(&vlan->tt.num_entries); in batadv_tt_prepare_tvlv_local_data()
907 (*tt_data)->flags = BATADV_NO_FLAGS; in batadv_tt_prepare_tvlv_local_data()
908 (*tt_data)->ttvn = atomic_read(&bat_priv->tt.vn); in batadv_tt_prepare_tvlv_local_data()
909 (*tt_data)->num_vlan = htons(num_vlan); in batadv_tt_prepare_tvlv_local_data()
911 tt_vlan = (*tt_data)->vlan_data; in batadv_tt_prepare_tvlv_local_data()
912 hlist_for_each_entry(vlan, &bat_priv->softif_vlan_list, list) { in batadv_tt_prepare_tvlv_local_data()
913 vlan_entries = atomic_read(&vlan->tt.num_entries); in batadv_tt_prepare_tvlv_local_data()
917 tt_vlan->vid = htons(vlan->vid); in batadv_tt_prepare_tvlv_local_data()
918 tt_vlan->crc = htonl(vlan->tt.crc); in batadv_tt_prepare_tvlv_local_data()
919 tt_vlan->reserved = 0; in batadv_tt_prepare_tvlv_local_data()
928 spin_unlock_bh(&bat_priv->softif_vlan_list_lock); in batadv_tt_prepare_tvlv_local_data()
933 * batadv_tt_tvlv_container_update() - update the translation table tvlv
935 * @bat_priv: the bat priv with all the soft interface information
949 tt_diff_entries_num = READ_ONCE(bat_priv->tt.local_changes); in batadv_tt_tvlv_container_update()
959 if (tt_diff_len > bat_priv->soft_iface->mtu) { in batadv_tt_tvlv_container_update()
970 tt_data->flags = BATADV_TT_OGM_DIFF; in batadv_tt_tvlv_container_update()
975 spin_lock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_tvlv_container_update()
976 WRITE_ONCE(bat_priv->tt.local_changes, 0); in batadv_tt_tvlv_container_update()
978 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, in batadv_tt_tvlv_container_update()
982 &entry->change, in batadv_tt_tvlv_container_update()
986 list_del(&entry->list); in batadv_tt_tvlv_container_update()
989 spin_unlock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_tvlv_container_update()
991 tt_extra_len = batadv_tt_len(tt_diff_entries_num - in batadv_tt_tvlv_container_update()
995 spin_lock_bh(&bat_priv->tt.last_changeset_lock); in batadv_tt_tvlv_container_update()
996 kfree(bat_priv->tt.last_changeset); in batadv_tt_tvlv_container_update()
997 bat_priv->tt.last_changeset_len = 0; in batadv_tt_tvlv_container_update()
998 bat_priv->tt.last_changeset = NULL; in batadv_tt_tvlv_container_update()
1002 tt_diff_len -= tt_extra_len; in batadv_tt_tvlv_container_update()
1006 bat_priv->tt.last_changeset = kzalloc(tt_diff_len, GFP_ATOMIC); in batadv_tt_tvlv_container_update()
1007 if (bat_priv->tt.last_changeset) { in batadv_tt_tvlv_container_update()
1008 memcpy(bat_priv->tt.last_changeset, in batadv_tt_tvlv_container_update()
1010 bat_priv->tt.last_changeset_len = tt_diff_len; in batadv_tt_tvlv_container_update()
1013 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); in batadv_tt_tvlv_container_update()
1016 tvlv_len -= tt_extra_len; in batadv_tt_tvlv_container_update()
1024 * batadv_tt_local_dump_entry() - Dump one TT local entry into a message
1028 * @bat_priv: The bat priv with all the soft interface information
1046 last_seen_msecs = jiffies_to_msecs(jiffies - local->last_seen); in batadv_tt_local_dump_entry()
1048 vlan = batadv_softif_vlan_get(bat_priv, common->vid); in batadv_tt_local_dump_entry()
1052 crc = vlan->tt.crc; in batadv_tt_local_dump_entry()
1056 hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq, in batadv_tt_local_dump_entry()
1060 return -ENOBUFS; in batadv_tt_local_dump_entry()
1064 if (nla_put(msg, BATADV_ATTR_TT_ADDRESS, ETH_ALEN, common->addr) || in batadv_tt_local_dump_entry()
1066 nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) || in batadv_tt_local_dump_entry()
1067 nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, common->flags)) in batadv_tt_local_dump_entry()
1070 if (!(common->flags & BATADV_TT_CLIENT_NOPURGE) && in batadv_tt_local_dump_entry()
1079 return -EMSGSIZE; in batadv_tt_local_dump_entry()
1083 * batadv_tt_local_dump_bucket() - Dump one TT local bucket into a message
1087 * @bat_priv: The bat priv with all the soft interface information
1104 spin_lock_bh(&hash->list_locks[bucket]); in batadv_tt_local_dump_bucket()
1105 cb->seq = atomic_read(&hash->generation) << 1 | 1; in batadv_tt_local_dump_bucket()
1107 hlist_for_each_entry(common, &hash->table[bucket], hash_entry) { in batadv_tt_local_dump_bucket()
1113 spin_unlock_bh(&hash->list_locks[bucket]); in batadv_tt_local_dump_bucket()
1114 *idx_s = idx - 1; in batadv_tt_local_dump_bucket()
1115 return -EMSGSIZE; in batadv_tt_local_dump_bucket()
1118 spin_unlock_bh(&hash->list_locks[bucket]); in batadv_tt_local_dump_bucket()
1125 * batadv_tt_local_dump() - Dump TT local entries into a message
1138 int bucket = cb->args[0]; in batadv_tt_local_dump()
1139 int idx = cb->args[1]; in batadv_tt_local_dump()
1140 int portid = NETLINK_CB(cb->skb).portid; in batadv_tt_local_dump()
1149 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { in batadv_tt_local_dump()
1150 ret = -ENOENT; in batadv_tt_local_dump()
1154 hash = bat_priv->tt.local_hash; in batadv_tt_local_dump()
1156 while (bucket < hash->size) { in batadv_tt_local_dump()
1164 ret = msg->len; in batadv_tt_local_dump()
1170 cb->args[0] = bucket; in batadv_tt_local_dump()
1171 cb->args[1] = idx; in batadv_tt_local_dump()
1187 tt_local_entry->common.flags |= BATADV_TT_CLIENT_PENDING; in batadv_tt_local_set_pending()
1191 tt_local_entry->common.addr, in batadv_tt_local_set_pending()
1192 batadv_print_vid(tt_local_entry->common.vid), message); in batadv_tt_local_set_pending()
1196 * batadv_tt_local_remove() - logically remove an entry from the local table
1197 * @bat_priv: the bat priv with all the soft interface information
1218 curr_flags = tt_local_entry->common.flags; in batadv_tt_local_remove()
1221 /* if this global entry addition is due to a roaming, the node has to in batadv_tt_local_remove()
1228 tt_local_entry->common.flags |= BATADV_TT_CLIENT_ROAM; in batadv_tt_local_remove()
1231 if (!(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) { in batadv_tt_local_remove()
1241 tt_removed_node = batadv_hash_remove(bat_priv->tt.local_hash, in batadv_tt_local_remove()
1244 &tt_local_entry->common); in batadv_tt_local_remove()
1261 * batadv_tt_local_purge_list() - purge inactive tt local entries
1262 * @bat_priv: the bat priv with all the soft interface information
1280 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_NOPURGE) in batadv_tt_local_purge_list()
1284 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) in batadv_tt_local_purge_list()
1287 if (!batadv_has_timed_out(tt_local_entry->last_seen, timeout)) in batadv_tt_local_purge_list()
1296 * batadv_tt_local_purge() - purge inactive tt local entries
1297 * @bat_priv: the bat priv with all the soft interface information
1304 struct batadv_hashtable *hash = bat_priv->tt.local_hash; in batadv_tt_local_purge()
1309 for (i = 0; i < hash->size; i++) { in batadv_tt_local_purge()
1310 head = &hash->table[i]; in batadv_tt_local_purge()
1311 list_lock = &hash->list_locks[i]; in batadv_tt_local_purge()
1329 if (!bat_priv->tt.local_hash) in batadv_tt_local_table_free()
1332 hash = bat_priv->tt.local_hash; in batadv_tt_local_table_free()
1334 for (i = 0; i < hash->size; i++) { in batadv_tt_local_table_free()
1335 head = &hash->table[i]; in batadv_tt_local_table_free()
1336 list_lock = &hash->list_locks[i]; in batadv_tt_local_table_free()
1341 hlist_del_rcu(&tt_common_entry->hash_entry); in batadv_tt_local_table_free()
1353 bat_priv->tt.local_hash = NULL; in batadv_tt_local_table_free()
1358 if (bat_priv->tt.global_hash) in batadv_tt_global_init()
1361 bat_priv->tt.global_hash = batadv_hash_new(1024); in batadv_tt_global_init()
1363 if (!bat_priv->tt.global_hash) in batadv_tt_global_init()
1364 return -ENOMEM; in batadv_tt_global_init()
1366 batadv_hash_set_lock_class(bat_priv->tt.global_hash, in batadv_tt_global_init()
1376 spin_lock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_changes_list_free()
1378 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, in batadv_tt_changes_list_free()
1380 list_del(&entry->list); in batadv_tt_changes_list_free()
1384 WRITE_ONCE(bat_priv->tt.local_changes, 0); in batadv_tt_changes_list_free()
1385 spin_unlock_bh(&bat_priv->tt.changes_list_lock); in batadv_tt_changes_list_free()
1389 * batadv_tt_global_orig_entry_find() - find a TT orig_list_entry
1407 head = &entry->orig_list; in batadv_tt_global_orig_entry_find()
1409 if (tmp_orig_entry->orig_node != orig_node) in batadv_tt_global_orig_entry_find()
1411 if (!kref_get_unless_zero(&tmp_orig_entry->refcount)) in batadv_tt_global_orig_entry_find()
1423 * batadv_tt_global_entry_has_orig() - check if a TT global entry is also
1447 *flags = orig_entry->flags; in batadv_tt_global_entry_has_orig()
1456 * batadv_tt_global_sync_flags() - update TT sync flags
1470 head = &tt_global->orig_list; in batadv_tt_global_sync_flags()
1472 flags |= orig_entry->flags; in batadv_tt_global_sync_flags()
1475 flags |= tt_global->common.flags & (~BATADV_TT_SYNC_MASK); in batadv_tt_global_sync_flags()
1476 tt_global->common.flags = flags; in batadv_tt_global_sync_flags()
1480 * batadv_tt_global_orig_entry_add() - add or update a TT orig entry
1493 spin_lock_bh(&tt_global->list_lock); in batadv_tt_global_orig_entry_add()
1500 orig_entry->ttvn = ttvn; in batadv_tt_global_orig_entry_add()
1501 orig_entry->flags = flags; in batadv_tt_global_orig_entry_add()
1509 INIT_HLIST_NODE(&orig_entry->list); in batadv_tt_global_orig_entry_add()
1510 kref_get(&orig_node->refcount); in batadv_tt_global_orig_entry_add()
1511 batadv_tt_global_size_inc(orig_node, tt_global->common.vid); in batadv_tt_global_orig_entry_add()
1512 orig_entry->orig_node = orig_node; in batadv_tt_global_orig_entry_add()
1513 orig_entry->ttvn = ttvn; in batadv_tt_global_orig_entry_add()
1514 orig_entry->flags = flags; in batadv_tt_global_orig_entry_add()
1515 kref_init(&orig_entry->refcount); in batadv_tt_global_orig_entry_add()
1517 kref_get(&orig_entry->refcount); in batadv_tt_global_orig_entry_add()
1518 hlist_add_head_rcu(&orig_entry->list, in batadv_tt_global_orig_entry_add()
1519 &tt_global->orig_list); in batadv_tt_global_orig_entry_add()
1520 atomic_inc(&tt_global->orig_list_count); in batadv_tt_global_orig_entry_add()
1527 spin_unlock_bh(&tt_global->list_lock); in batadv_tt_global_orig_entry_add()
1531 * batadv_tt_global_add() - add a new TT global entry or update an existing one
1532 * @bat_priv: the bat priv with all the soft interface information
1534 * @tt_addr: the mac address of the non-mesh client
1536 * @flags: TT flags that have to be set for this non-mesh client
1537 * @ttvn: the tt version number ever announcing this non-mesh client
1543 * If a TT local entry exists for this non-mesh client remove it.
1562 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) in batadv_tt_global_add()
1568 /* if the node already has a local client for this entry, it has to wait in batadv_tt_global_add()
1573 !(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) in batadv_tt_global_add()
1582 common = &tt_global_entry->common; in batadv_tt_global_add()
1583 ether_addr_copy(common->addr, tt_addr); in batadv_tt_global_add()
1584 common->vid = vid; in batadv_tt_global_add()
1586 if (!is_multicast_ether_addr(common->addr)) in batadv_tt_global_add()
1587 common->flags = flags & (~BATADV_TT_SYNC_MASK); in batadv_tt_global_add()
1589 tt_global_entry->roam_at = 0; in batadv_tt_global_add()
1590 /* node must store current time in case of roaming. This is in batadv_tt_global_add()
1595 tt_global_entry->roam_at = jiffies; in batadv_tt_global_add()
1596 kref_init(&common->refcount); in batadv_tt_global_add()
1597 common->added_at = jiffies; in batadv_tt_global_add()
1599 INIT_HLIST_HEAD(&tt_global_entry->orig_list); in batadv_tt_global_add()
1600 atomic_set(&tt_global_entry->orig_list_count, 0); in batadv_tt_global_add()
1601 spin_lock_init(&tt_global_entry->list_lock); in batadv_tt_global_add()
1603 kref_get(&common->refcount); in batadv_tt_global_add()
1604 hash_added = batadv_hash_add(bat_priv->tt.global_hash, in batadv_tt_global_add()
1607 &common->hash_entry); in batadv_tt_global_add()
1615 common = &tt_global_entry->common; in batadv_tt_global_add()
1627 if (!(common->flags & BATADV_TT_CLIENT_TEMP)) in batadv_tt_global_add()
1638 * remove the previous temporary orig node and re-add it in batadv_tt_global_add()
1640 * is a non-temporary entry is preferred. in batadv_tt_global_add()
1642 if (common->flags & BATADV_TT_CLIENT_TEMP) { in batadv_tt_global_add()
1644 common->flags &= ~BATADV_TT_CLIENT_TEMP; in batadv_tt_global_add()
1651 if (!is_multicast_ether_addr(common->addr)) in batadv_tt_global_add()
1652 common->flags |= flags & (~BATADV_TT_SYNC_MASK); in batadv_tt_global_add()
1661 if (common->flags & BATADV_TT_CLIENT_ROAM) { in batadv_tt_global_add()
1663 common->flags &= ~BATADV_TT_CLIENT_ROAM; in batadv_tt_global_add()
1664 tt_global_entry->roam_at = 0; in batadv_tt_global_add()
1674 common->addr, batadv_print_vid(common->vid), in batadv_tt_global_add()
1675 orig_node->orig); in batadv_tt_global_add()
1689 tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI; in batadv_tt_global_add()
1695 tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM; in batadv_tt_global_add()
1704 * batadv_transtable_best_orig() - Get best originator list entry from tt entry
1705 * @bat_priv: the bat priv with all the soft interface information
1716 struct batadv_algo_ops *bao = bat_priv->algo_ops; in batadv_transtable_best_orig()
1720 head = &tt_global_entry->orig_list; in batadv_transtable_best_orig()
1722 router = batadv_orig_router_get(orig_entry->orig_node, in batadv_transtable_best_orig()
1728 bao->neigh.cmp(router, BATADV_IF_DEFAULT, best_router, in batadv_transtable_best_orig()
1747 * batadv_tt_global_dump_subentry() - Dump all TT local entries into a message
1752 * @orig: Originator node announcing a non-mesh client
1763 u16 flags = (common->flags & (~BATADV_TT_SYNC_MASK)) | orig->flags; in batadv_tt_global_dump_subentry()
1769 vlan = batadv_orig_node_vlan_get(orig->orig_node, in batadv_tt_global_dump_subentry()
1770 common->vid); in batadv_tt_global_dump_subentry()
1774 crc = vlan->tt.crc; in batadv_tt_global_dump_subentry()
1782 return -ENOBUFS; in batadv_tt_global_dump_subentry()
1784 last_ttvn = atomic_read(&orig->orig_node->last_ttvn); in batadv_tt_global_dump_subentry()
1786 if (nla_put(msg, BATADV_ATTR_TT_ADDRESS, ETH_ALEN, common->addr) || in batadv_tt_global_dump_subentry()
1788 orig->orig_node->orig) || in batadv_tt_global_dump_subentry()
1789 nla_put_u8(msg, BATADV_ATTR_TT_TTVN, orig->ttvn) || in batadv_tt_global_dump_subentry()
1792 nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) || in batadv_tt_global_dump_subentry()
1804 return -EMSGSIZE; in batadv_tt_global_dump_subentry()
1808 * batadv_tt_global_dump_entry() - Dump one TT global entry into a message
1812 * @bat_priv: The bat priv with all the soft interface information
1833 head = &global->orig_list; in batadv_tt_global_dump_entry()
1843 *sub_s = sub - 1; in batadv_tt_global_dump_entry()
1844 return -EMSGSIZE; in batadv_tt_global_dump_entry()
1853 * batadv_tt_global_dump_bucket() - Dump one TT local bucket into a message
1857 * @bat_priv: The bat priv with all the soft interface information
1880 *idx_s = idx - 1; in batadv_tt_global_dump_bucket()
1881 return -EMSGSIZE; in batadv_tt_global_dump_bucket()
1892 * batadv_tt_global_dump() - Dump TT global entries into a message
1906 int bucket = cb->args[0]; in batadv_tt_global_dump()
1907 int idx = cb->args[1]; in batadv_tt_global_dump()
1908 int sub = cb->args[2]; in batadv_tt_global_dump()
1909 int portid = NETLINK_CB(cb->skb).portid; in batadv_tt_global_dump()
1918 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { in batadv_tt_global_dump()
1919 ret = -ENOENT; in batadv_tt_global_dump()
1923 hash = bat_priv->tt.global_hash; in batadv_tt_global_dump()
1925 while (bucket < hash->size) { in batadv_tt_global_dump()
1926 head = &hash->table[bucket]; in batadv_tt_global_dump()
1929 cb->nlh->nlmsg_seq, bat_priv, in batadv_tt_global_dump()
1936 ret = msg->len; in batadv_tt_global_dump()
1942 cb->args[0] = bucket; in batadv_tt_global_dump()
1943 cb->args[1] = idx; in batadv_tt_global_dump()
1944 cb->args[2] = sub; in batadv_tt_global_dump()
1950 * _batadv_tt_global_del_orig_entry() - remove and free an orig_entry
1957 * Caller must hold tt_global_entry->list_lock and ensure orig_entry->list is
1964 lockdep_assert_held(&tt_global_entry->list_lock); in _batadv_tt_global_del_orig_entry()
1966 batadv_tt_global_size_dec(orig_entry->orig_node, in _batadv_tt_global_del_orig_entry()
1967 tt_global_entry->common.vid); in _batadv_tt_global_del_orig_entry()
1968 atomic_dec(&tt_global_entry->orig_list_count); in _batadv_tt_global_del_orig_entry()
1969 /* requires holding tt_global_entry->list_lock and orig_entry->list in _batadv_tt_global_del_orig_entry()
1972 hlist_del_rcu(&orig_entry->list); in _batadv_tt_global_del_orig_entry()
1984 spin_lock_bh(&tt_global_entry->list_lock); in batadv_tt_global_del_orig_list()
1985 head = &tt_global_entry->orig_list; in batadv_tt_global_del_orig_list()
1988 spin_unlock_bh(&tt_global_entry->list_lock); in batadv_tt_global_del_orig_list()
1992 * batadv_tt_global_del_orig_node() - remove orig_node from a global tt entry
1993 * @bat_priv: the bat priv with all the soft interface information
2012 spin_lock_bh(&tt_global_entry->list_lock); in batadv_tt_global_del_orig_node()
2013 head = &tt_global_entry->orig_list; in batadv_tt_global_del_orig_node()
2015 if (orig_entry->orig_node == orig_node) { in batadv_tt_global_del_orig_node()
2016 vid = tt_global_entry->common.vid; in batadv_tt_global_del_orig_node()
2019 orig_node->orig, in batadv_tt_global_del_orig_node()
2020 tt_global_entry->common.addr, in batadv_tt_global_del_orig_node()
2026 spin_unlock_bh(&tt_global_entry->list_lock); in batadv_tt_global_del_orig_node()
2048 head = &tt_global_entry->orig_list; in batadv_tt_global_del_roaming()
2050 if (orig_entry->orig_node != orig_node) { in batadv_tt_global_del_roaming()
2059 tt_global_entry->common.flags |= BATADV_TT_CLIENT_ROAM; in batadv_tt_global_del_roaming()
2060 tt_global_entry->roam_at = jiffies; in batadv_tt_global_del_roaming()
2071 * batadv_tt_global_del() - remove a client from the global table
2072 * @bat_priv: the bat priv with all the soft interface information
2096 if (hlist_empty(&tt_global_entry->orig_list)) in batadv_tt_global_del()
2105 * 1) the client roamed from node A to node B => if there in batadv_tt_global_del()
2108 * wait for node B to claim it. In case of timeout in batadv_tt_global_del()
2117 tt_global_entry->common.addr, in batadv_tt_global_del()
2135 * batadv_tt_global_del_orig() - remove all the TT global entries belonging to
2137 * @bat_priv: the bat priv with all the soft interface information
2151 struct batadv_hashtable *hash = bat_priv->tt.global_hash; in batadv_tt_global_del_orig()
2160 for (i = 0; i < hash->size; i++) { in batadv_tt_global_del_orig()
2161 head = &hash->table[i]; in batadv_tt_global_del_orig()
2162 list_lock = &hash->list_locks[i]; in batadv_tt_global_del_orig()
2168 if (match_vid >= 0 && tt_common_entry->vid != match_vid) in batadv_tt_global_del_orig()
2178 if (hlist_empty(&tt_global->orig_list)) { in batadv_tt_global_del_orig()
2179 vid = tt_global->common.vid; in batadv_tt_global_del_orig()
2182 tt_global->common.addr, in batadv_tt_global_del_orig()
2184 hlist_del_rcu(&tt_common_entry->hash_entry); in batadv_tt_global_del_orig()
2190 clear_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized); in batadv_tt_global_del_orig()
2200 if ((tt_global->common.flags & BATADV_TT_CLIENT_ROAM) && in batadv_tt_global_to_purge()
2201 batadv_has_timed_out(tt_global->roam_at, roam_timeout)) { in batadv_tt_global_to_purge()
2206 if ((tt_global->common.flags & BATADV_TT_CLIENT_TEMP) && in batadv_tt_global_to_purge()
2207 batadv_has_timed_out(tt_global->common.added_at, temp_timeout)) { in batadv_tt_global_to_purge()
2217 struct batadv_hashtable *hash = bat_priv->tt.global_hash; in batadv_tt_global_purge()
2226 for (i = 0; i < hash->size; i++) { in batadv_tt_global_purge()
2227 head = &hash->table[i]; in batadv_tt_global_purge()
2228 list_lock = &hash->list_locks[i]; in batadv_tt_global_purge()
2242 tt_global->common.addr, in batadv_tt_global_purge()
2243 batadv_print_vid(tt_global->common.vid), in batadv_tt_global_purge()
2246 hlist_del_rcu(&tt_common->hash_entry); in batadv_tt_global_purge()
2264 if (!bat_priv->tt.global_hash) in batadv_tt_global_table_free()
2267 hash = bat_priv->tt.global_hash; in batadv_tt_global_table_free()
2269 for (i = 0; i < hash->size; i++) { in batadv_tt_global_table_free()
2270 head = &hash->table[i]; in batadv_tt_global_table_free()
2271 list_lock = &hash->list_locks[i]; in batadv_tt_global_table_free()
2276 hlist_del_rcu(&tt_common_entry->hash_entry); in batadv_tt_global_table_free()
2287 bat_priv->tt.global_hash = NULL; in batadv_tt_global_table_free()
2294 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_WIFI && in _batadv_is_ap_isolated()
2295 tt_global_entry->common.flags & BATADV_TT_CLIENT_WIFI) in _batadv_is_ap_isolated()
2299 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_ISOLA && in _batadv_is_ap_isolated()
2300 tt_global_entry->common.flags & BATADV_TT_CLIENT_ISOLA) in _batadv_is_ap_isolated()
2307 * batadv_transtable_search() - get the mesh destination for a given client
2308 * @bat_priv: the bat priv with all the soft interface information
2316 * the best one (best in terms of metric towards the destination node).
2333 (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)) in batadv_transtable_search()
2352 orig_node = best_entry->orig_node; in batadv_transtable_search()
2353 if (orig_node && !kref_get_unless_zero(&orig_node->refcount)) in batadv_transtable_search()
2365 * batadv_tt_global_crc() - calculates the checksum of the local table belonging
2367 * @bat_priv: the bat priv with all the soft interface information
2379 * the CRC32C function affects the result and since every node in the network
2392 struct batadv_hashtable *hash = bat_priv->tt.global_hash; in batadv_tt_global_crc()
2401 for (i = 0; i < hash->size; i++) { in batadv_tt_global_crc()
2402 head = &hash->table[i]; in batadv_tt_global_crc()
2412 if (tt_common->vid != vid) in batadv_tt_global_crc()
2420 if (tt_common->flags & BATADV_TT_CLIENT_ROAM) in batadv_tt_global_crc()
2426 if (tt_common->flags & BATADV_TT_CLIENT_TEMP) in batadv_tt_global_crc()
2438 * every node reads the bytes in the same order. in batadv_tt_global_crc()
2440 tmp_vid = htons(tt_common->vid); in batadv_tt_global_crc()
2446 flags = tt_orig->flags; in batadv_tt_global_crc()
2449 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN); in batadv_tt_global_crc()
2460 * batadv_tt_local_crc() - calculates the checksum of the local table
2461 * @bat_priv: the bat priv with all the soft interface information
2472 struct batadv_hashtable *hash = bat_priv->tt.local_hash; in batadv_tt_local_crc()
2479 for (i = 0; i < hash->size; i++) { in batadv_tt_local_crc()
2480 head = &hash->table[i]; in batadv_tt_local_crc()
2487 if (tt_common->vid != vid) in batadv_tt_local_crc()
2493 if (tt_common->flags & BATADV_TT_CLIENT_NEW) in batadv_tt_local_crc()
2497 * every node reads the bytes in the same order. in batadv_tt_local_crc()
2499 tmp_vid = htons(tt_common->vid); in batadv_tt_local_crc()
2505 flags = tt_common->flags & BATADV_TT_SYNC_MASK; in batadv_tt_local_crc()
2508 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN); in batadv_tt_local_crc()
2517 * batadv_tt_req_node_release() - free tt_req node entry
2530 * batadv_tt_req_node_put() - decrement the tt_req_node refcounter and
2539 kref_put(&tt_req_node->refcount, batadv_tt_req_node_release); in batadv_tt_req_node_put()
2544 struct batadv_tt_req_node *node; in batadv_tt_req_list_free() local
2547 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_list_free()
2549 hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { in batadv_tt_req_list_free()
2550 hlist_del_init(&node->list); in batadv_tt_req_list_free()
2551 batadv_tt_req_node_put(node); in batadv_tt_req_list_free()
2554 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_list_free()
2565 spin_lock_bh(&orig_node->tt_buff_lock); in batadv_tt_save_orig_buffer()
2567 kfree(orig_node->tt_buff); in batadv_tt_save_orig_buffer()
2568 orig_node->tt_buff_len = 0; in batadv_tt_save_orig_buffer()
2569 orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC); in batadv_tt_save_orig_buffer()
2570 if (orig_node->tt_buff) { in batadv_tt_save_orig_buffer()
2571 memcpy(orig_node->tt_buff, tt_buff, tt_buff_len); in batadv_tt_save_orig_buffer()
2572 orig_node->tt_buff_len = tt_buff_len; in batadv_tt_save_orig_buffer()
2575 spin_unlock_bh(&orig_node->tt_buff_lock); in batadv_tt_save_orig_buffer()
2580 struct batadv_tt_req_node *node; in batadv_tt_req_purge() local
2583 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_purge()
2584 hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { in batadv_tt_req_purge()
2585 if (batadv_has_timed_out(node->issued_at, in batadv_tt_req_purge()
2587 hlist_del_init(&node->list); in batadv_tt_req_purge()
2588 batadv_tt_req_node_put(node); in batadv_tt_req_purge()
2591 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_purge()
2595 * batadv_tt_req_node_new() - search and possibly create a tt_req_node object
2596 * @bat_priv: the bat priv with all the soft interface information
2597 * @orig_node: orig node this request is being issued for
2608 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_node_new()
2609 hlist_for_each_entry(tt_req_node_tmp, &bat_priv->tt.req_list, list) { in batadv_tt_req_node_new()
2611 !batadv_has_timed_out(tt_req_node_tmp->issued_at, in batadv_tt_req_node_new()
2620 kref_init(&tt_req_node->refcount); in batadv_tt_req_node_new()
2621 ether_addr_copy(tt_req_node->addr, orig_node->orig); in batadv_tt_req_node_new()
2622 tt_req_node->issued_at = jiffies; in batadv_tt_req_node_new()
2624 kref_get(&tt_req_node->refcount); in batadv_tt_req_node_new()
2625 hlist_add_head(&tt_req_node->list, &bat_priv->tt.req_list); in batadv_tt_req_node_new()
2627 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_tt_req_node_new()
2632 * batadv_tt_local_valid() - verify local tt entry and get flags
2648 if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW) in batadv_tt_local_valid()
2652 *flags = tt_common_entry->flags; in batadv_tt_local_valid()
2658 * batadv_tt_global_valid() - verify global tt entry and get flags
2677 if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM || in batadv_tt_global_valid()
2678 tt_common_entry->flags & BATADV_TT_CLIENT_TEMP) in batadv_tt_global_valid()
2690 * batadv_tt_tvlv_generate() - fill the tvlv buff with the tt entries from the
2692 * @bat_priv: the bat priv with all the soft interface information
2700 * is not provided then this becomes a no-op.
2727 for (i = 0; i < hash->size; i++) { in batadv_tt_tvlv_generate()
2728 head = &hash->table[i]; in batadv_tt_tvlv_generate()
2739 ether_addr_copy(tt_change->addr, tt_common_entry->addr); in batadv_tt_tvlv_generate()
2740 tt_change->flags = flags; in batadv_tt_tvlv_generate()
2741 tt_change->vid = htons(tt_common_entry->vid); in batadv_tt_tvlv_generate()
2742 memset(tt_change->reserved, 0, in batadv_tt_tvlv_generate()
2743 sizeof(tt_change->reserved)); in batadv_tt_tvlv_generate()
2751 return batadv_tt_len(tt_tot - tt_num_entries); in batadv_tt_tvlv_generate()
2755 * batadv_tt_global_check_crc() - check if all the CRCs are correct
2776 /* if orig_node is a backbone node for this VLAN, don't check in batadv_tt_global_check_crc()
2779 if (batadv_bla_is_backbone_gw_orig(orig_node->bat_priv, in batadv_tt_global_check_crc()
2780 orig_node->orig, in batadv_tt_global_check_crc()
2781 ntohs(tt_vlan_tmp->vid))) in batadv_tt_global_check_crc()
2785 ntohs(tt_vlan_tmp->vid)); in batadv_tt_global_check_crc()
2789 crc = vlan->tt.crc; in batadv_tt_global_check_crc()
2792 if (crc != ntohl(tt_vlan_tmp->crc)) in batadv_tt_global_check_crc()
2801 hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) in batadv_tt_global_check_crc()
2812 * batadv_tt_local_update_crc() - update all the local CRCs
2813 * @bat_priv: the bat priv with all the soft interface information
2821 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { in batadv_tt_local_update_crc()
2822 vlan->tt.crc = batadv_tt_local_crc(bat_priv, vlan->vid); in batadv_tt_local_update_crc()
2828 * batadv_tt_global_update_crc() - update all the global CRCs for this orig_node
2829 * @bat_priv: the bat priv with all the soft interface information
2840 hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) { in batadv_tt_global_update_crc()
2841 /* if orig_node is a backbone node for this VLAN, don't compute in batadv_tt_global_update_crc()
2844 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, in batadv_tt_global_update_crc()
2845 vlan->vid)) in batadv_tt_global_update_crc()
2848 crc = batadv_tt_global_crc(bat_priv, orig_node, vlan->vid); in batadv_tt_global_update_crc()
2849 vlan->tt.crc = crc; in batadv_tt_global_update_crc()
2855 * batadv_send_tt_request() - send a TT Request message to a given node
2856 * @bat_priv: the bat priv with all the soft interface information
2894 tvlv_tt_data->flags = BATADV_TT_REQUEST; in batadv_send_tt_request()
2895 tvlv_tt_data->ttvn = ttvn; in batadv_send_tt_request()
2896 tvlv_tt_data->num_vlan = htons(num_vlan); in batadv_send_tt_request()
2902 tvlv_tt_data->vlan_data[i].vid = tt_vlan->vid; in batadv_send_tt_request()
2903 tvlv_tt_data->vlan_data[i].crc = tt_vlan->crc; in batadv_send_tt_request()
2909 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE; in batadv_send_tt_request()
2912 dst_orig_node->orig, full_table ? 'F' : '.'); in batadv_send_tt_request()
2915 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr, in batadv_send_tt_request()
2916 dst_orig_node->orig, BATADV_TVLV_TT, 1, in batadv_send_tt_request()
2924 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_send_tt_request()
2925 if (!hlist_unhashed(&tt_req_node->list)) { in batadv_send_tt_request()
2926 hlist_del_init(&tt_req_node->list); in batadv_send_tt_request()
2929 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_send_tt_request()
2939 * batadv_send_other_tt_response() - send reply to tt request concerning another
2940 * node's translation table
2941 * @bat_priv: the bat priv with all the soft interface information
2963 req_src, tt_data->ttvn, req_dst, in batadv_send_other_tt_response()
2964 ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.')); in batadv_send_other_tt_response()
2966 /* Let's get the orig node of the REAL destination */ in batadv_send_other_tt_response()
2975 orig_ttvn = (u8)atomic_read(&req_dst_orig_node->last_ttvn); in batadv_send_other_tt_response()
2976 req_ttvn = tt_data->ttvn; in batadv_send_other_tt_response()
2978 /* this node doesn't have the requested data */ in batadv_send_other_tt_response()
2980 !batadv_tt_global_check_crc(req_dst_orig_node, tt_data->vlan_data, in batadv_send_other_tt_response()
2981 ntohs(tt_data->num_vlan))) in batadv_send_other_tt_response()
2985 if (tt_data->flags & BATADV_TT_FULL_TABLE || in batadv_send_other_tt_response()
2986 !req_dst_orig_node->tt_buff) in batadv_send_other_tt_response()
2995 spin_lock_bh(&req_dst_orig_node->tt_buff_lock); in batadv_send_other_tt_response()
2996 tt_len = req_dst_orig_node->tt_buff_len; in batadv_send_other_tt_response()
3006 memcpy(tt_change, req_dst_orig_node->tt_buff, in batadv_send_other_tt_response()
3007 req_dst_orig_node->tt_buff_len); in batadv_send_other_tt_response()
3008 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); in batadv_send_other_tt_response()
3013 tt_len = -1; in batadv_send_other_tt_response()
3022 tvlv_len -= batadv_tt_tvlv_generate(bat_priv, in batadv_send_other_tt_response()
3023 bat_priv->tt.global_hash, in batadv_send_other_tt_response()
3031 if (tt_len > atomic_read(&bat_priv->packet_size_max)) { in batadv_send_other_tt_response()
3032 net_ratelimited_function(batadv_info, bat_priv->soft_iface, in batadv_send_other_tt_response()
3034 res_dst_orig_node->orig); in batadv_send_other_tt_response()
3038 tvlv_tt_data->flags = BATADV_TT_RESPONSE; in batadv_send_other_tt_response()
3039 tvlv_tt_data->ttvn = req_ttvn; in batadv_send_other_tt_response()
3042 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE; in batadv_send_other_tt_response()
3046 res_dst_orig_node->orig, req_dst_orig_node->orig, in batadv_send_other_tt_response()
3051 batadv_tvlv_unicast_send(bat_priv, req_dst_orig_node->orig, in batadv_send_other_tt_response()
3059 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock); in batadv_send_other_tt_response()
3069 * batadv_send_my_tt_response() - send reply to tt request concerning this
3070 * node's translation table
3071 * @bat_priv: the bat priv with all the soft interface information
3092 req_src, tt_data->ttvn, in batadv_send_my_tt_response()
3093 ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.')); in batadv_send_my_tt_response()
3095 spin_lock_bh(&bat_priv->tt.commit_lock); in batadv_send_my_tt_response()
3097 my_ttvn = (u8)atomic_read(&bat_priv->tt.vn); in batadv_send_my_tt_response()
3098 req_ttvn = tt_data->ttvn; in batadv_send_my_tt_response()
3111 if (tt_data->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn || in batadv_send_my_tt_response()
3112 !bat_priv->tt.last_changeset) in batadv_send_my_tt_response()
3121 spin_lock_bh(&bat_priv->tt.last_changeset_lock); in batadv_send_my_tt_response()
3123 tt_len = bat_priv->tt.last_changeset_len; in batadv_send_my_tt_response()
3132 memcpy(tt_change, bat_priv->tt.last_changeset, in batadv_send_my_tt_response()
3133 bat_priv->tt.last_changeset_len); in batadv_send_my_tt_response()
3134 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); in batadv_send_my_tt_response()
3136 req_ttvn = (u8)atomic_read(&bat_priv->tt.vn); in batadv_send_my_tt_response()
3141 tt_len = -1; in batadv_send_my_tt_response()
3150 tvlv_len -= batadv_tt_tvlv_generate(bat_priv, in batadv_send_my_tt_response()
3151 bat_priv->tt.local_hash, in batadv_send_my_tt_response()
3157 tvlv_tt_data->flags = BATADV_TT_RESPONSE; in batadv_send_my_tt_response()
3158 tvlv_tt_data->ttvn = req_ttvn; in batadv_send_my_tt_response()
3161 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE; in batadv_send_my_tt_response()
3165 orig_node->orig, full_table ? 'F' : '.', req_ttvn); in batadv_send_my_tt_response()
3169 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr, in batadv_send_my_tt_response()
3176 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); in batadv_send_my_tt_response()
3178 spin_unlock_bh(&bat_priv->tt.commit_lock); in batadv_send_my_tt_response()
3182 /* The packet was for this host, so it doesn't need to be re-routed */ in batadv_send_my_tt_response()
3187 * batadv_send_tt_response() - send reply to tt request
3188 * @bat_priv: the bat priv with all the soft interface information
3214 if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) { in _batadv_tt_update_changes()
3215 roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM; in _batadv_tt_update_changes()
3217 (tt_change + i)->addr, in _batadv_tt_update_changes()
3218 ntohs((tt_change + i)->vid), in _batadv_tt_update_changes()
3223 (tt_change + i)->addr, in _batadv_tt_update_changes()
3224 ntohs((tt_change + i)->vid), in _batadv_tt_update_changes()
3225 (tt_change + i)->flags, ttvn)) in _batadv_tt_update_changes()
3235 set_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized); in _batadv_tt_update_changes()
3250 batadv_tt_global_del_orig(bat_priv, orig_node, -1, in batadv_tt_fill_gtable()
3256 spin_lock_bh(&orig_node->tt_buff_lock); in batadv_tt_fill_gtable()
3257 kfree(orig_node->tt_buff); in batadv_tt_fill_gtable()
3258 orig_node->tt_buff_len = 0; in batadv_tt_fill_gtable()
3259 orig_node->tt_buff = NULL; in batadv_tt_fill_gtable()
3260 spin_unlock_bh(&orig_node->tt_buff_lock); in batadv_tt_fill_gtable()
3262 atomic_set(&orig_node->last_ttvn, ttvn); in batadv_tt_fill_gtable()
3278 atomic_set(&orig_node->last_ttvn, ttvn); in batadv_tt_update_changes()
3282 * batadv_is_my_client() - check if a client is served by the local node
3283 * @bat_priv: the bat priv with all the soft interface information
3287 * Return: true if the client is served by this node, false otherwise.
3301 if ((tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) || in batadv_is_my_client()
3302 (tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM)) in batadv_is_my_client()
3311 * batadv_handle_tt_response() - process incoming tt reply
3312 * @bat_priv: the bat priv with all the soft interface information
3321 struct batadv_tt_req_node *node; in batadv_handle_tt_response() local
3329 resp_src, tt_data->ttvn, num_entries, in batadv_handle_tt_response()
3330 ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.')); in batadv_handle_tt_response()
3336 spin_lock_bh(&orig_node->tt_lock); in batadv_handle_tt_response()
3338 tvlv_ptr += struct_size(tt_data, vlan_data, ntohs(tt_data->num_vlan)); in batadv_handle_tt_response()
3341 if (tt_data->flags & BATADV_TT_FULL_TABLE) { in batadv_handle_tt_response()
3342 batadv_tt_fill_gtable(bat_priv, tt_change, tt_data->ttvn, in batadv_handle_tt_response()
3346 tt_data->ttvn, tt_change); in batadv_handle_tt_response()
3352 spin_unlock_bh(&orig_node->tt_lock); in batadv_handle_tt_response()
3355 spin_lock_bh(&bat_priv->tt.req_list_lock); in batadv_handle_tt_response()
3356 hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { in batadv_handle_tt_response()
3357 if (!batadv_compare_eth(node->addr, resp_src)) in batadv_handle_tt_response()
3359 hlist_del_init(&node->list); in batadv_handle_tt_response()
3360 batadv_tt_req_node_put(node); in batadv_handle_tt_response()
3363 spin_unlock_bh(&bat_priv->tt.req_list_lock); in batadv_handle_tt_response()
3370 struct batadv_tt_roam_node *node, *safe; in batadv_tt_roam_list_free() local
3372 spin_lock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_roam_list_free()
3374 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { in batadv_tt_roam_list_free()
3375 list_del(&node->list); in batadv_tt_roam_list_free()
3376 kmem_cache_free(batadv_tt_roam_cache, node); in batadv_tt_roam_list_free()
3379 spin_unlock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_roam_list_free()
3384 struct batadv_tt_roam_node *node, *safe; in batadv_tt_roam_purge() local
3386 spin_lock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_roam_purge()
3387 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { in batadv_tt_roam_purge()
3388 if (!batadv_has_timed_out(node->first_time, in batadv_tt_roam_purge()
3392 list_del(&node->list); in batadv_tt_roam_purge()
3393 kmem_cache_free(batadv_tt_roam_cache, node); in batadv_tt_roam_purge()
3395 spin_unlock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_roam_purge()
3399 * batadv_tt_check_roam_count() - check if a client has roamed too frequently
3400 * @bat_priv: the bat priv with all the soft interface information
3414 spin_lock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_check_roam_count()
3418 list_for_each_entry(tt_roam_node, &bat_priv->tt.roam_list, list) { in batadv_tt_check_roam_count()
3419 if (!batadv_compare_eth(tt_roam_node->addr, client)) in batadv_tt_check_roam_count()
3422 if (batadv_has_timed_out(tt_roam_node->first_time, in batadv_tt_check_roam_count()
3426 if (!batadv_atomic_dec_not_zero(&tt_roam_node->counter)) in batadv_tt_check_roam_count()
3439 tt_roam_node->first_time = jiffies; in batadv_tt_check_roam_count()
3440 atomic_set(&tt_roam_node->counter, in batadv_tt_check_roam_count()
3441 BATADV_ROAMING_MAX_COUNT - 1); in batadv_tt_check_roam_count()
3442 ether_addr_copy(tt_roam_node->addr, client); in batadv_tt_check_roam_count()
3444 list_add(&tt_roam_node->list, &bat_priv->tt.roam_list); in batadv_tt_check_roam_count()
3449 spin_unlock_bh(&bat_priv->tt.roam_list_lock); in batadv_tt_check_roam_count()
3454 * batadv_send_roam_adv() - send a roaming advertisement message
3455 * @bat_priv: the bat priv with all the soft interface information
3460 * Send a ROAMING_ADV message to the node which was previously serving this
3461 * client. This is done to inform the node that from now on all traffic destined
3484 orig_node->orig, client, batadv_print_vid(vid)); in batadv_send_roam_adv()
3491 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr, in batadv_send_roam_adv()
3492 orig_node->orig, BATADV_TVLV_ROAM, 1, in batadv_send_roam_adv()
3514 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work, in batadv_tt_purge()
3519 * batadv_tt_free() - Free translation table of soft interface
3520 * @bat_priv: the bat priv with all the soft interface information
3529 cancel_delayed_work_sync(&bat_priv->tt.work); in batadv_tt_free()
3537 kfree(bat_priv->tt.last_changeset); in batadv_tt_free()
3541 * batadv_tt_local_set_flags() - set or unset the specified flags on the local
3543 * @bat_priv: the bat priv with all the soft interface information
3551 struct batadv_hashtable *hash = bat_priv->tt.local_hash; in batadv_tt_local_set_flags()
3559 for (i = 0; i < hash->size; i++) { in batadv_tt_local_set_flags()
3560 head = &hash->table[i]; in batadv_tt_local_set_flags()
3566 if ((tt_common_entry->flags & flags) == flags) in batadv_tt_local_set_flags()
3568 tt_common_entry->flags |= flags; in batadv_tt_local_set_flags()
3570 if (!(tt_common_entry->flags & flags)) in batadv_tt_local_set_flags()
3572 tt_common_entry->flags &= ~flags; in batadv_tt_local_set_flags()
3579 tt_common_entry->vid); in batadv_tt_local_set_flags()
3588 struct batadv_hashtable *hash = bat_priv->tt.local_hash; in batadv_tt_local_purge_pending_clients()
3599 for (i = 0; i < hash->size; i++) { in batadv_tt_local_purge_pending_clients()
3600 head = &hash->table[i]; in batadv_tt_local_purge_pending_clients()
3601 list_lock = &hash->list_locks[i]; in batadv_tt_local_purge_pending_clients()
3606 if (!(tt_common->flags & BATADV_TT_CLIENT_PENDING)) in batadv_tt_local_purge_pending_clients()
3611 tt_common->addr, in batadv_tt_local_purge_pending_clients()
3612 batadv_print_vid(tt_common->vid)); in batadv_tt_local_purge_pending_clients()
3614 batadv_tt_local_size_dec(bat_priv, tt_common->vid); in batadv_tt_local_purge_pending_clients()
3615 hlist_del_rcu(&tt_common->hash_entry); in batadv_tt_local_purge_pending_clients()
3627 * batadv_tt_local_commit_changes_nolock() - commit all pending local tt changes
3629 * @bat_priv: the bat priv with all the soft interface information
3631 * Caller must hold tt->commit_lock.
3635 lockdep_assert_held(&bat_priv->tt.commit_lock); in batadv_tt_local_commit_changes_nolock()
3637 if (READ_ONCE(bat_priv->tt.local_changes) == 0) { in batadv_tt_local_commit_changes_nolock()
3638 if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt)) in batadv_tt_local_commit_changes_nolock()
3649 atomic_inc(&bat_priv->tt.vn); in batadv_tt_local_commit_changes_nolock()
3652 (u8)atomic_read(&bat_priv->tt.vn)); in batadv_tt_local_commit_changes_nolock()
3655 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); in batadv_tt_local_commit_changes_nolock()
3660 * batadv_tt_local_commit_changes() - commit all pending local tt changes which
3662 * @bat_priv: the bat priv with all the soft interface information
3666 spin_lock_bh(&bat_priv->tt.commit_lock); in batadv_tt_local_commit_changes()
3668 spin_unlock_bh(&bat_priv->tt.commit_lock); in batadv_tt_local_commit_changes()
3672 * batadv_is_ap_isolated() - Check if packet from upper layer should be dropped
3673 * @bat_priv: the bat priv with all the soft interface information
3692 if (!atomic_read(&vlan->ap_isolation)) in batadv_is_ap_isolated()
3715 * batadv_tt_update_orig() - update global translation table with new tt
3717 * @bat_priv: the bat priv with all the soft interface information
3731 u8 orig_ttvn = (u8)atomic_read(&orig_node->last_ttvn); in batadv_tt_update_orig()
3738 &orig_node->capa_initialized); in batadv_tt_update_orig()
3741 * increased by one -> we can apply the attached changes in batadv_tt_update_orig()
3743 if ((!has_tt_init && ttvn == 1) || ttvn - orig_ttvn == 1) { in batadv_tt_update_orig()
3754 spin_lock_bh(&orig_node->tt_lock); in batadv_tt_update_orig()
3765 spin_unlock_bh(&orig_node->tt_lock); in batadv_tt_update_orig()
3769 * (due to the wrap around). Thus a node has to check whether in batadv_tt_update_orig()
3771 * consistent or not. E.g. a node could disconnect while its in batadv_tt_update_orig()
3781 * in sync anymore -> request fresh tt data in batadv_tt_update_orig()
3789 orig_node->orig, ttvn, orig_ttvn, in batadv_tt_update_orig()
3800 * batadv_tt_global_client_is_roaming() - check if a client is marked as roaming
3801 * @bat_priv: the bat priv with all the soft interface information
3819 ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM; in batadv_tt_global_client_is_roaming()
3826 * batadv_tt_local_client_is_roaming() - tells whether the client is roaming
3827 * @bat_priv: the bat priv with all the soft interface information
3832 * this node anymore) or not. If yes, the client is still present in the table
3833 * to keep the latter consistent with the node TTVN
3845 ret = tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM; in batadv_tt_local_client_is_roaming()
3852 * batadv_tt_add_temporary_global_entry() - Add temporary entry to global TT
3853 * @bat_priv: the bat priv with all the soft interface information
3854 * @orig_node: orig node which the temporary entry should be associated with
3873 atomic_read(&orig_node->last_ttvn))) in batadv_tt_add_temporary_global_entry()
3878 addr, batadv_print_vid(vid), orig_node->orig); in batadv_tt_add_temporary_global_entry()
3884 * batadv_tt_local_resize_to_mtu() - resize the local translation table fit the
3886 * @soft_iface: netdev struct of the mesh interface
3894 int packet_size_max = atomic_read(&bat_priv->packet_size_max); in batadv_tt_local_resize_to_mtu()
3898 spin_lock_bh(&bat_priv->tt.commit_lock); in batadv_tt_local_resize_to_mtu()
3921 spin_unlock_bh(&bat_priv->tt.commit_lock); in batadv_tt_local_resize_to_mtu()
3925 * batadv_tt_tvlv_ogm_handler_v1() - process incoming tt tvlv container
3926 * @bat_priv: the bat priv with all the soft interface information
3946 num_vlan = ntohs(tt_data->num_vlan); in batadv_tt_tvlv_ogm_handler_v1()
3954 tvlv_value_len -= tt_data_sz; in batadv_tt_tvlv_ogm_handler_v1()
3958 batadv_tt_update_orig(bat_priv, orig, tt_data->vlan_data, num_vlan, in batadv_tt_tvlv_ogm_handler_v1()
3959 tt_change, num_entries, tt_data->ttvn); in batadv_tt_tvlv_ogm_handler_v1()
3963 * batadv_tt_tvlv_unicast_handler_v1() - process incoming (unicast) tt tvlv
3965 * @bat_priv: the bat priv with all the soft interface information
3971 * Return: NET_RX_DROP if the tt tvlv is to be re-routed, NET_RX_SUCCESS
3988 tvlv_value_len -= sizeof(*tt_data); in batadv_tt_tvlv_unicast_handler_v1()
3991 ntohs(tt_data->num_vlan)); in batadv_tt_tvlv_unicast_handler_v1()
3996 tvlv_value_len -= tt_vlan_len; in batadv_tt_tvlv_unicast_handler_v1()
3999 switch (tt_data->flags & BATADV_TT_DATA_TYPE_MASK) { in batadv_tt_tvlv_unicast_handler_v1()
4003 /* If this node cannot provide a TT response the tt_request is in batadv_tt_tvlv_unicast_handler_v1()
4008 if (tt_data->flags & BATADV_TT_FULL_TABLE) in batadv_tt_tvlv_unicast_handler_v1()
4016 /* tvlv API will re-route the packet */ in batadv_tt_tvlv_unicast_handler_v1()
4029 if (tt_data->flags & BATADV_TT_FULL_TABLE) in batadv_tt_tvlv_unicast_handler_v1()
4037 /* tvlv API will re-route the packet */ in batadv_tt_tvlv_unicast_handler_v1()
4045 * batadv_roam_tvlv_unicast_handler_v1() - process incoming tt roam tvlv
4047 * @bat_priv: the bat priv with all the soft interface information
4053 * Return: NET_RX_DROP if the tt roam tvlv is to be re-routed, NET_RX_SUCCESS
4064 /* If this node is not the intended recipient of the in batadv_roam_tvlv_unicast_handler_v1()
4066 * (the tvlv API will re-route the packet). in batadv_roam_tvlv_unicast_handler_v1()
4083 src, roaming_adv->client); in batadv_roam_tvlv_unicast_handler_v1()
4085 batadv_tt_global_add(bat_priv, orig_node, roaming_adv->client, in batadv_roam_tvlv_unicast_handler_v1()
4086 ntohs(roaming_adv->vid), BATADV_TT_CLIENT_ROAM, in batadv_roam_tvlv_unicast_handler_v1()
4087 atomic_read(&orig_node->last_ttvn) + 1); in batadv_roam_tvlv_unicast_handler_v1()
4095 * batadv_tt_init() - initialise the translation table internals
4096 * @bat_priv: the bat priv with all the soft interface information
4125 INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge); in batadv_tt_init()
4126 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work, in batadv_tt_init()
4133 * batadv_tt_global_is_isolated() - check if a client is marked as isolated
4134 * @bat_priv: the bat priv with all the soft interface information
4151 ret = tt->common.flags & BATADV_TT_CLIENT_ISOLA; in batadv_tt_global_is_isolated()
4159 * batadv_tt_cache_init() - Initialize tt memory object cache
4175 return -ENOMEM; in batadv_tt_cache_init()
4224 return -ENOMEM; in batadv_tt_cache_init()
4228 * batadv_tt_cache_destroy() - Destroy tt memory object cache