37 static void batadv_tt_global_del(
struct batadv_priv *bat_priv,
39 const unsigned char *
addr,
40 const char *
message,
bool roaming);
51 static void batadv_tt_start_timer(
struct batadv_priv *bat_priv)
70 index = batadv_choose_orig(data, hash->
size);
74 hlist_for_each_entry_rcu(tt_common_entry, node, head,
hash_entry) {
75 if (!batadv_compare_eth(tt_common_entry, data))
81 tt_common_entry_tmp = tt_common_entry;
86 return tt_common_entry_tmp;
90 batadv_tt_local_hash_find(
struct batadv_priv *bat_priv,
const void *data)
95 tt_common_entry = batadv_tt_hash_find(bat_priv->
tt.local_hash, data);
100 return tt_local_entry;
104 batadv_tt_global_hash_find(
struct batadv_priv *bat_priv,
const void *data)
109 tt_common_entry = batadv_tt_hash_find(bat_priv->
tt.global_hash, data);
114 return tt_global_entry;
125 static void batadv_tt_global_entry_free_rcu(
struct rcu_head *rcu)
134 kfree(tt_global_entry);
141 batadv_tt_global_del_orig_list(tt_global_entry);
143 batadv_tt_global_entry_free_rcu);
147 static void batadv_tt_orig_list_entry_free_rcu(
struct rcu_head *rcu)
163 call_rcu(&orig_entry->
rcu, batadv_tt_orig_list_entry_free_rcu);
166 static void batadv_tt_local_event(
struct batadv_priv *bat_priv,
170 bool event_removed =
false;
171 bool del_op_requested, del_op_entry;
184 spin_lock_bh(&bat_priv->
tt.changes_list_lock);
187 if (!batadv_compare_eth(entry->
change.addr, addr))
198 if (!del_op_requested && del_op_entry)
200 if (del_op_requested && !del_op_entry)
206 kfree(tt_change_node);
207 event_removed =
true;
215 spin_unlock_bh(&bat_priv->
tt.changes_list_lock);
228 static int batadv_tt_local_init(
struct batadv_priv *bat_priv)
230 if (bat_priv->
tt.local_hash)
235 if (!bat_priv->
tt.local_hash)
244 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
252 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
254 if (tt_local_entry) {
266 "Creating new local tt entry: %pM (ttvn: %d)\n", addr,
278 if (batadv_compare_eth(addr, soft_iface->
dev_addr))
287 hash_added = batadv_hash_add(bat_priv->
tt.local_hash, batadv_compare_tt,
290 &tt_local_entry->
common.hash_entry);
294 batadv_tt_local_entry_free_ref(tt_local_entry);
298 batadv_tt_local_event(bat_priv, addr, tt_local_entry->
common.flags);
301 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
304 if (tt_global_entry) {
308 hlist_for_each_entry_rcu(orig_entry, node, head,
list) {
309 orig_entry->
orig_node->tt_poss_change =
true;
311 batadv_send_roam_adv(bat_priv,
312 tt_global_entry->
common.addr,
324 batadv_tt_local_entry_free_ref(tt_local_entry);
326 batadv_tt_global_entry_free_ref(tt_global_entry);
329 static void batadv_tt_realloc_packet_buff(
unsigned char **packet_buff,
330 int *packet_buff_len,
334 unsigned char *new_buff;
340 memcpy(new_buff, *packet_buff, min_packet_len);
342 *packet_buff = new_buff;
343 *packet_buff_len = new_packet_len;
347 static void batadv_tt_prepare_packet_buff(
struct batadv_priv *bat_priv,
348 unsigned char **packet_buff,
349 int *packet_buff_len,
355 primary_if = batadv_primary_if_get_selected(bat_priv);
357 req_len = min_packet_len;
363 if ((!primary_if) || (req_len > primary_if->
soft_iface->mtu))
364 req_len = min_packet_len;
366 batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len,
367 min_packet_len, req_len);
370 batadv_hardif_free_ref(primary_if);
373 static int batadv_tt_changes_fill_buff(
struct batadv_priv *bat_priv,
374 unsigned char **packet_buff,
375 int *packet_buff_len,
379 int count = 0, tot_changes = 0, new_len;
380 unsigned char *tt_buff;
382 batadv_tt_prepare_packet_buff(bat_priv, packet_buff,
383 packet_buff_len, min_packet_len);
385 new_len = *packet_buff_len - min_packet_len;
386 tt_buff = *packet_buff + min_packet_len;
391 spin_lock_bh(&bat_priv->
tt.changes_list_lock);
396 if (count < tot_changes) {
404 spin_unlock_bh(&bat_priv->
tt.changes_list_lock);
407 spin_lock_bh(&bat_priv->
tt.last_changeset_lock);
408 kfree(bat_priv->
tt.last_changeset);
409 bat_priv->
tt.last_changeset_len = 0;
410 bat_priv->
tt.last_changeset =
NULL;
417 if (bat_priv->
tt.last_changeset) {
418 memcpy(bat_priv->
tt.last_changeset, tt_buff, new_len);
419 bat_priv->
tt.last_changeset_len = new_len;
422 spin_unlock_bh(&bat_priv->
tt.last_changeset_lock);
430 struct batadv_priv *bat_priv = netdev_priv(net_dev);
439 primary_if = batadv_primary_if_get_selected(bat_priv);
442 "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
449 "BATMAN mesh %s disabled - primary interface not active\n",
455 "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n",
458 for (i = 0; i < hash->
size; i++) {
462 hlist_for_each_entry_rcu(tt_common_entry, node,
465 tt_common_entry->
addr,
466 (tt_common_entry->
flags &
468 (tt_common_entry->
flags &
470 (tt_common_entry->
flags &
472 (tt_common_entry->
flags &
474 (tt_common_entry->
flags &
481 batadv_hardif_free_ref(primary_if);
486 batadv_tt_local_set_pending(
struct batadv_priv *bat_priv,
490 batadv_tt_local_event(bat_priv, tt_local_entry->
common.addr,
491 tt_local_entry->
common.flags | flags);
500 "Local tt entry (%pM) pending to be removed: %s\n",
501 tt_local_entry->
common.addr, message);
505 const char *
message,
bool roaming)
510 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
518 batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, message);
521 batadv_tt_local_entry_free_ref(tt_local_entry);
524 static void batadv_tt_local_purge_list(
struct batadv_priv *bat_priv,
543 if (!batadv_has_timed_out(tt_local_entry->
last_seen,
547 batadv_tt_local_set_pending(bat_priv, tt_local_entry,
548 BATADV_TT_CLIENT_DEL,
"timed out");
552 static void batadv_tt_local_purge(
struct batadv_priv *bat_priv)
559 for (i = 0; i < hash->
size; i++) {
563 spin_lock_bh(list_lock);
564 batadv_tt_local_purge_list(bat_priv, head);
565 spin_unlock_bh(list_lock);
570 static void batadv_tt_local_table_free(
struct batadv_priv *bat_priv)
580 if (!bat_priv->
tt.local_hash)
583 hash = bat_priv->
tt.local_hash;
585 for (i = 0; i < hash->
size; i++) {
589 spin_lock_bh(list_lock);
596 batadv_tt_local_entry_free_ref(tt_local);
598 spin_unlock_bh(list_lock);
603 bat_priv->
tt.local_hash =
NULL;
606 static int batadv_tt_global_init(
struct batadv_priv *bat_priv)
608 if (bat_priv->
tt.global_hash)
613 if (!bat_priv->
tt.global_hash)
619 static void batadv_tt_changes_list_free(
struct batadv_priv *bat_priv)
623 spin_lock_bh(&bat_priv->
tt.changes_list_lock);
632 spin_unlock_bh(&bat_priv->
tt.changes_list_lock);
650 hlist_for_each_entry_rcu(tmp_orig_entry, node, head,
list) {
651 if (tmp_orig_entry->
orig_node != orig_node)
656 orig_entry = tmp_orig_entry;
674 orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node);
677 batadv_tt_orig_list_entry_free_ref(orig_entry);
689 orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node);
698 orig_entry = kzalloc(
sizeof(*orig_entry),
GFP_ATOMIC);
702 INIT_HLIST_NODE(&orig_entry->
list);
710 hlist_add_head_rcu(&orig_entry->
list,
715 batadv_tt_orig_list_entry_free_ref(orig_entry);
721 const unsigned char *tt_addr,
uint8_t flags,
729 tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr);
731 if (!tt_global_entry) {
732 tt_global_entry = kzalloc(
sizeof(*tt_global_entry),
GFP_ATOMIC);
733 if (!tt_global_entry)
736 common = &tt_global_entry->
common;
747 hash_added = batadv_hash_add(bat_priv->
tt.global_hash,
749 batadv_choose_orig, common,
754 batadv_tt_global_entry_free_ref(tt_global_entry);
770 tt_global_entry->
common.flags &= ~BATADV_TT_CLIENT_TEMP;
786 batadv_tt_global_del_orig_list(tt_global_entry);
792 batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
795 "Creating new global tt entry: %pM (via %pM)\n",
796 tt_global_entry->
common.addr, orig_node->
orig);
801 "global tt received",
806 batadv_tt_global_entry_free_ref(tt_global_entry);
824 tt_common_entry = &tt_global_entry->
common;
828 hlist_for_each_entry_rcu(orig_entry, node, head,
list) {
829 flags = tt_common_entry->
flags;
831 seq_printf(seq,
" * %pM (%3u) via %pM (%3u) [%c%c%c]\n",
832 tt_global_entry->
common.addr, orig_entry->
ttvn,
843 struct batadv_priv *bat_priv = netdev_priv(net_dev);
853 primary_if = batadv_primary_if_get_selected(bat_priv);
856 "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
863 "BATMAN mesh %s disabled - primary interface not active\n",
869 "Globally announced TT entries received via the mesh %s\n",
872 "Client",
"(TTVN)",
"Originator",
"(Curr TTVN)",
"Flags");
874 for (i = 0; i < hash->
size; i++) {
878 hlist_for_each_entry_rcu(tt_common_entry, node,
883 batadv_tt_global_print_entry(tt_global, seq);
889 batadv_hardif_free_ref(primary_if);
901 spin_lock_bh(&tt_global_entry->
list_lock);
905 batadv_tt_orig_list_entry_free_ref(orig_entry);
907 spin_unlock_bh(&tt_global_entry->
list_lock);
912 batadv_tt_global_del_orig_entry(
struct batadv_priv *bat_priv,
921 spin_lock_bh(&tt_global_entry->
list_lock);
924 if (orig_entry->
orig_node == orig_node) {
926 "Deleting %pM from global tt entry %pM: %s\n",
928 tt_global_entry->
common.addr, message);
930 batadv_tt_orig_list_entry_free_ref(orig_entry);
933 spin_unlock_bh(&tt_global_entry->
list_lock);
937 batadv_tt_global_del_struct(
struct batadv_priv *bat_priv,
942 "Deleting global tt entry %pM: %s\n",
943 tt_global_entry->
common.addr, message);
945 batadv_hash_remove(bat_priv->
tt.global_hash, batadv_compare_tt,
946 batadv_choose_orig, tt_global_entry->
common.addr);
947 batadv_tt_global_entry_free_ref(tt_global_entry);
956 batadv_tt_global_del_roaming(
struct batadv_priv *bat_priv,
961 bool last_entry =
true;
972 hlist_for_each_entry_rcu(orig_entry, node, head,
list) {
973 if (orig_entry->
orig_node != orig_node) {
988 batadv_tt_global_del_orig_entry(bat_priv, tt_global_entry,
994 static void batadv_tt_global_del(
struct batadv_priv *bat_priv,
996 const unsigned char *addr,
997 const char *message,
bool roaming)
1002 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
1003 if (!tt_global_entry)
1007 batadv_tt_global_del_orig_entry(bat_priv, tt_global_entry,
1008 orig_node, message);
1010 if (hlist_empty(&tt_global_entry->
orig_list))
1011 batadv_tt_global_del_struct(bat_priv, tt_global_entry,
1030 local_entry = batadv_tt_local_hash_find(bat_priv,
1031 tt_global_entry->
common.addr);
1034 batadv_tt_global_del_orig_list(tt_global_entry);
1035 batadv_tt_global_del_struct(bat_priv, tt_global_entry, message);
1038 batadv_tt_global_del_roaming(bat_priv, tt_global_entry,
1039 orig_node, message);
1043 if (tt_global_entry)
1044 batadv_tt_global_entry_free_ref(tt_global_entry);
1046 batadv_tt_local_entry_free_ref(local_entry);
1051 const char *message)
1064 for (i = 0; i < hash->
size; i++) {
1068 spin_lock_bh(list_lock);
1075 batadv_tt_global_del_orig_entry(bat_priv, tt_global,
1076 orig_node, message);
1078 if (hlist_empty(&tt_global->
orig_list)) {
1080 "Deleting global tt entry %pM: %s\n",
1081 tt_global->
common.addr, message);
1082 hlist_del_rcu(node);
1083 batadv_tt_global_entry_free_ref(tt_global);
1086 spin_unlock_bh(list_lock);
1099 batadv_has_timed_out(tt_global->
roam_at, roam_timeout)) {
1101 *msg =
"Roaming timeout\n";
1105 batadv_has_timed_out(tt_global->
common.added_at, temp_timeout)) {
1107 *msg =
"Temporary client timeout\n";
1113 static void batadv_tt_global_purge(
struct batadv_priv *bat_priv)
1124 for (i = 0; i < hash->
size; i++) {
1128 spin_lock_bh(list_lock);
1135 if (!batadv_tt_global_to_purge(tt_global, &msg))
1139 "Deleting global tt entry (%pM): %s\n",
1140 tt_global->
common.addr, msg);
1142 hlist_del_rcu(node);
1144 batadv_tt_global_entry_free_ref(tt_global);
1146 spin_unlock_bh(list_lock);
1150 static void batadv_tt_global_table_free(
struct batadv_priv *bat_priv)
1160 if (!bat_priv->
tt.global_hash)
1163 hash = bat_priv->
tt.global_hash;
1165 for (i = 0; i < hash->
size; i++) {
1169 spin_lock_bh(list_lock);
1172 hlist_del_rcu(node);
1176 batadv_tt_global_entry_free_ref(tt_global);
1178 spin_unlock_bh(list_lock);
1183 bat_priv->
tt.global_hash =
NULL;
1213 tt_local_entry = batadv_tt_local_hash_find(bat_priv, src);
1214 if (!tt_local_entry)
1218 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
1219 if (!tt_global_entry)
1225 if (tt_local_entry &&
1226 _batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
1233 hlist_for_each_entry_rcu(orig_entry, node, head,
list) {
1238 if (router->
tq_avg > best_tq) {
1240 best_tq = router->
tq_avg;
1249 if (tt_global_entry)
1250 batadv_tt_global_entry_free_ref(tt_global_entry);
1252 batadv_tt_local_entry_free_ref(tt_local_entry);
1270 for (i = 0; i < hash->
size; i++) {
1274 hlist_for_each_entry_rcu(tt_common, node, head, hash_entry) {
1295 if (!batadv_tt_global_entry_has_orig(tt_global,
1301 total_one = crc16_byte(total_one,
1302 tt_common->
addr[j]);
1322 for (i = 0; i < hash->
size; i++) {
1326 hlist_for_each_entry_rcu(tt_common, node, head, hash_entry) {
1334 total_one = crc16_byte(total_one,
1335 tt_common->
addr[j]);
1344 static void batadv_tt_req_list_free(
struct batadv_priv *bat_priv)
1348 spin_lock_bh(&bat_priv->
tt.req_list_lock);
1355 spin_unlock_bh(&bat_priv->
tt.req_list_lock);
1358 static void batadv_tt_save_orig_buffer(
struct batadv_priv *bat_priv,
1360 const unsigned char *tt_buff,
1369 if (tt_buff_len > 0) {
1381 static void batadv_tt_req_purge(
struct batadv_priv *bat_priv)
1385 spin_lock_bh(&bat_priv->
tt.req_list_lock);
1387 if (batadv_has_timed_out(node->
issued_at,
1393 spin_unlock_bh(&bat_priv->
tt.req_list_lock);
1400 batadv_new_tt_req_node(
struct batadv_priv *bat_priv,
1405 spin_lock_bh(&bat_priv->
tt.req_list_lock);
1407 if (batadv_compare_eth(tt_req_node_tmp, orig_node) &&
1408 !batadv_has_timed_out(tt_req_node_tmp->
issued_at,
1420 list_add(&tt_req_node->
list, &bat_priv->
tt.req_list);
1422 spin_unlock_bh(&bat_priv->
tt.req_list_lock);
1427 static int batadv_tt_local_valid_entry(
const void *entry_ptr,
1428 const void *data_ptr)
1437 static int batadv_tt_global_valid(
const void *entry_ptr,
1438 const void *data_ptr)
1452 return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node);
1459 int (*valid_cb)(
const void *,
const void *),
1473 if (tt_query_size + tt_len > primary_if->
soft_iface->mtu) {
1474 tt_len = primary_if->
soft_iface->mtu - tt_query_size;
1479 len = tt_query_size + tt_len;
1480 skb = dev_alloc_skb(len +
ETH_HLEN);
1492 for (i = 0; i < hash->
size; i++) {
1495 hlist_for_each_entry_rcu(tt_common_entry, node,
1497 if (tt_count == tt_tot)
1500 if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data)))
1522 static int batadv_send_tt_request(
struct batadv_priv *bat_priv,
1535 primary_if = batadv_primary_if_get_selected(bat_priv);
1542 tt_req_node = batadv_new_tt_req_node(bat_priv, dst_orig_node);
1546 skb = dev_alloc_skb(
sizeof(*tt_request) +
ETH_HLEN);
1552 tt_req_len =
sizeof(*tt_request);
1572 "Sending TT_REQUEST to %pM via %pM [%c]\n",
1573 dst_orig_node->
orig, neigh_node->
addr,
1574 (full_table ?
'F' :
'.'));
1585 batadv_hardif_free_ref(primary_if);
1588 if (ret && tt_req_node) {
1589 spin_lock_bh(&bat_priv->
tt.req_list_lock);
1591 spin_unlock_bh(&bat_priv->
tt.req_list_lock);
1598 batadv_send_other_tt_response(
struct batadv_priv *bat_priv,
1605 uint8_t orig_ttvn, req_ttvn, ttvn;
1607 unsigned char *tt_buff;
1616 "Received TT_REQUEST from %pM for ttvn: %u (%pM) [%c]\n",
1617 tt_request->
src, tt_request->
ttvn, tt_request->
dst,
1621 req_dst_orig_node = batadv_orig_hash_find(bat_priv, tt_request->
dst);
1622 if (!req_dst_orig_node)
1625 res_dst_orig_node = batadv_orig_hash_find(bat_priv, tt_request->
src);
1626 if (!res_dst_orig_node)
1633 primary_if = batadv_primary_if_get_selected(bat_priv);
1638 req_ttvn = tt_request->
ttvn;
1641 if (orig_ttvn != req_ttvn ||
1660 len =
sizeof(*tt_response) + tt_len;
1661 skb = dev_alloc_skb(len +
ETH_HLEN);
1666 packet_pos =
skb_put(skb, len);
1668 tt_response->
ttvn = req_ttvn;
1671 tt_buff = skb->
data +
sizeof(*tt_response);
1682 skb = batadv_tt_response_fill_table(tt_len, ttvn,
1683 bat_priv->
tt.global_hash,
1685 batadv_tt_global_valid,
1704 "Sending TT_RESPONSE %pM via %pM for %pM (ttvn: %u)\n",
1705 res_dst_orig_node->
orig, neigh_node->
addr,
1706 req_dst_orig_node->
orig, req_ttvn);
1718 if (res_dst_orig_node)
1720 if (req_dst_orig_node)
1725 batadv_hardif_free_ref(primary_if);
1733 batadv_send_my_tt_response(
struct batadv_priv *bat_priv,
1739 uint8_t my_ttvn, req_ttvn, ttvn;
1741 unsigned char *tt_buff;
1750 "Received TT_REQUEST from %pM for ttvn: %u (me) [%c]\n",
1751 tt_request->
src, tt_request->
ttvn,
1756 req_ttvn = tt_request->
ttvn;
1758 orig_node = batadv_orig_hash_find(bat_priv, tt_request->
src);
1766 primary_if = batadv_primary_if_get_selected(bat_priv);
1774 !bat_priv->
tt.last_changeset)
1783 spin_lock_bh(&bat_priv->
tt.last_changeset_lock);
1784 tt_len = bat_priv->
tt.last_changeset_len;
1787 len =
sizeof(*tt_response) + tt_len;
1788 skb = dev_alloc_skb(len +
ETH_HLEN);
1793 packet_pos =
skb_put(skb, len);
1795 tt_response->
ttvn = req_ttvn;
1798 tt_buff = skb->
data +
sizeof(*tt_response);
1799 memcpy(tt_buff, bat_priv->
tt.last_changeset,
1800 bat_priv->
tt.last_changeset_len);
1801 spin_unlock_bh(&bat_priv->
tt.last_changeset_lock);
1807 skb = batadv_tt_response_fill_table(tt_len, ttvn,
1808 bat_priv->
tt.local_hash,
1810 batadv_tt_local_valid_entry,
1829 "Sending TT_RESPONSE to %pM via %pM [%c]\n",
1840 spin_unlock_bh(&bat_priv->
tt.last_changeset_lock);
1847 batadv_hardif_free_ref(primary_if);
1862 return batadv_send_my_tt_response(bat_priv, tt_request);
1864 return batadv_send_other_tt_response(bat_priv, tt_request);
1868 static void _batadv_tt_update_changes(
struct batadv_priv *bat_priv,
1876 for (i = 0; i < tt_num_changes; i++) {
1877 if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) {
1879 batadv_tt_global_del(bat_priv, orig_node,
1880 (tt_change + i)->addr,
1881 "tt removed by changes",
1885 (tt_change + i)->addr,
1886 (tt_change + i)->flags, ttvn))
1899 static void batadv_tt_fill_gtable(
struct batadv_priv *bat_priv,
1904 orig_node = batadv_orig_hash_find(bat_priv, tt_response->
src);
1911 _batadv_tt_update_changes(bat_priv, orig_node,
1929 static void batadv_tt_update_changes(
struct batadv_priv *bat_priv,
1934 _batadv_tt_update_changes(bat_priv, orig_node, tt_change,
1935 tt_num_changes, ttvn);
1937 batadv_tt_save_orig_buffer(bat_priv, orig_node,
1938 (
unsigned char *)tt_change, tt_num_changes);
1947 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
1948 if (!tt_local_entry)
1958 batadv_tt_local_entry_free_ref(tt_local_entry);
1970 "Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n",
1971 tt_response->
src, tt_response->
ttvn,
1979 orig_node = batadv_orig_hash_find(bat_priv, tt_response->
src);
1984 batadv_tt_fill_gtable(bat_priv, tt_response);
1987 batadv_tt_update_changes(bat_priv, orig_node,
1989 tt_response->
ttvn, tt_change);
1993 spin_lock_bh(&bat_priv->
tt.req_list_lock);
1995 if (!batadv_compare_eth(node->
addr, tt_response->
src))
2000 spin_unlock_bh(&bat_priv->
tt.req_list_lock);
2003 orig_node->
tt_crc = batadv_tt_global_crc(bat_priv, orig_node);
2017 ret = batadv_tt_local_init(bat_priv);
2021 ret = batadv_tt_global_init(bat_priv);
2025 batadv_tt_start_timer(bat_priv);
2030 static void batadv_tt_roam_list_free(
struct batadv_priv *bat_priv)
2034 spin_lock_bh(&bat_priv->
tt.roam_list_lock);
2041 spin_unlock_bh(&bat_priv->
tt.roam_list_lock);
2044 static void batadv_tt_roam_purge(
struct batadv_priv *bat_priv)
2048 spin_lock_bh(&bat_priv->
tt.roam_list_lock);
2057 spin_unlock_bh(&bat_priv->
tt.roam_list_lock);
2066 static bool batadv_tt_check_roam_count(
struct batadv_priv *bat_priv,
2072 spin_lock_bh(&bat_priv->
tt.roam_list_lock);
2077 if (!batadv_compare_eth(tt_roam_node->
addr, client))
2080 if (batadv_has_timed_out(tt_roam_node->
first_time,
2101 list_add(&tt_roam_node->
list, &bat_priv->
tt.roam_list);
2106 spin_unlock_bh(&bat_priv->
tt.roam_list_lock);
2118 size_t len =
sizeof(*roam_adv_packet);
2123 if (!batadv_tt_check_roam_count(bat_priv, client))
2126 skb = dev_alloc_skb(
sizeof(*roam_adv_packet) +
ETH_HLEN);
2138 primary_if = batadv_primary_if_get_selected(bat_priv);
2142 batadv_hardif_free_ref(primary_if);
2151 "Sending ROAMING_ADV to %pM (client %pM) via %pM\n",
2152 orig_node->
orig, client, neigh_node->
addr);
2173 delayed_work =
container_of(work,
struct delayed_work, work);
2177 batadv_tt_local_purge(bat_priv);
2178 batadv_tt_global_purge(bat_priv);
2179 batadv_tt_req_purge(bat_priv);
2180 batadv_tt_roam_purge(bat_priv);
2182 batadv_tt_start_timer(bat_priv);
2189 batadv_tt_local_table_free(bat_priv);
2190 batadv_tt_global_table_free(bat_priv);
2191 batadv_tt_req_list_free(bat_priv);
2192 batadv_tt_changes_list_free(bat_priv);
2193 batadv_tt_roam_list_free(bat_priv);
2195 kfree(bat_priv->
tt.last_changeset);
2213 for (i = 0; i < hash->
size; i++) {
2217 hlist_for_each_entry_rcu(tt_common_entry, node,
2220 if ((tt_common_entry->
flags & flags) == flags)
2224 if (!(tt_common_entry->
flags & flags))
2226 tt_common_entry->
flags &= ~flags;
2237 static void batadv_tt_local_purge_pending_clients(
struct batadv_priv *bat_priv)
2250 for (i = 0; i < hash->
size; i++) {
2254 spin_lock_bh(list_lock);
2261 "Deleting local tt entry (%pM): pending\n",
2265 hlist_del_rcu(node);
2269 batadv_tt_local_entry_free_ref(tt_local);
2271 spin_unlock_bh(list_lock);
2276 static int batadv_tt_commit_changes(
struct batadv_priv *bat_priv,
2277 unsigned char **packet_buff,
2278 int *packet_buff_len,
int packet_min_len)
2285 changed_num = batadv_tt_set_flags(bat_priv->
tt.local_hash,
2289 atomic_add(changed_num, &bat_priv->
tt.local_entry_num);
2290 batadv_tt_local_purge_pending_clients(bat_priv);
2291 bat_priv->
tt.local_crc = batadv_tt_local_crc(bat_priv);
2296 "Local changes committed, updating to ttvn %u\n",
2298 bat_priv->
tt.poss_change =
false;
2303 return batadv_tt_changes_fill_buff(bat_priv, packet_buff,
2304 packet_buff_len, packet_min_len);
2309 unsigned char **packet_buff,
int *packet_buff_len,
2315 tt_num_changes = batadv_tt_commit_changes(bat_priv, packet_buff,
2320 if ((tt_num_changes < 0) &&
2322 batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len,
2323 packet_min_len, packet_min_len);
2327 return tt_num_changes;
2340 tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst);
2341 if (!tt_local_entry)
2344 tt_global_entry = batadv_tt_global_hash_find(bat_priv, src);
2345 if (!tt_global_entry)
2348 if (!_batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
2354 if (tt_global_entry)
2355 batadv_tt_global_entry_free_ref(tt_global_entry);
2357 batadv_tt_local_entry_free_ref(tt_local_entry);
2363 const unsigned char *tt_buff,
uint8_t tt_num_changes,
2367 bool full_table =
true;
2378 ttvn - orig_ttvn == 1) {
2384 if (!tt_num_changes) {
2390 batadv_tt_update_changes(bat_priv, orig_node, tt_num_changes,
2397 orig_node->
tt_crc = batadv_tt_global_crc(bat_priv, orig_node);
2408 if (orig_node->
tt_crc != tt_crc)
2420 orig_node->
tt_crc != tt_crc) {
2423 "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u crc: %u last_crc: %u num_changes: %u)\n",
2424 orig_node->
orig, ttvn, orig_ttvn, tt_crc,
2425 orig_node->
tt_crc, tt_num_changes);
2426 batadv_send_tt_request(bat_priv, orig_node, ttvn,
2427 tt_crc, full_table);
2443 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
2444 if (!tt_global_entry)
2448 batadv_tt_global_entry_free_ref(tt_global_entry);
2455 const unsigned char *addr)
2472 "Added temporary global client (addr: %pM orig: %pM)\n",
2473 addr, orig_node->
orig);