558
static void _tt_global_del_orig(struct bat_priv *bat_priv,
559
struct tt_global_entry *tt_global_entry,
671
static void _tt_global_del(struct bat_priv *bat_priv,
672
struct tt_global_entry *tt_global_entry,
562
bat_dbg(DBG_ROUTES, bat_priv,
675
if (!tt_global_entry)
678
bat_dbg(DBG_TT, bat_priv,
563
679
"Deleting global tt entry %pM (via %pM): %s\n",
564
680
tt_global_entry->addr, tt_global_entry->orig_node->orig,
683
atomic_dec(&tt_global_entry->orig_node->tt_size);
567
685
hash_remove(bat_priv->tt_global_hash, compare_gtt, choose_orig,
568
686
tt_global_entry->addr);
569
kfree(tt_global_entry);
689
tt_global_entry_free_ref(tt_global_entry);
692
void tt_global_del(struct bat_priv *bat_priv,
693
struct orig_node *orig_node, const unsigned char *addr,
694
const char *message, bool roaming)
696
struct tt_global_entry *tt_global_entry = NULL;
698
tt_global_entry = tt_global_hash_find(bat_priv, addr);
699
if (!tt_global_entry)
702
if (tt_global_entry->orig_node == orig_node) {
704
tt_global_entry->flags |= TT_CLIENT_ROAM;
705
tt_global_entry->roam_at = jiffies;
708
_tt_global_del(bat_priv, tt_global_entry, message);
712
tt_global_entry_free_ref(tt_global_entry);
572
715
void tt_global_del_orig(struct bat_priv *bat_priv,
573
struct orig_node *orig_node, char *message)
716
struct orig_node *orig_node, const char *message)
575
718
struct tt_global_entry *tt_global_entry;
576
int tt_buff_count = 0;
577
unsigned char *tt_ptr;
720
struct hashtable_t *hash = bat_priv->tt_global_hash;
721
struct hlist_node *node, *safe;
722
struct hlist_head *head;
723
spinlock_t *list_lock; /* protects write access to the hash lists */
579
if (orig_node->tt_buff_len == 0)
582
spin_lock_bh(&bat_priv->tt_ghash_lock);
584
while ((tt_buff_count + 1) * ETH_ALEN <= orig_node->tt_buff_len) {
585
tt_ptr = orig_node->tt_buff + (tt_buff_count * ETH_ALEN);
586
tt_global_entry = tt_global_hash_find(bat_priv, tt_ptr);
588
if ((tt_global_entry) &&
589
(tt_global_entry->orig_node == orig_node))
590
_tt_global_del_orig(bat_priv, tt_global_entry,
596
spin_unlock_bh(&bat_priv->tt_ghash_lock);
598
orig_node->tt_buff_len = 0;
599
kfree(orig_node->tt_buff);
600
orig_node->tt_buff = NULL;
603
static void tt_global_del(struct hlist_node *node, void *arg)
605
void *data = container_of(node, struct tt_global_entry, hash_entry);
610
void tt_global_free(struct bat_priv *bat_priv)
728
for (i = 0; i < hash->size; i++) {
729
head = &hash->table[i];
730
list_lock = &hash->list_locks[i];
732
spin_lock_bh(list_lock);
733
hlist_for_each_entry_safe(tt_global_entry, node, safe,
735
if (tt_global_entry->orig_node == orig_node) {
736
bat_dbg(DBG_TT, bat_priv,
737
"Deleting global tt entry %pM "
738
"(via %pM): originator time out\n",
739
tt_global_entry->addr,
740
tt_global_entry->orig_node->orig);
742
tt_global_entry_free_ref(tt_global_entry);
745
spin_unlock_bh(list_lock);
747
atomic_set(&orig_node->tt_size, 0);
750
static void tt_global_roam_purge(struct bat_priv *bat_priv)
752
struct hashtable_t *hash = bat_priv->tt_global_hash;
753
struct tt_global_entry *tt_global_entry;
754
struct hlist_node *node, *node_tmp;
755
struct hlist_head *head;
756
spinlock_t *list_lock; /* protects write access to the hash lists */
759
for (i = 0; i < hash->size; i++) {
760
head = &hash->table[i];
761
list_lock = &hash->list_locks[i];
763
spin_lock_bh(list_lock);
764
hlist_for_each_entry_safe(tt_global_entry, node, node_tmp,
766
if (!(tt_global_entry->flags & TT_CLIENT_ROAM))
768
if (!is_out_of_time(tt_global_entry->roam_at,
769
TT_CLIENT_ROAM_TIMEOUT * 1000))
772
bat_dbg(DBG_TT, bat_priv, "Deleting global "
773
"tt entry (%pM): Roaming timeout\n",
774
tt_global_entry->addr);
775
atomic_dec(&tt_global_entry->orig_node->tt_size);
777
tt_global_entry_free_ref(tt_global_entry);
779
spin_unlock_bh(list_lock);
784
static void tt_global_table_free(struct bat_priv *bat_priv)
786
struct hashtable_t *hash;
787
spinlock_t *list_lock; /* protects write access to the hash lists */
788
struct tt_global_entry *tt_global_entry;
789
struct hlist_node *node, *node_tmp;
790
struct hlist_head *head;
612
793
if (!bat_priv->tt_global_hash)
615
hash_delete(bat_priv->tt_global_hash, tt_global_del, NULL);
796
hash = bat_priv->tt_global_hash;
798
for (i = 0; i < hash->size; i++) {
799
head = &hash->table[i];
800
list_lock = &hash->list_locks[i];
802
spin_lock_bh(list_lock);
803
hlist_for_each_entry_safe(tt_global_entry, node, node_tmp,
806
tt_global_entry_free_ref(tt_global_entry);
808
spin_unlock_bh(list_lock);
616
813
bat_priv->tt_global_hash = NULL;
619
struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr)
621
struct tt_global_entry *tt_global_entry;
816
static bool _is_ap_isolated(struct tt_local_entry *tt_local_entry,
817
struct tt_global_entry *tt_global_entry)
821
if (tt_local_entry->flags & TT_CLIENT_WIFI &&
822
tt_global_entry->flags & TT_CLIENT_WIFI)
828
struct orig_node *transtable_search(struct bat_priv *bat_priv,
829
const uint8_t *src, const uint8_t *addr)
831
struct tt_local_entry *tt_local_entry = NULL;
832
struct tt_global_entry *tt_global_entry = NULL;
622
833
struct orig_node *orig_node = NULL;
624
spin_lock_bh(&bat_priv->tt_ghash_lock);
835
if (src && atomic_read(&bat_priv->ap_isolation)) {
836
tt_local_entry = tt_local_hash_find(bat_priv, src);
625
841
tt_global_entry = tt_global_hash_find(bat_priv, addr);
627
842
if (!tt_global_entry)
845
/* check whether the clients should not communicate due to AP
847
if (tt_local_entry && _is_ap_isolated(tt_local_entry, tt_global_entry))
630
850
if (!atomic_inc_not_zero(&tt_global_entry->orig_node->refcount))
853
/* A global client marked as PENDING has already moved from that
855
if (tt_global_entry->flags & TT_CLIENT_PENDING)
633
858
orig_node = tt_global_entry->orig_node;
636
spin_unlock_bh(&bat_priv->tt_ghash_lock);
862
tt_global_entry_free_ref(tt_global_entry);
864
tt_local_entry_free_ref(tt_local_entry);
637
866
return orig_node;
869
/* Calculates the checksum of the local table of a given orig_node */
870
uint16_t tt_global_crc(struct bat_priv *bat_priv, struct orig_node *orig_node)
872
uint16_t total = 0, total_one;
873
struct hashtable_t *hash = bat_priv->tt_global_hash;
874
struct tt_global_entry *tt_global_entry;
875
struct hlist_node *node;
876
struct hlist_head *head;
879
for (i = 0; i < hash->size; i++) {
880
head = &hash->table[i];
883
hlist_for_each_entry_rcu(tt_global_entry, node,
885
if (compare_eth(tt_global_entry->orig_node,
887
/* Roaming clients are in the global table for
888
* consistency only. They don't have to be
889
* taken into account while computing the
891
if (tt_global_entry->flags & TT_CLIENT_ROAM)
894
for (j = 0; j < ETH_ALEN; j++)
895
total_one = crc16_byte(total_one,
896
tt_global_entry->addr[j]);
906
/* Calculates the checksum of the local table */
907
uint16_t tt_local_crc(struct bat_priv *bat_priv)
909
uint16_t total = 0, total_one;
910
struct hashtable_t *hash = bat_priv->tt_local_hash;
911
struct tt_local_entry *tt_local_entry;
912
struct hlist_node *node;
913
struct hlist_head *head;
916
for (i = 0; i < hash->size; i++) {
917
head = &hash->table[i];
920
hlist_for_each_entry_rcu(tt_local_entry, node,
922
/* not yet committed clients have not to be taken into
923
* account while computing the CRC */
924
if (tt_local_entry->flags & TT_CLIENT_NEW)
927
for (j = 0; j < ETH_ALEN; j++)
928
total_one = crc16_byte(total_one,
929
tt_local_entry->addr[j]);
938
static void tt_req_list_free(struct bat_priv *bat_priv)
940
struct tt_req_node *node, *safe;
942
spin_lock_bh(&bat_priv->tt_req_list_lock);
944
list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
945
list_del(&node->list);
949
spin_unlock_bh(&bat_priv->tt_req_list_lock);
952
void tt_save_orig_buffer(struct bat_priv *bat_priv, struct orig_node *orig_node,
953
const unsigned char *tt_buff, uint8_t tt_num_changes)
955
uint16_t tt_buff_len = tt_len(tt_num_changes);
957
/* Replace the old buffer only if I received something in the
958
* last OGM (the OGM could carry no changes) */
959
spin_lock_bh(&orig_node->tt_buff_lock);
960
if (tt_buff_len > 0) {
961
kfree(orig_node->tt_buff);
962
orig_node->tt_buff_len = 0;
963
orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC);
964
if (orig_node->tt_buff) {
965
memcpy(orig_node->tt_buff, tt_buff, tt_buff_len);
966
orig_node->tt_buff_len = tt_buff_len;
969
spin_unlock_bh(&orig_node->tt_buff_lock);
972
static void tt_req_purge(struct bat_priv *bat_priv)
974
struct tt_req_node *node, *safe;
976
spin_lock_bh(&bat_priv->tt_req_list_lock);
977
list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
978
if (is_out_of_time(node->issued_at,
979
TT_REQUEST_TIMEOUT * 1000)) {
980
list_del(&node->list);
984
spin_unlock_bh(&bat_priv->tt_req_list_lock);
987
/* returns the pointer to the new tt_req_node struct if no request
988
* has already been issued for this orig_node, NULL otherwise */
989
static struct tt_req_node *new_tt_req_node(struct bat_priv *bat_priv,
990
struct orig_node *orig_node)
992
struct tt_req_node *tt_req_node_tmp, *tt_req_node = NULL;
994
spin_lock_bh(&bat_priv->tt_req_list_lock);
995
list_for_each_entry(tt_req_node_tmp, &bat_priv->tt_req_list, list) {
996
if (compare_eth(tt_req_node_tmp, orig_node) &&
997
!is_out_of_time(tt_req_node_tmp->issued_at,
998
TT_REQUEST_TIMEOUT * 1000))
1002
tt_req_node = kmalloc(sizeof(*tt_req_node), GFP_ATOMIC);
1006
memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN);
1007
tt_req_node->issued_at = jiffies;
1009
list_add(&tt_req_node->list, &bat_priv->tt_req_list);
1011
spin_unlock_bh(&bat_priv->tt_req_list_lock);
1015
/* data_ptr is useless here, but has to be kept to respect the prototype */
1016
static int tt_local_valid_entry(const void *entry_ptr, const void *data_ptr)
1018
const struct tt_local_entry *tt_local_entry = entry_ptr;
1020
if (tt_local_entry->flags & TT_CLIENT_NEW)
1025
static int tt_global_valid_entry(const void *entry_ptr, const void *data_ptr)
1027
const struct tt_global_entry *tt_global_entry = entry_ptr;
1028
const struct orig_node *orig_node = data_ptr;
1030
if (tt_global_entry->flags & TT_CLIENT_ROAM)
1033
return (tt_global_entry->orig_node == orig_node);
1036
static struct sk_buff *tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
1037
struct hashtable_t *hash,
1038
struct hard_iface *primary_if,
1039
int (*valid_cb)(const void *,
1043
struct tt_local_entry *tt_local_entry;
1044
struct tt_query_packet *tt_response;
1045
struct tt_change *tt_change;
1046
struct hlist_node *node;
1047
struct hlist_head *head;
1048
struct sk_buff *skb = NULL;
1049
uint16_t tt_tot, tt_count;
1050
ssize_t tt_query_size = sizeof(struct tt_query_packet);
1053
if (tt_query_size + tt_len > primary_if->soft_iface->mtu) {
1054
tt_len = primary_if->soft_iface->mtu - tt_query_size;
1055
tt_len -= tt_len % sizeof(struct tt_change);
1057
tt_tot = tt_len / sizeof(struct tt_change);
1059
skb = dev_alloc_skb(tt_query_size + tt_len + ETH_HLEN);
1063
skb_reserve(skb, ETH_HLEN);
1064
tt_response = (struct tt_query_packet *)skb_put(skb,
1065
tt_query_size + tt_len);
1066
tt_response->ttvn = ttvn;
1068
tt_change = (struct tt_change *)(skb->data + tt_query_size);
1072
for (i = 0; i < hash->size; i++) {
1073
head = &hash->table[i];
1075
hlist_for_each_entry_rcu(tt_local_entry, node,
1077
if (tt_count == tt_tot)
1080
if ((valid_cb) && (!valid_cb(tt_local_entry, cb_data)))
1083
memcpy(tt_change->addr, tt_local_entry->addr, ETH_ALEN);
1084
tt_change->flags = NO_FLAGS;
1092
/* store in the message the number of entries we have successfully
1094
tt_response->tt_data = htons(tt_count);
1100
static int send_tt_request(struct bat_priv *bat_priv,
1101
struct orig_node *dst_orig_node,
1102
uint8_t ttvn, uint16_t tt_crc, bool full_table)
1104
struct sk_buff *skb = NULL;
1105
struct tt_query_packet *tt_request;
1106
struct neigh_node *neigh_node = NULL;
1107
struct hard_iface *primary_if;
1108
struct tt_req_node *tt_req_node = NULL;
1111
primary_if = primary_if_get_selected(bat_priv);
1115
/* The new tt_req will be issued only if I'm not waiting for a
1116
* reply from the same orig_node yet */
1117
tt_req_node = new_tt_req_node(bat_priv, dst_orig_node);
1121
skb = dev_alloc_skb(sizeof(struct tt_query_packet) + ETH_HLEN);
1125
skb_reserve(skb, ETH_HLEN);
1127
tt_request = (struct tt_query_packet *)skb_put(skb,
1128
sizeof(struct tt_query_packet));
1130
tt_request->packet_type = BAT_TT_QUERY;
1131
tt_request->version = COMPAT_VERSION;
1132
memcpy(tt_request->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1133
memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN);
1134
tt_request->ttl = TTL;
1135
tt_request->ttvn = ttvn;
1136
tt_request->tt_data = tt_crc;
1137
tt_request->flags = TT_REQUEST;
1140
tt_request->flags |= TT_FULL_TABLE;
1142
neigh_node = orig_node_get_router(dst_orig_node);
1146
bat_dbg(DBG_TT, bat_priv, "Sending TT_REQUEST to %pM via %pM "
1147
"[%c]\n", dst_orig_node->orig, neigh_node->addr,
1148
(full_table ? 'F' : '.'));
1150
send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1155
neigh_node_free_ref(neigh_node);
1157
hardif_free_ref(primary_if);
1160
if (ret && tt_req_node) {
1161
spin_lock_bh(&bat_priv->tt_req_list_lock);
1162
list_del(&tt_req_node->list);
1163
spin_unlock_bh(&bat_priv->tt_req_list_lock);
1169
static bool send_other_tt_response(struct bat_priv *bat_priv,
1170
struct tt_query_packet *tt_request)
1172
struct orig_node *req_dst_orig_node = NULL, *res_dst_orig_node = NULL;
1173
struct neigh_node *neigh_node = NULL;
1174
struct hard_iface *primary_if = NULL;
1175
uint8_t orig_ttvn, req_ttvn, ttvn;
1177
unsigned char *tt_buff;
1179
uint16_t tt_len, tt_tot;
1180
struct sk_buff *skb = NULL;
1181
struct tt_query_packet *tt_response;
1183
bat_dbg(DBG_TT, bat_priv,
1184
"Received TT_REQUEST from %pM for "
1185
"ttvn: %u (%pM) [%c]\n", tt_request->src,
1186
tt_request->ttvn, tt_request->dst,
1187
(tt_request->flags & TT_FULL_TABLE ? 'F' : '.'));
1189
/* Let's get the orig node of the REAL destination */
1190
req_dst_orig_node = get_orig_node(bat_priv, tt_request->dst);
1191
if (!req_dst_orig_node)
1194
res_dst_orig_node = get_orig_node(bat_priv, tt_request->src);
1195
if (!res_dst_orig_node)
1198
neigh_node = orig_node_get_router(res_dst_orig_node);
1202
primary_if = primary_if_get_selected(bat_priv);
1206
orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
1207
req_ttvn = tt_request->ttvn;
1209
/* I don't have the requested data */
1210
if (orig_ttvn != req_ttvn ||
1211
tt_request->tt_data != req_dst_orig_node->tt_crc)
1214
/* If the full table has been explicitly requested */
1215
if (tt_request->flags & TT_FULL_TABLE ||
1216
!req_dst_orig_node->tt_buff)
1221
/* In this version, fragmentation is not implemented, then
1222
* I'll send only one packet with as much TT entries as I can */
1224
spin_lock_bh(&req_dst_orig_node->tt_buff_lock);
1225
tt_len = req_dst_orig_node->tt_buff_len;
1226
tt_tot = tt_len / sizeof(struct tt_change);
1228
skb = dev_alloc_skb(sizeof(struct tt_query_packet) +
1233
skb_reserve(skb, ETH_HLEN);
1234
tt_response = (struct tt_query_packet *)skb_put(skb,
1235
sizeof(struct tt_query_packet) + tt_len);
1236
tt_response->ttvn = req_ttvn;
1237
tt_response->tt_data = htons(tt_tot);
1239
tt_buff = skb->data + sizeof(struct tt_query_packet);
1240
/* Copy the last orig_node's OGM buffer */
1241
memcpy(tt_buff, req_dst_orig_node->tt_buff,
1242
req_dst_orig_node->tt_buff_len);
1244
spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
1246
tt_len = (uint16_t)atomic_read(&req_dst_orig_node->tt_size) *
1247
sizeof(struct tt_change);
1248
ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
1250
skb = tt_response_fill_table(tt_len, ttvn,
1251
bat_priv->tt_global_hash,
1252
primary_if, tt_global_valid_entry,
1257
tt_response = (struct tt_query_packet *)skb->data;
1260
tt_response->packet_type = BAT_TT_QUERY;
1261
tt_response->version = COMPAT_VERSION;
1262
tt_response->ttl = TTL;
1263
memcpy(tt_response->src, req_dst_orig_node->orig, ETH_ALEN);
1264
memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
1265
tt_response->flags = TT_RESPONSE;
1268
tt_response->flags |= TT_FULL_TABLE;
1270
bat_dbg(DBG_TT, bat_priv,
1271
"Sending TT_RESPONSE %pM via %pM for %pM (ttvn: %u)\n",
1272
res_dst_orig_node->orig, neigh_node->addr,
1273
req_dst_orig_node->orig, req_ttvn);
1275
send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1280
spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
1283
if (res_dst_orig_node)
1284
orig_node_free_ref(res_dst_orig_node);
1285
if (req_dst_orig_node)
1286
orig_node_free_ref(req_dst_orig_node);
1288
neigh_node_free_ref(neigh_node);
1290
hardif_free_ref(primary_if);
1296
static bool send_my_tt_response(struct bat_priv *bat_priv,
1297
struct tt_query_packet *tt_request)
1299
struct orig_node *orig_node = NULL;
1300
struct neigh_node *neigh_node = NULL;
1301
struct hard_iface *primary_if = NULL;
1302
uint8_t my_ttvn, req_ttvn, ttvn;
1304
unsigned char *tt_buff;
1306
uint16_t tt_len, tt_tot;
1307
struct sk_buff *skb = NULL;
1308
struct tt_query_packet *tt_response;
1310
bat_dbg(DBG_TT, bat_priv,
1311
"Received TT_REQUEST from %pM for "
1312
"ttvn: %u (me) [%c]\n", tt_request->src,
1314
(tt_request->flags & TT_FULL_TABLE ? 'F' : '.'));
1317
my_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn);
1318
req_ttvn = tt_request->ttvn;
1320
orig_node = get_orig_node(bat_priv, tt_request->src);
1324
neigh_node = orig_node_get_router(orig_node);
1328
primary_if = primary_if_get_selected(bat_priv);
1332
/* If the full table has been explicitly requested or the gap
1333
* is too big send the whole local translation table */
1334
if (tt_request->flags & TT_FULL_TABLE || my_ttvn != req_ttvn ||
1340
/* In this version, fragmentation is not implemented, then
1341
* I'll send only one packet with as much TT entries as I can */
1343
spin_lock_bh(&bat_priv->tt_buff_lock);
1344
tt_len = bat_priv->tt_buff_len;
1345
tt_tot = tt_len / sizeof(struct tt_change);
1347
skb = dev_alloc_skb(sizeof(struct tt_query_packet) +
1352
skb_reserve(skb, ETH_HLEN);
1353
tt_response = (struct tt_query_packet *)skb_put(skb,
1354
sizeof(struct tt_query_packet) + tt_len);
1355
tt_response->ttvn = req_ttvn;
1356
tt_response->tt_data = htons(tt_tot);
1358
tt_buff = skb->data + sizeof(struct tt_query_packet);
1359
memcpy(tt_buff, bat_priv->tt_buff,
1360
bat_priv->tt_buff_len);
1361
spin_unlock_bh(&bat_priv->tt_buff_lock);
1363
tt_len = (uint16_t)atomic_read(&bat_priv->num_local_tt) *
1364
sizeof(struct tt_change);
1365
ttvn = (uint8_t)atomic_read(&bat_priv->ttvn);
1367
skb = tt_response_fill_table(tt_len, ttvn,
1368
bat_priv->tt_local_hash,
1369
primary_if, tt_local_valid_entry,
1374
tt_response = (struct tt_query_packet *)skb->data;
1377
tt_response->packet_type = BAT_TT_QUERY;
1378
tt_response->version = COMPAT_VERSION;
1379
tt_response->ttl = TTL;
1380
memcpy(tt_response->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1381
memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
1382
tt_response->flags = TT_RESPONSE;
1385
tt_response->flags |= TT_FULL_TABLE;
1387
bat_dbg(DBG_TT, bat_priv,
1388
"Sending TT_RESPONSE to %pM via %pM [%c]\n",
1389
orig_node->orig, neigh_node->addr,
1390
(tt_response->flags & TT_FULL_TABLE ? 'F' : '.'));
1392
send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1397
spin_unlock_bh(&bat_priv->tt_buff_lock);
1400
orig_node_free_ref(orig_node);
1402
neigh_node_free_ref(neigh_node);
1404
hardif_free_ref(primary_if);
1407
/* This packet was for me, so it doesn't need to be re-routed */
1411
bool send_tt_response(struct bat_priv *bat_priv,
1412
struct tt_query_packet *tt_request)
1414
if (is_my_mac(tt_request->dst))
1415
return send_my_tt_response(bat_priv, tt_request);
1417
return send_other_tt_response(bat_priv, tt_request);
1420
static void _tt_update_changes(struct bat_priv *bat_priv,
1421
struct orig_node *orig_node,
1422
struct tt_change *tt_change,
1423
uint16_t tt_num_changes, uint8_t ttvn)
1427
for (i = 0; i < tt_num_changes; i++) {
1428
if ((tt_change + i)->flags & TT_CLIENT_DEL)
1429
tt_global_del(bat_priv, orig_node,
1430
(tt_change + i)->addr,
1431
"tt removed by changes",
1432
(tt_change + i)->flags & TT_CLIENT_ROAM);
1434
if (!tt_global_add(bat_priv, orig_node,
1435
(tt_change + i)->addr, ttvn, false,
1436
(tt_change + i)->flags &
1438
/* In case of problem while storing a
1439
* global_entry, we stop the updating
1440
* procedure without committing the
1441
* ttvn change. This will avoid to send
1442
* corrupted data on tt_request
1448
static void tt_fill_gtable(struct bat_priv *bat_priv,
1449
struct tt_query_packet *tt_response)
1451
struct orig_node *orig_node = NULL;
1453
orig_node = orig_hash_find(bat_priv, tt_response->src);
1457
/* Purge the old table first.. */
1458
tt_global_del_orig(bat_priv, orig_node, "Received full table");
1460
_tt_update_changes(bat_priv, orig_node,
1461
(struct tt_change *)(tt_response + 1),
1462
tt_response->tt_data, tt_response->ttvn);
1464
spin_lock_bh(&orig_node->tt_buff_lock);
1465
kfree(orig_node->tt_buff);
1466
orig_node->tt_buff_len = 0;
1467
orig_node->tt_buff = NULL;
1468
spin_unlock_bh(&orig_node->tt_buff_lock);
1470
atomic_set(&orig_node->last_ttvn, tt_response->ttvn);
1474
orig_node_free_ref(orig_node);
1477
static void tt_update_changes(struct bat_priv *bat_priv,
1478
struct orig_node *orig_node,
1479
uint16_t tt_num_changes, uint8_t ttvn,
1480
struct tt_change *tt_change)
1482
_tt_update_changes(bat_priv, orig_node, tt_change, tt_num_changes,
1485
tt_save_orig_buffer(bat_priv, orig_node, (unsigned char *)tt_change,
1487
atomic_set(&orig_node->last_ttvn, ttvn);
1490
bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr)
1492
struct tt_local_entry *tt_local_entry = NULL;
1495
tt_local_entry = tt_local_hash_find(bat_priv, addr);
1496
if (!tt_local_entry)
1498
/* Check if the client has been logically deleted (but is kept for
1499
* consistency purpose) */
1500
if (tt_local_entry->flags & TT_CLIENT_PENDING)
1505
tt_local_entry_free_ref(tt_local_entry);
1509
void handle_tt_response(struct bat_priv *bat_priv,
1510
struct tt_query_packet *tt_response)
1512
struct tt_req_node *node, *safe;
1513
struct orig_node *orig_node = NULL;
1515
bat_dbg(DBG_TT, bat_priv, "Received TT_RESPONSE from %pM for "
1516
"ttvn %d t_size: %d [%c]\n",
1517
tt_response->src, tt_response->ttvn,
1518
tt_response->tt_data,
1519
(tt_response->flags & TT_FULL_TABLE ? 'F' : '.'));
1521
orig_node = orig_hash_find(bat_priv, tt_response->src);
1525
if (tt_response->flags & TT_FULL_TABLE)
1526
tt_fill_gtable(bat_priv, tt_response);
1528
tt_update_changes(bat_priv, orig_node, tt_response->tt_data,
1530
(struct tt_change *)(tt_response + 1));
1532
/* Delete the tt_req_node from pending tt_requests list */
1533
spin_lock_bh(&bat_priv->tt_req_list_lock);
1534
list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
1535
if (!compare_eth(node->addr, tt_response->src))
1537
list_del(&node->list);
1540
spin_unlock_bh(&bat_priv->tt_req_list_lock);
1542
/* Recalculate the CRC for this orig_node and store it */
1543
orig_node->tt_crc = tt_global_crc(bat_priv, orig_node);
1544
/* Roaming phase is over: tables are in sync again. I can
1546
orig_node->tt_poss_change = false;
1549
orig_node_free_ref(orig_node);
1552
int tt_init(struct bat_priv *bat_priv)
1554
if (!tt_local_init(bat_priv))
1557
if (!tt_global_init(bat_priv))
1560
tt_start_timer(bat_priv);
1565
static void tt_roam_list_free(struct bat_priv *bat_priv)
1567
struct tt_roam_node *node, *safe;
1569
spin_lock_bh(&bat_priv->tt_roam_list_lock);
1571
list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) {
1572
list_del(&node->list);
1576
spin_unlock_bh(&bat_priv->tt_roam_list_lock);
1579
static void tt_roam_purge(struct bat_priv *bat_priv)
1581
struct tt_roam_node *node, *safe;
1583
spin_lock_bh(&bat_priv->tt_roam_list_lock);
1584
list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) {
1585
if (!is_out_of_time(node->first_time,
1586
ROAMING_MAX_TIME * 1000))
1589
list_del(&node->list);
1592
spin_unlock_bh(&bat_priv->tt_roam_list_lock);
1595
/* This function checks whether the client already reached the
1596
* maximum number of possible roaming phases. In this case the ROAMING_ADV
1599
* returns true if the ROAMING_ADV can be sent, false otherwise */
1600
static bool tt_check_roam_count(struct bat_priv *bat_priv,
1603
struct tt_roam_node *tt_roam_node;
1606
spin_lock_bh(&bat_priv->tt_roam_list_lock);
1607
/* The new tt_req will be issued only if I'm not waiting for a
1608
* reply from the same orig_node yet */
1609
list_for_each_entry(tt_roam_node, &bat_priv->tt_roam_list, list) {
1610
if (!compare_eth(tt_roam_node->addr, client))
1613
if (is_out_of_time(tt_roam_node->first_time,
1614
ROAMING_MAX_TIME * 1000))
1617
if (!atomic_dec_not_zero(&tt_roam_node->counter))
1618
/* Sorry, you roamed too many times! */
1625
tt_roam_node = kmalloc(sizeof(*tt_roam_node), GFP_ATOMIC);
1629
tt_roam_node->first_time = jiffies;
1630
atomic_set(&tt_roam_node->counter, ROAMING_MAX_COUNT - 1);
1631
memcpy(tt_roam_node->addr, client, ETH_ALEN);
1633
list_add(&tt_roam_node->list, &bat_priv->tt_roam_list);
1638
spin_unlock_bh(&bat_priv->tt_roam_list_lock);
1642
void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client,
1643
struct orig_node *orig_node)
1645
struct neigh_node *neigh_node = NULL;
1646
struct sk_buff *skb = NULL;
1647
struct roam_adv_packet *roam_adv_packet;
1649
struct hard_iface *primary_if;
1651
/* before going on we have to check whether the client has
1652
* already roamed to us too many times */
1653
if (!tt_check_roam_count(bat_priv, client))
1656
skb = dev_alloc_skb(sizeof(struct roam_adv_packet) + ETH_HLEN);
1660
skb_reserve(skb, ETH_HLEN);
1662
roam_adv_packet = (struct roam_adv_packet *)skb_put(skb,
1663
sizeof(struct roam_adv_packet));
1665
roam_adv_packet->packet_type = BAT_ROAM_ADV;
1666
roam_adv_packet->version = COMPAT_VERSION;
1667
roam_adv_packet->ttl = TTL;
1668
primary_if = primary_if_get_selected(bat_priv);
1671
memcpy(roam_adv_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1672
hardif_free_ref(primary_if);
1673
memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN);
1674
memcpy(roam_adv_packet->client, client, ETH_ALEN);
1676
neigh_node = orig_node_get_router(orig_node);
1680
bat_dbg(DBG_TT, bat_priv,
1681
"Sending ROAMING_ADV to %pM (client %pM) via %pM\n",
1682
orig_node->orig, client, neigh_node->addr);
1684
send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1689
neigh_node_free_ref(neigh_node);
1695
static void tt_purge(struct work_struct *work)
1697
struct delayed_work *delayed_work =
1698
container_of(work, struct delayed_work, work);
1699
struct bat_priv *bat_priv =
1700
container_of(delayed_work, struct bat_priv, tt_work);
1702
tt_local_purge(bat_priv);
1703
tt_global_roam_purge(bat_priv);
1704
tt_req_purge(bat_priv);
1705
tt_roam_purge(bat_priv);
1707
tt_start_timer(bat_priv);
1710
void tt_free(struct bat_priv *bat_priv)
1712
cancel_delayed_work_sync(&bat_priv->tt_work);
1714
tt_local_table_free(bat_priv);
1715
tt_global_table_free(bat_priv);
1716
tt_req_list_free(bat_priv);
1717
tt_changes_list_free(bat_priv);
1718
tt_roam_list_free(bat_priv);
1720
kfree(bat_priv->tt_buff);
1723
/* This function will reset the specified flags from all the entries in
1724
* the given hash table and will increment num_local_tt for each involved
1726
static void tt_local_reset_flags(struct bat_priv *bat_priv, uint16_t flags)
1729
struct hashtable_t *hash = bat_priv->tt_local_hash;
1730
struct hlist_head *head;
1731
struct hlist_node *node;
1732
struct tt_local_entry *tt_local_entry;
1737
for (i = 0; i < hash->size; i++) {
1738
head = &hash->table[i];
1741
hlist_for_each_entry_rcu(tt_local_entry, node,
1743
if (!(tt_local_entry->flags & flags))
1745
tt_local_entry->flags &= ~flags;
1746
atomic_inc(&bat_priv->num_local_tt);
1753
/* Purge out all the tt local entries marked with TT_CLIENT_PENDING */
1754
static void tt_local_purge_pending_clients(struct bat_priv *bat_priv)
1756
struct hashtable_t *hash = bat_priv->tt_local_hash;
1757
struct tt_local_entry *tt_local_entry;
1758
struct hlist_node *node, *node_tmp;
1759
struct hlist_head *head;
1760
spinlock_t *list_lock; /* protects write access to the hash lists */
1766
for (i = 0; i < hash->size; i++) {
1767
head = &hash->table[i];
1768
list_lock = &hash->list_locks[i];
1770
spin_lock_bh(list_lock);
1771
hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
1773
if (!(tt_local_entry->flags & TT_CLIENT_PENDING))
1776
bat_dbg(DBG_TT, bat_priv, "Deleting local tt entry "
1777
"(%pM): pending\n", tt_local_entry->addr);
1779
atomic_dec(&bat_priv->num_local_tt);
1780
hlist_del_rcu(node);
1781
tt_local_entry_free_ref(tt_local_entry);
1783
spin_unlock_bh(list_lock);
1788
void tt_commit_changes(struct bat_priv *bat_priv)
1790
tt_local_reset_flags(bat_priv, TT_CLIENT_NEW);
1791
tt_local_purge_pending_clients(bat_priv);
1793
/* Increment the TTVN only once per OGM interval */
1794
atomic_inc(&bat_priv->ttvn);
1795
bat_priv->tt_poss_change = false;
1798
bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst)
1800
struct tt_local_entry *tt_local_entry = NULL;
1801
struct tt_global_entry *tt_global_entry = NULL;
1804
if (!atomic_read(&bat_priv->ap_isolation))
1807
tt_local_entry = tt_local_hash_find(bat_priv, dst);
1808
if (!tt_local_entry)
1811
tt_global_entry = tt_global_hash_find(bat_priv, src);
1812
if (!tt_global_entry)
1815
if (_is_ap_isolated(tt_local_entry, tt_global_entry))
1821
if (tt_global_entry)
1822
tt_global_entry_free_ref(tt_global_entry);
1824
tt_local_entry_free_ref(tt_local_entry);
1828
void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
1829
const unsigned char *tt_buff, uint8_t tt_num_changes,
1830
uint8_t ttvn, uint16_t tt_crc)
1832
uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
1833
bool full_table = true;
1835
/* the ttvn increased by one -> we can apply the attached changes */
1836
if (ttvn - orig_ttvn == 1) {
1837
/* the OGM could not contain the changes due to their size or
1838
* because they have already been sent TT_OGM_APPEND_MAX times.
1839
* In this case send a tt request */
1840
if (!tt_num_changes) {
1845
tt_update_changes(bat_priv, orig_node, tt_num_changes, ttvn,
1846
(struct tt_change *)tt_buff);
1848
/* Even if we received the precomputed crc with the OGM, we
1849
* prefer to recompute it to spot any possible inconsistency
1850
* in the global table */
1851
orig_node->tt_crc = tt_global_crc(bat_priv, orig_node);
1853
/* The ttvn alone is not enough to guarantee consistency
1854
* because a single value could represent different states
1855
* (due to the wrap around). Thus a node has to check whether
1856
* the resulting table (after applying the changes) is still
1857
* consistent or not. E.g. a node could disconnect while its
1858
* ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case
1859
* checking the CRC value is mandatory to detect the
1861
if (orig_node->tt_crc != tt_crc)
1864
/* Roaming phase is over: tables are in sync again. I can
1866
orig_node->tt_poss_change = false;
1868
/* if we missed more than one change or our tables are not
1869
* in sync anymore -> request fresh tt data */
1870
if (ttvn != orig_ttvn || orig_node->tt_crc != tt_crc) {
1872
bat_dbg(DBG_TT, bat_priv, "TT inconsistency for %pM. "
1873
"Need to retrieve the correct information "
1874
"(ttvn: %u last_ttvn: %u crc: %u last_crc: "
1875
"%u num_changes: %u)\n", orig_node->orig, ttvn,
1876
orig_ttvn, tt_crc, orig_node->tt_crc,
1878
send_tt_request(bat_priv, orig_node, ttvn, tt_crc,