558
static void _tt_global_del_orig(struct bat_priv *bat_priv,
559
struct tt_global_entry *tt_global_entry,
673
static void _tt_global_del(struct bat_priv *bat_priv,
674
struct tt_global_entry *tt_global_entry,
562
bat_dbg(DBG_ROUTES, bat_priv,
677
if (!tt_global_entry)
680
bat_dbg(DBG_TT, bat_priv,
563
681
"Deleting global tt entry %pM (via %pM): %s\n",
564
682
tt_global_entry->addr, tt_global_entry->orig_node->orig,
685
atomic_dec(&tt_global_entry->orig_node->tt_size);
567
687
hash_remove(bat_priv->tt_global_hash, compare_gtt, choose_orig,
568
688
tt_global_entry->addr);
569
kfree(tt_global_entry);
691
tt_global_entry_free_ref(tt_global_entry);
694
void tt_global_del(struct bat_priv *bat_priv,
695
struct orig_node *orig_node, const unsigned char *addr,
696
const char *message, bool roaming)
698
struct tt_global_entry *tt_global_entry = NULL;
699
struct tt_local_entry *tt_local_entry = NULL;
701
tt_global_entry = tt_global_hash_find(bat_priv, addr);
702
if (!tt_global_entry)
705
if (tt_global_entry->orig_node == orig_node) {
707
/* if we are deleting a global entry due to a roam
708
* event, there are two possibilities:
709
* 1) the client roamed from node A to node B => we mark
710
* it with TT_CLIENT_ROAM, we start a timer and we
711
* wait for node B to claim it. In case of timeout
712
* the entry is purged.
713
* 2) the client roamed to us => we can directly delete
714
* the global entry, since it is useless now. */
715
tt_local_entry = tt_local_hash_find(bat_priv,
716
tt_global_entry->addr);
717
if (!tt_local_entry) {
718
tt_global_entry->flags |= TT_CLIENT_ROAM;
719
tt_global_entry->roam_at = jiffies;
723
_tt_global_del(bat_priv, tt_global_entry, message);
727
tt_global_entry_free_ref(tt_global_entry);
729
tt_local_entry_free_ref(tt_local_entry);
572
732
void tt_global_del_orig(struct bat_priv *bat_priv,
573
struct orig_node *orig_node, char *message)
733
struct orig_node *orig_node, const char *message)
575
735
struct tt_global_entry *tt_global_entry;
576
int tt_buff_count = 0;
577
unsigned char *tt_ptr;
737
struct hashtable_t *hash = bat_priv->tt_global_hash;
738
struct hlist_node *node, *safe;
739
struct hlist_head *head;
740
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)
745
for (i = 0; i < hash->size; i++) {
746
head = &hash->table[i];
747
list_lock = &hash->list_locks[i];
749
spin_lock_bh(list_lock);
750
hlist_for_each_entry_safe(tt_global_entry, node, safe,
752
if (tt_global_entry->orig_node == orig_node) {
753
bat_dbg(DBG_TT, bat_priv,
754
"Deleting global tt entry %pM "
755
"(via %pM): originator time out\n",
756
tt_global_entry->addr,
757
tt_global_entry->orig_node->orig);
759
tt_global_entry_free_ref(tt_global_entry);
762
spin_unlock_bh(list_lock);
764
atomic_set(&orig_node->tt_size, 0);
767
static void tt_global_roam_purge(struct bat_priv *bat_priv)
769
struct hashtable_t *hash = bat_priv->tt_global_hash;
770
struct tt_global_entry *tt_global_entry;
771
struct hlist_node *node, *node_tmp;
772
struct hlist_head *head;
773
spinlock_t *list_lock; /* protects write access to the hash lists */
776
for (i = 0; i < hash->size; i++) {
777
head = &hash->table[i];
778
list_lock = &hash->list_locks[i];
780
spin_lock_bh(list_lock);
781
hlist_for_each_entry_safe(tt_global_entry, node, node_tmp,
783
if (!(tt_global_entry->flags & TT_CLIENT_ROAM))
785
if (!is_out_of_time(tt_global_entry->roam_at,
786
TT_CLIENT_ROAM_TIMEOUT * 1000))
789
bat_dbg(DBG_TT, bat_priv, "Deleting global "
790
"tt entry (%pM): Roaming timeout\n",
791
tt_global_entry->addr);
792
atomic_dec(&tt_global_entry->orig_node->tt_size);
794
tt_global_entry_free_ref(tt_global_entry);
796
spin_unlock_bh(list_lock);
801
static void tt_global_table_free(struct bat_priv *bat_priv)
803
struct hashtable_t *hash;
804
spinlock_t *list_lock; /* protects write access to the hash lists */
805
struct tt_global_entry *tt_global_entry;
806
struct hlist_node *node, *node_tmp;
807
struct hlist_head *head;
612
810
if (!bat_priv->tt_global_hash)
615
hash_delete(bat_priv->tt_global_hash, tt_global_del, NULL);
813
hash = bat_priv->tt_global_hash;
815
for (i = 0; i < hash->size; i++) {
816
head = &hash->table[i];
817
list_lock = &hash->list_locks[i];
819
spin_lock_bh(list_lock);
820
hlist_for_each_entry_safe(tt_global_entry, node, node_tmp,
823
tt_global_entry_free_ref(tt_global_entry);
825
spin_unlock_bh(list_lock);
616
830
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;
833
static bool _is_ap_isolated(struct tt_local_entry *tt_local_entry,
834
struct tt_global_entry *tt_global_entry)
838
if (tt_local_entry->flags & TT_CLIENT_WIFI &&
839
tt_global_entry->flags & TT_CLIENT_WIFI)
845
struct orig_node *transtable_search(struct bat_priv *bat_priv,
846
const uint8_t *src, const uint8_t *addr)
848
struct tt_local_entry *tt_local_entry = NULL;
849
struct tt_global_entry *tt_global_entry = NULL;
622
850
struct orig_node *orig_node = NULL;
624
spin_lock_bh(&bat_priv->tt_ghash_lock);
852
if (src && atomic_read(&bat_priv->ap_isolation)) {
853
tt_local_entry = tt_local_hash_find(bat_priv, src);
625
858
tt_global_entry = tt_global_hash_find(bat_priv, addr);
627
859
if (!tt_global_entry)
862
/* check whether the clients should not communicate due to AP
864
if (tt_local_entry && _is_ap_isolated(tt_local_entry, tt_global_entry))
630
867
if (!atomic_inc_not_zero(&tt_global_entry->orig_node->refcount))
870
/* A global client marked as PENDING has already moved from that
872
if (tt_global_entry->flags & TT_CLIENT_PENDING)
633
875
orig_node = tt_global_entry->orig_node;
636
spin_unlock_bh(&bat_priv->tt_ghash_lock);
879
tt_global_entry_free_ref(tt_global_entry);
881
tt_local_entry_free_ref(tt_local_entry);
637
883
return orig_node;
886
/* Calculates the checksum of the local table of a given orig_node */
887
uint16_t tt_global_crc(struct bat_priv *bat_priv, struct orig_node *orig_node)
889
uint16_t total = 0, total_one;
890
struct hashtable_t *hash = bat_priv->tt_global_hash;
891
struct tt_global_entry *tt_global_entry;
892
struct hlist_node *node;
893
struct hlist_head *head;
896
for (i = 0; i < hash->size; i++) {
897
head = &hash->table[i];
900
hlist_for_each_entry_rcu(tt_global_entry, node,
902
if (compare_eth(tt_global_entry->orig_node,
904
/* Roaming clients are in the global table for
905
* consistency only. They don't have to be
906
* taken into account while computing the
908
if (tt_global_entry->flags & TT_CLIENT_ROAM)
911
for (j = 0; j < ETH_ALEN; j++)
912
total_one = crc16_byte(total_one,
913
tt_global_entry->addr[j]);
923
/* Calculates the checksum of the local table */
924
uint16_t tt_local_crc(struct bat_priv *bat_priv)
926
uint16_t total = 0, total_one;
927
struct hashtable_t *hash = bat_priv->tt_local_hash;
928
struct tt_local_entry *tt_local_entry;
929
struct hlist_node *node;
930
struct hlist_head *head;
933
for (i = 0; i < hash->size; i++) {
934
head = &hash->table[i];
937
hlist_for_each_entry_rcu(tt_local_entry, node,
939
/* not yet committed clients have not to be taken into
940
* account while computing the CRC */
941
if (tt_local_entry->flags & TT_CLIENT_NEW)
944
for (j = 0; j < ETH_ALEN; j++)
945
total_one = crc16_byte(total_one,
946
tt_local_entry->addr[j]);
955
static void tt_req_list_free(struct bat_priv *bat_priv)
957
struct tt_req_node *node, *safe;
959
spin_lock_bh(&bat_priv->tt_req_list_lock);
961
list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
962
list_del(&node->list);
966
spin_unlock_bh(&bat_priv->tt_req_list_lock);
969
void tt_save_orig_buffer(struct bat_priv *bat_priv, struct orig_node *orig_node,
970
const unsigned char *tt_buff, uint8_t tt_num_changes)
972
uint16_t tt_buff_len = tt_len(tt_num_changes);
974
/* Replace the old buffer only if I received something in the
975
* last OGM (the OGM could carry no changes) */
976
spin_lock_bh(&orig_node->tt_buff_lock);
977
if (tt_buff_len > 0) {
978
kfree(orig_node->tt_buff);
979
orig_node->tt_buff_len = 0;
980
orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC);
981
if (orig_node->tt_buff) {
982
memcpy(orig_node->tt_buff, tt_buff, tt_buff_len);
983
orig_node->tt_buff_len = tt_buff_len;
986
spin_unlock_bh(&orig_node->tt_buff_lock);
989
static void tt_req_purge(struct bat_priv *bat_priv)
991
struct tt_req_node *node, *safe;
993
spin_lock_bh(&bat_priv->tt_req_list_lock);
994
list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
995
if (is_out_of_time(node->issued_at,
996
TT_REQUEST_TIMEOUT * 1000)) {
997
list_del(&node->list);
1001
spin_unlock_bh(&bat_priv->tt_req_list_lock);
1004
/* returns the pointer to the new tt_req_node struct if no request
1005
* has already been issued for this orig_node, NULL otherwise */
1006
static struct tt_req_node *new_tt_req_node(struct bat_priv *bat_priv,
1007
struct orig_node *orig_node)
1009
struct tt_req_node *tt_req_node_tmp, *tt_req_node = NULL;
1011
spin_lock_bh(&bat_priv->tt_req_list_lock);
1012
list_for_each_entry(tt_req_node_tmp, &bat_priv->tt_req_list, list) {
1013
if (compare_eth(tt_req_node_tmp, orig_node) &&
1014
!is_out_of_time(tt_req_node_tmp->issued_at,
1015
TT_REQUEST_TIMEOUT * 1000))
1019
tt_req_node = kmalloc(sizeof(*tt_req_node), GFP_ATOMIC);
1023
memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN);
1024
tt_req_node->issued_at = jiffies;
1026
list_add(&tt_req_node->list, &bat_priv->tt_req_list);
1028
spin_unlock_bh(&bat_priv->tt_req_list_lock);
1032
/* data_ptr is useless here, but has to be kept to respect the prototype */
1033
static int tt_local_valid_entry(const void *entry_ptr, const void *data_ptr)
1035
const struct tt_local_entry *tt_local_entry = entry_ptr;
1037
if (tt_local_entry->flags & TT_CLIENT_NEW)
1042
static int tt_global_valid_entry(const void *entry_ptr, const void *data_ptr)
1044
const struct tt_global_entry *tt_global_entry = entry_ptr;
1045
const struct orig_node *orig_node = data_ptr;
1047
if (tt_global_entry->flags & TT_CLIENT_ROAM)
1050
return (tt_global_entry->orig_node == orig_node);
1053
static struct sk_buff *tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
1054
struct hashtable_t *hash,
1055
struct hard_iface *primary_if,
1056
int (*valid_cb)(const void *,
1060
struct tt_local_entry *tt_local_entry;
1061
struct tt_query_packet *tt_response;
1062
struct tt_change *tt_change;
1063
struct hlist_node *node;
1064
struct hlist_head *head;
1065
struct sk_buff *skb = NULL;
1066
uint16_t tt_tot, tt_count;
1067
ssize_t tt_query_size = sizeof(struct tt_query_packet);
1070
if (tt_query_size + tt_len > primary_if->soft_iface->mtu) {
1071
tt_len = primary_if->soft_iface->mtu - tt_query_size;
1072
tt_len -= tt_len % sizeof(struct tt_change);
1074
tt_tot = tt_len / sizeof(struct tt_change);
1076
skb = dev_alloc_skb(tt_query_size + tt_len + ETH_HLEN);
1080
skb_reserve(skb, ETH_HLEN);
1081
tt_response = (struct tt_query_packet *)skb_put(skb,
1082
tt_query_size + tt_len);
1083
tt_response->ttvn = ttvn;
1085
tt_change = (struct tt_change *)(skb->data + tt_query_size);
1089
for (i = 0; i < hash->size; i++) {
1090
head = &hash->table[i];
1092
hlist_for_each_entry_rcu(tt_local_entry, node,
1094
if (tt_count == tt_tot)
1097
if ((valid_cb) && (!valid_cb(tt_local_entry, cb_data)))
1100
memcpy(tt_change->addr, tt_local_entry->addr, ETH_ALEN);
1101
tt_change->flags = NO_FLAGS;
1109
/* store in the message the number of entries we have successfully
1111
tt_response->tt_data = htons(tt_count);
1117
static int send_tt_request(struct bat_priv *bat_priv,
1118
struct orig_node *dst_orig_node,
1119
uint8_t ttvn, uint16_t tt_crc, bool full_table)
1121
struct sk_buff *skb = NULL;
1122
struct tt_query_packet *tt_request;
1123
struct neigh_node *neigh_node = NULL;
1124
struct hard_iface *primary_if;
1125
struct tt_req_node *tt_req_node = NULL;
1128
primary_if = primary_if_get_selected(bat_priv);
1132
/* The new tt_req will be issued only if I'm not waiting for a
1133
* reply from the same orig_node yet */
1134
tt_req_node = new_tt_req_node(bat_priv, dst_orig_node);
1138
skb = dev_alloc_skb(sizeof(struct tt_query_packet) + ETH_HLEN);
1142
skb_reserve(skb, ETH_HLEN);
1144
tt_request = (struct tt_query_packet *)skb_put(skb,
1145
sizeof(struct tt_query_packet));
1147
tt_request->packet_type = BAT_TT_QUERY;
1148
tt_request->version = COMPAT_VERSION;
1149
memcpy(tt_request->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1150
memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN);
1151
tt_request->ttl = TTL;
1152
tt_request->ttvn = ttvn;
1153
tt_request->tt_data = tt_crc;
1154
tt_request->flags = TT_REQUEST;
1157
tt_request->flags |= TT_FULL_TABLE;
1159
neigh_node = orig_node_get_router(dst_orig_node);
1163
bat_dbg(DBG_TT, bat_priv, "Sending TT_REQUEST to %pM via %pM "
1164
"[%c]\n", dst_orig_node->orig, neigh_node->addr,
1165
(full_table ? 'F' : '.'));
1167
send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1172
neigh_node_free_ref(neigh_node);
1174
hardif_free_ref(primary_if);
1177
if (ret && tt_req_node) {
1178
spin_lock_bh(&bat_priv->tt_req_list_lock);
1179
list_del(&tt_req_node->list);
1180
spin_unlock_bh(&bat_priv->tt_req_list_lock);
1186
static bool send_other_tt_response(struct bat_priv *bat_priv,
1187
struct tt_query_packet *tt_request)
1189
struct orig_node *req_dst_orig_node = NULL, *res_dst_orig_node = NULL;
1190
struct neigh_node *neigh_node = NULL;
1191
struct hard_iface *primary_if = NULL;
1192
uint8_t orig_ttvn, req_ttvn, ttvn;
1194
unsigned char *tt_buff;
1196
uint16_t tt_len, tt_tot;
1197
struct sk_buff *skb = NULL;
1198
struct tt_query_packet *tt_response;
1200
bat_dbg(DBG_TT, bat_priv,
1201
"Received TT_REQUEST from %pM for "
1202
"ttvn: %u (%pM) [%c]\n", tt_request->src,
1203
tt_request->ttvn, tt_request->dst,
1204
(tt_request->flags & TT_FULL_TABLE ? 'F' : '.'));
1206
/* Let's get the orig node of the REAL destination */
1207
req_dst_orig_node = get_orig_node(bat_priv, tt_request->dst);
1208
if (!req_dst_orig_node)
1211
res_dst_orig_node = get_orig_node(bat_priv, tt_request->src);
1212
if (!res_dst_orig_node)
1215
neigh_node = orig_node_get_router(res_dst_orig_node);
1219
primary_if = primary_if_get_selected(bat_priv);
1223
orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
1224
req_ttvn = tt_request->ttvn;
1226
/* I don't have the requested data */
1227
if (orig_ttvn != req_ttvn ||
1228
tt_request->tt_data != req_dst_orig_node->tt_crc)
1231
/* If the full table has been explicitly requested */
1232
if (tt_request->flags & TT_FULL_TABLE ||
1233
!req_dst_orig_node->tt_buff)
1238
/* In this version, fragmentation is not implemented, then
1239
* I'll send only one packet with as much TT entries as I can */
1241
spin_lock_bh(&req_dst_orig_node->tt_buff_lock);
1242
tt_len = req_dst_orig_node->tt_buff_len;
1243
tt_tot = tt_len / sizeof(struct tt_change);
1245
skb = dev_alloc_skb(sizeof(struct tt_query_packet) +
1250
skb_reserve(skb, ETH_HLEN);
1251
tt_response = (struct tt_query_packet *)skb_put(skb,
1252
sizeof(struct tt_query_packet) + tt_len);
1253
tt_response->ttvn = req_ttvn;
1254
tt_response->tt_data = htons(tt_tot);
1256
tt_buff = skb->data + sizeof(struct tt_query_packet);
1257
/* Copy the last orig_node's OGM buffer */
1258
memcpy(tt_buff, req_dst_orig_node->tt_buff,
1259
req_dst_orig_node->tt_buff_len);
1261
spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
1263
tt_len = (uint16_t)atomic_read(&req_dst_orig_node->tt_size) *
1264
sizeof(struct tt_change);
1265
ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
1267
skb = tt_response_fill_table(tt_len, ttvn,
1268
bat_priv->tt_global_hash,
1269
primary_if, tt_global_valid_entry,
1274
tt_response = (struct tt_query_packet *)skb->data;
1277
tt_response->packet_type = BAT_TT_QUERY;
1278
tt_response->version = COMPAT_VERSION;
1279
tt_response->ttl = TTL;
1280
memcpy(tt_response->src, req_dst_orig_node->orig, ETH_ALEN);
1281
memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
1282
tt_response->flags = TT_RESPONSE;
1285
tt_response->flags |= TT_FULL_TABLE;
1287
bat_dbg(DBG_TT, bat_priv,
1288
"Sending TT_RESPONSE %pM via %pM for %pM (ttvn: %u)\n",
1289
res_dst_orig_node->orig, neigh_node->addr,
1290
req_dst_orig_node->orig, req_ttvn);
1292
send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1297
spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
1300
if (res_dst_orig_node)
1301
orig_node_free_ref(res_dst_orig_node);
1302
if (req_dst_orig_node)
1303
orig_node_free_ref(req_dst_orig_node);
1305
neigh_node_free_ref(neigh_node);
1307
hardif_free_ref(primary_if);
1313
static bool send_my_tt_response(struct bat_priv *bat_priv,
1314
struct tt_query_packet *tt_request)
1316
struct orig_node *orig_node = NULL;
1317
struct neigh_node *neigh_node = NULL;
1318
struct hard_iface *primary_if = NULL;
1319
uint8_t my_ttvn, req_ttvn, ttvn;
1321
unsigned char *tt_buff;
1323
uint16_t tt_len, tt_tot;
1324
struct sk_buff *skb = NULL;
1325
struct tt_query_packet *tt_response;
1327
bat_dbg(DBG_TT, bat_priv,
1328
"Received TT_REQUEST from %pM for "
1329
"ttvn: %u (me) [%c]\n", tt_request->src,
1331
(tt_request->flags & TT_FULL_TABLE ? 'F' : '.'));
1334
my_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn);
1335
req_ttvn = tt_request->ttvn;
1337
orig_node = get_orig_node(bat_priv, tt_request->src);
1341
neigh_node = orig_node_get_router(orig_node);
1345
primary_if = primary_if_get_selected(bat_priv);
1349
/* If the full table has been explicitly requested or the gap
1350
* is too big send the whole local translation table */
1351
if (tt_request->flags & TT_FULL_TABLE || my_ttvn != req_ttvn ||
1357
/* In this version, fragmentation is not implemented, then
1358
* I'll send only one packet with as much TT entries as I can */
1360
spin_lock_bh(&bat_priv->tt_buff_lock);
1361
tt_len = bat_priv->tt_buff_len;
1362
tt_tot = tt_len / sizeof(struct tt_change);
1364
skb = dev_alloc_skb(sizeof(struct tt_query_packet) +
1369
skb_reserve(skb, ETH_HLEN);
1370
tt_response = (struct tt_query_packet *)skb_put(skb,
1371
sizeof(struct tt_query_packet) + tt_len);
1372
tt_response->ttvn = req_ttvn;
1373
tt_response->tt_data = htons(tt_tot);
1375
tt_buff = skb->data + sizeof(struct tt_query_packet);
1376
memcpy(tt_buff, bat_priv->tt_buff,
1377
bat_priv->tt_buff_len);
1378
spin_unlock_bh(&bat_priv->tt_buff_lock);
1380
tt_len = (uint16_t)atomic_read(&bat_priv->num_local_tt) *
1381
sizeof(struct tt_change);
1382
ttvn = (uint8_t)atomic_read(&bat_priv->ttvn);
1384
skb = tt_response_fill_table(tt_len, ttvn,
1385
bat_priv->tt_local_hash,
1386
primary_if, tt_local_valid_entry,
1391
tt_response = (struct tt_query_packet *)skb->data;
1394
tt_response->packet_type = BAT_TT_QUERY;
1395
tt_response->version = COMPAT_VERSION;
1396
tt_response->ttl = TTL;
1397
memcpy(tt_response->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1398
memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
1399
tt_response->flags = TT_RESPONSE;
1402
tt_response->flags |= TT_FULL_TABLE;
1404
bat_dbg(DBG_TT, bat_priv,
1405
"Sending TT_RESPONSE to %pM via %pM [%c]\n",
1406
orig_node->orig, neigh_node->addr,
1407
(tt_response->flags & TT_FULL_TABLE ? 'F' : '.'));
1409
send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1414
spin_unlock_bh(&bat_priv->tt_buff_lock);
1417
orig_node_free_ref(orig_node);
1419
neigh_node_free_ref(neigh_node);
1421
hardif_free_ref(primary_if);
1424
/* This packet was for me, so it doesn't need to be re-routed */
1428
bool send_tt_response(struct bat_priv *bat_priv,
1429
struct tt_query_packet *tt_request)
1431
if (is_my_mac(tt_request->dst))
1432
return send_my_tt_response(bat_priv, tt_request);
1434
return send_other_tt_response(bat_priv, tt_request);
1437
static void _tt_update_changes(struct bat_priv *bat_priv,
1438
struct orig_node *orig_node,
1439
struct tt_change *tt_change,
1440
uint16_t tt_num_changes, uint8_t ttvn)
1444
for (i = 0; i < tt_num_changes; i++) {
1445
if ((tt_change + i)->flags & TT_CLIENT_DEL)
1446
tt_global_del(bat_priv, orig_node,
1447
(tt_change + i)->addr,
1448
"tt removed by changes",
1449
(tt_change + i)->flags & TT_CLIENT_ROAM);
1451
if (!tt_global_add(bat_priv, orig_node,
1452
(tt_change + i)->addr, ttvn, false,
1453
(tt_change + i)->flags &
1455
/* In case of problem while storing a
1456
* global_entry, we stop the updating
1457
* procedure without committing the
1458
* ttvn change. This will avoid to send
1459
* corrupted data on tt_request
1465
static void tt_fill_gtable(struct bat_priv *bat_priv,
1466
struct tt_query_packet *tt_response)
1468
struct orig_node *orig_node = NULL;
1470
orig_node = orig_hash_find(bat_priv, tt_response->src);
1474
/* Purge the old table first.. */
1475
tt_global_del_orig(bat_priv, orig_node, "Received full table");
1477
_tt_update_changes(bat_priv, orig_node,
1478
(struct tt_change *)(tt_response + 1),
1479
tt_response->tt_data, tt_response->ttvn);
1481
spin_lock_bh(&orig_node->tt_buff_lock);
1482
kfree(orig_node->tt_buff);
1483
orig_node->tt_buff_len = 0;
1484
orig_node->tt_buff = NULL;
1485
spin_unlock_bh(&orig_node->tt_buff_lock);
1487
atomic_set(&orig_node->last_ttvn, tt_response->ttvn);
1491
orig_node_free_ref(orig_node);
1494
static void tt_update_changes(struct bat_priv *bat_priv,
1495
struct orig_node *orig_node,
1496
uint16_t tt_num_changes, uint8_t ttvn,
1497
struct tt_change *tt_change)
1499
_tt_update_changes(bat_priv, orig_node, tt_change, tt_num_changes,
1502
tt_save_orig_buffer(bat_priv, orig_node, (unsigned char *)tt_change,
1504
atomic_set(&orig_node->last_ttvn, ttvn);
1507
bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr)
1509
struct tt_local_entry *tt_local_entry = NULL;
1512
tt_local_entry = tt_local_hash_find(bat_priv, addr);
1513
if (!tt_local_entry)
1515
/* Check if the client has been logically deleted (but is kept for
1516
* consistency purpose) */
1517
if (tt_local_entry->flags & TT_CLIENT_PENDING)
1522
tt_local_entry_free_ref(tt_local_entry);
1526
void handle_tt_response(struct bat_priv *bat_priv,
1527
struct tt_query_packet *tt_response)
1529
struct tt_req_node *node, *safe;
1530
struct orig_node *orig_node = NULL;
1532
bat_dbg(DBG_TT, bat_priv, "Received TT_RESPONSE from %pM for "
1533
"ttvn %d t_size: %d [%c]\n",
1534
tt_response->src, tt_response->ttvn,
1535
tt_response->tt_data,
1536
(tt_response->flags & TT_FULL_TABLE ? 'F' : '.'));
1538
orig_node = orig_hash_find(bat_priv, tt_response->src);
1542
if (tt_response->flags & TT_FULL_TABLE)
1543
tt_fill_gtable(bat_priv, tt_response);
1545
tt_update_changes(bat_priv, orig_node, tt_response->tt_data,
1547
(struct tt_change *)(tt_response + 1));
1549
/* Delete the tt_req_node from pending tt_requests list */
1550
spin_lock_bh(&bat_priv->tt_req_list_lock);
1551
list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
1552
if (!compare_eth(node->addr, tt_response->src))
1554
list_del(&node->list);
1557
spin_unlock_bh(&bat_priv->tt_req_list_lock);
1559
/* Recalculate the CRC for this orig_node and store it */
1560
orig_node->tt_crc = tt_global_crc(bat_priv, orig_node);
1561
/* Roaming phase is over: tables are in sync again. I can
1563
orig_node->tt_poss_change = false;
1566
orig_node_free_ref(orig_node);
1569
int tt_init(struct bat_priv *bat_priv)
1571
if (!tt_local_init(bat_priv))
1574
if (!tt_global_init(bat_priv))
1577
tt_start_timer(bat_priv);
1582
static void tt_roam_list_free(struct bat_priv *bat_priv)
1584
struct tt_roam_node *node, *safe;
1586
spin_lock_bh(&bat_priv->tt_roam_list_lock);
1588
list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) {
1589
list_del(&node->list);
1593
spin_unlock_bh(&bat_priv->tt_roam_list_lock);
1596
static void tt_roam_purge(struct bat_priv *bat_priv)
1598
struct tt_roam_node *node, *safe;
1600
spin_lock_bh(&bat_priv->tt_roam_list_lock);
1601
list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) {
1602
if (!is_out_of_time(node->first_time,
1603
ROAMING_MAX_TIME * 1000))
1606
list_del(&node->list);
1609
spin_unlock_bh(&bat_priv->tt_roam_list_lock);
1612
/* This function checks whether the client already reached the
1613
* maximum number of possible roaming phases. In this case the ROAMING_ADV
1616
* returns true if the ROAMING_ADV can be sent, false otherwise */
1617
static bool tt_check_roam_count(struct bat_priv *bat_priv,
1620
struct tt_roam_node *tt_roam_node;
1623
spin_lock_bh(&bat_priv->tt_roam_list_lock);
1624
/* The new tt_req will be issued only if I'm not waiting for a
1625
* reply from the same orig_node yet */
1626
list_for_each_entry(tt_roam_node, &bat_priv->tt_roam_list, list) {
1627
if (!compare_eth(tt_roam_node->addr, client))
1630
if (is_out_of_time(tt_roam_node->first_time,
1631
ROAMING_MAX_TIME * 1000))
1634
if (!atomic_dec_not_zero(&tt_roam_node->counter))
1635
/* Sorry, you roamed too many times! */
1642
tt_roam_node = kmalloc(sizeof(*tt_roam_node), GFP_ATOMIC);
1646
tt_roam_node->first_time = jiffies;
1647
atomic_set(&tt_roam_node->counter, ROAMING_MAX_COUNT - 1);
1648
memcpy(tt_roam_node->addr, client, ETH_ALEN);
1650
list_add(&tt_roam_node->list, &bat_priv->tt_roam_list);
1655
spin_unlock_bh(&bat_priv->tt_roam_list_lock);
1659
void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client,
1660
struct orig_node *orig_node)
1662
struct neigh_node *neigh_node = NULL;
1663
struct sk_buff *skb = NULL;
1664
struct roam_adv_packet *roam_adv_packet;
1666
struct hard_iface *primary_if;
1668
/* before going on we have to check whether the client has
1669
* already roamed to us too many times */
1670
if (!tt_check_roam_count(bat_priv, client))
1673
skb = dev_alloc_skb(sizeof(struct roam_adv_packet) + ETH_HLEN);
1677
skb_reserve(skb, ETH_HLEN);
1679
roam_adv_packet = (struct roam_adv_packet *)skb_put(skb,
1680
sizeof(struct roam_adv_packet));
1682
roam_adv_packet->packet_type = BAT_ROAM_ADV;
1683
roam_adv_packet->version = COMPAT_VERSION;
1684
roam_adv_packet->ttl = TTL;
1685
primary_if = primary_if_get_selected(bat_priv);
1688
memcpy(roam_adv_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1689
hardif_free_ref(primary_if);
1690
memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN);
1691
memcpy(roam_adv_packet->client, client, ETH_ALEN);
1693
neigh_node = orig_node_get_router(orig_node);
1697
bat_dbg(DBG_TT, bat_priv,
1698
"Sending ROAMING_ADV to %pM (client %pM) via %pM\n",
1699
orig_node->orig, client, neigh_node->addr);
1701
send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1706
neigh_node_free_ref(neigh_node);
1712
static void tt_purge(struct work_struct *work)
1714
struct delayed_work *delayed_work =
1715
container_of(work, struct delayed_work, work);
1716
struct bat_priv *bat_priv =
1717
container_of(delayed_work, struct bat_priv, tt_work);
1719
tt_local_purge(bat_priv);
1720
tt_global_roam_purge(bat_priv);
1721
tt_req_purge(bat_priv);
1722
tt_roam_purge(bat_priv);
1724
tt_start_timer(bat_priv);
1727
void tt_free(struct bat_priv *bat_priv)
1729
cancel_delayed_work_sync(&bat_priv->tt_work);
1731
tt_local_table_free(bat_priv);
1732
tt_global_table_free(bat_priv);
1733
tt_req_list_free(bat_priv);
1734
tt_changes_list_free(bat_priv);
1735
tt_roam_list_free(bat_priv);
1737
kfree(bat_priv->tt_buff);
1740
/* This function will reset the specified flags from all the entries in
1741
* the given hash table and will increment num_local_tt for each involved
1743
static void tt_local_reset_flags(struct bat_priv *bat_priv, uint16_t flags)
1746
struct hashtable_t *hash = bat_priv->tt_local_hash;
1747
struct hlist_head *head;
1748
struct hlist_node *node;
1749
struct tt_local_entry *tt_local_entry;
1754
for (i = 0; i < hash->size; i++) {
1755
head = &hash->table[i];
1758
hlist_for_each_entry_rcu(tt_local_entry, node,
1760
if (!(tt_local_entry->flags & flags))
1762
tt_local_entry->flags &= ~flags;
1763
atomic_inc(&bat_priv->num_local_tt);
1770
/* Purge out all the tt local entries marked with TT_CLIENT_PENDING */
1771
static void tt_local_purge_pending_clients(struct bat_priv *bat_priv)
1773
struct hashtable_t *hash = bat_priv->tt_local_hash;
1774
struct tt_local_entry *tt_local_entry;
1775
struct hlist_node *node, *node_tmp;
1776
struct hlist_head *head;
1777
spinlock_t *list_lock; /* protects write access to the hash lists */
1783
for (i = 0; i < hash->size; i++) {
1784
head = &hash->table[i];
1785
list_lock = &hash->list_locks[i];
1787
spin_lock_bh(list_lock);
1788
hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
1790
if (!(tt_local_entry->flags & TT_CLIENT_PENDING))
1793
bat_dbg(DBG_TT, bat_priv, "Deleting local tt entry "
1794
"(%pM): pending\n", tt_local_entry->addr);
1796
atomic_dec(&bat_priv->num_local_tt);
1797
hlist_del_rcu(node);
1798
tt_local_entry_free_ref(tt_local_entry);
1800
spin_unlock_bh(list_lock);
1805
void tt_commit_changes(struct bat_priv *bat_priv)
1807
tt_local_reset_flags(bat_priv, TT_CLIENT_NEW);
1808
tt_local_purge_pending_clients(bat_priv);
1810
/* Increment the TTVN only once per OGM interval */
1811
atomic_inc(&bat_priv->ttvn);
1812
bat_priv->tt_poss_change = false;
1815
bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst)
1817
struct tt_local_entry *tt_local_entry = NULL;
1818
struct tt_global_entry *tt_global_entry = NULL;
1821
if (!atomic_read(&bat_priv->ap_isolation))
1824
tt_local_entry = tt_local_hash_find(bat_priv, dst);
1825
if (!tt_local_entry)
1828
tt_global_entry = tt_global_hash_find(bat_priv, src);
1829
if (!tt_global_entry)
1832
if (_is_ap_isolated(tt_local_entry, tt_global_entry))
1838
if (tt_global_entry)
1839
tt_global_entry_free_ref(tt_global_entry);
1841
tt_local_entry_free_ref(tt_local_entry);
1845
void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
1846
const unsigned char *tt_buff, uint8_t tt_num_changes,
1847
uint8_t ttvn, uint16_t tt_crc)
1849
uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
1850
bool full_table = true;
1852
/* the ttvn increased by one -> we can apply the attached changes */
1853
if (ttvn - orig_ttvn == 1) {
1854
/* the OGM could not contain the changes due to their size or
1855
* because they have already been sent TT_OGM_APPEND_MAX times.
1856
* In this case send a tt request */
1857
if (!tt_num_changes) {
1862
tt_update_changes(bat_priv, orig_node, tt_num_changes, ttvn,
1863
(struct tt_change *)tt_buff);
1865
/* Even if we received the precomputed crc with the OGM, we
1866
* prefer to recompute it to spot any possible inconsistency
1867
* in the global table */
1868
orig_node->tt_crc = tt_global_crc(bat_priv, orig_node);
1870
/* The ttvn alone is not enough to guarantee consistency
1871
* because a single value could represent different states
1872
* (due to the wrap around). Thus a node has to check whether
1873
* the resulting table (after applying the changes) is still
1874
* consistent or not. E.g. a node could disconnect while its
1875
* ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case
1876
* checking the CRC value is mandatory to detect the
1878
if (orig_node->tt_crc != tt_crc)
1881
/* Roaming phase is over: tables are in sync again. I can
1883
orig_node->tt_poss_change = false;
1885
/* if we missed more than one change or our tables are not
1886
* in sync anymore -> request fresh tt data */
1887
if (ttvn != orig_ttvn || orig_node->tt_crc != tt_crc) {
1889
bat_dbg(DBG_TT, bat_priv, "TT inconsistency for %pM. "
1890
"Need to retrieve the correct information "
1891
"(ttvn: %u last_ttvn: %u crc: %u last_crc: "
1892
"%u num_changes: %u)\n", orig_node->orig, ttvn,
1893
orig_ttvn, tt_crc, orig_node->tt_crc,
1895
send_tt_request(bat_priv, orig_node, ttvn, tt_crc,