aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/batman-adv/bat_iv_ogm.c44
-rw-r--r--net/batman-adv/packet.h51
-rw-r--r--net/batman-adv/translation-table.c240
-rw-r--r--net/batman-adv/translation-table.h8
-rw-r--r--net/batman-adv/types.h2
5 files changed, 187 insertions, 158 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index f0f02d1a10d7..871ba672bdc2 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -137,8 +137,6 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
137 batadv_ogm_packet->flags = BATADV_NO_FLAGS; 137 batadv_ogm_packet->flags = BATADV_NO_FLAGS;
138 batadv_ogm_packet->reserved = 0; 138 batadv_ogm_packet->reserved = 0;
139 batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE; 139 batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
140 batadv_ogm_packet->tt_num_changes = 0;
141 batadv_ogm_packet->ttvn = 0;
142 140
143 res = 0; 141 res = 0;
144 142
@@ -257,14 +255,14 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
257 fwd_str = "Sending own"; 255 fwd_str = "Sending own";
258 256
259 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 257 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
260 "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s, ttvn %d) on interface %s [%pM]\n", 258 "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s) on interface %s [%pM]\n",
261 fwd_str, (packet_num > 0 ? "aggregated " : ""), 259 fwd_str, (packet_num > 0 ? "aggregated " : ""),
262 batadv_ogm_packet->orig, 260 batadv_ogm_packet->orig,
263 ntohl(batadv_ogm_packet->seqno), 261 ntohl(batadv_ogm_packet->seqno),
264 batadv_ogm_packet->tq, batadv_ogm_packet->header.ttl, 262 batadv_ogm_packet->tq, batadv_ogm_packet->header.ttl,
265 (batadv_ogm_packet->flags & BATADV_DIRECTLINK ? 263 (batadv_ogm_packet->flags & BATADV_DIRECTLINK ?
266 "on" : "off"), 264 "on" : "off"),
267 batadv_ogm_packet->ttvn, hard_iface->net_dev->name, 265 hard_iface->net_dev->name,
268 hard_iface->net_dev->dev_addr); 266 hard_iface->net_dev->dev_addr);
269 267
270 buff_pos += BATADV_OGM_HLEN; 268 buff_pos += BATADV_OGM_HLEN;
@@ -689,17 +687,22 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
689 struct batadv_ogm_packet *batadv_ogm_packet; 687 struct batadv_ogm_packet *batadv_ogm_packet;
690 struct batadv_hard_iface *primary_if; 688 struct batadv_hard_iface *primary_if;
691 int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len; 689 int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
692 int vis_server, tt_num_changes = 0; 690 int vis_server;
693 uint32_t seqno; 691 uint32_t seqno;
694 uint16_t tvlv_len = 0; 692 uint16_t tvlv_len = 0;
695 693
696 vis_server = atomic_read(&bat_priv->vis_mode); 694 vis_server = atomic_read(&bat_priv->vis_mode);
697 primary_if = batadv_primary_if_get_selected(bat_priv); 695 primary_if = batadv_primary_if_get_selected(bat_priv);
698 696
699 if (hard_iface == primary_if) 697 if (hard_iface == primary_if) {
698 /* tt changes have to be committed before the tvlv data is
699 * appended as it may alter the tt tvlv container
700 */
701 batadv_tt_local_commit_changes(bat_priv);
700 tvlv_len = batadv_tvlv_container_ogm_append(bat_priv, ogm_buff, 702 tvlv_len = batadv_tvlv_container_ogm_append(bat_priv, ogm_buff,
701 ogm_buff_len, 703 ogm_buff_len,
702 BATADV_OGM_HLEN); 704 BATADV_OGM_HLEN);
705 }
703 706
704 batadv_ogm_packet = (struct batadv_ogm_packet *)(*ogm_buff); 707 batadv_ogm_packet = (struct batadv_ogm_packet *)(*ogm_buff);
705 batadv_ogm_packet->tvlv_len = htons(tvlv_len); 708 batadv_ogm_packet->tvlv_len = htons(tvlv_len);
@@ -709,11 +712,6 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
709 batadv_ogm_packet->seqno = htonl(seqno); 712 batadv_ogm_packet->seqno = htonl(seqno);
710 atomic_inc(&hard_iface->bat_iv.ogm_seqno); 713 atomic_inc(&hard_iface->bat_iv.ogm_seqno);
711 714
712 batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn);
713 batadv_ogm_packet->tt_crc = htons(bat_priv->tt.local_crc);
714 if (tt_num_changes >= 0)
715 batadv_ogm_packet->tt_num_changes = tt_num_changes;
716
717 if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC) 715 if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC)
718 batadv_ogm_packet->flags |= BATADV_VIS_SERVER; 716 batadv_ogm_packet->flags |= BATADV_VIS_SERVER;
719 else 717 else
@@ -814,11 +812,11 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
814 */ 812 */
815 router = batadv_orig_node_get_router(orig_node); 813 router = batadv_orig_node_get_router(orig_node);
816 if (router == neigh_node) 814 if (router == neigh_node)
817 goto update_tt; 815 goto out;
818 816
819 /* if this neighbor does not offer a better TQ we won't consider it */ 817 /* if this neighbor does not offer a better TQ we won't consider it */
820 if (router && (router->tq_avg > neigh_node->tq_avg)) 818 if (router && (router->tq_avg > neigh_node->tq_avg))
821 goto update_tt; 819 goto out;
822 820
823 /* if the TQ is the same and the link not more symmetric we 821 /* if the TQ is the same and the link not more symmetric we
824 * won't consider it either 822 * won't consider it either
@@ -837,22 +835,10 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
837 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); 835 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
838 836
839 if (sum_orig >= sum_neigh) 837 if (sum_orig >= sum_neigh)
840 goto update_tt; 838 goto out;
841 } 839 }
842 840
843 batadv_update_route(bat_priv, orig_node, neigh_node); 841 batadv_update_route(bat_priv, orig_node, neigh_node);
844
845update_tt:
846 /* I have to check for transtable changes only if the OGM has been
847 * sent through a primary interface
848 */
849 if (((batadv_ogm_packet->orig != ethhdr->h_source) &&
850 (batadv_ogm_packet->header.ttl > 2)) ||
851 (batadv_ogm_packet->flags & BATADV_PRIMARIES_FIRST_HOP))
852 batadv_tt_update_orig(bat_priv, orig_node, tt_buff,
853 batadv_ogm_packet->tt_num_changes,
854 batadv_ogm_packet->ttvn,
855 ntohs(batadv_ogm_packet->tt_crc));
856 goto out; 842 goto out;
857 843
858unlock: 844unlock:
@@ -1103,13 +1089,11 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1103 is_single_hop_neigh = true; 1089 is_single_hop_neigh = true;
1104 1090
1105 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 1091 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1106 "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, ttvn %u, crc %#.4x, changes %u, tq %d, TTL %d, V %d, IDF %d)\n", 1092 "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, tq %d, TTL %d, V %d, IDF %d)\n",
1107 ethhdr->h_source, if_incoming->net_dev->name, 1093 ethhdr->h_source, if_incoming->net_dev->name,
1108 if_incoming->net_dev->dev_addr, batadv_ogm_packet->orig, 1094 if_incoming->net_dev->dev_addr, batadv_ogm_packet->orig,
1109 batadv_ogm_packet->prev_sender, 1095 batadv_ogm_packet->prev_sender,
1110 ntohl(batadv_ogm_packet->seqno), batadv_ogm_packet->ttvn, 1096 ntohl(batadv_ogm_packet->seqno), batadv_ogm_packet->tq,
1111 ntohs(batadv_ogm_packet->tt_crc),
1112 batadv_ogm_packet->tt_num_changes, batadv_ogm_packet->tq,
1113 batadv_ogm_packet->header.ttl, 1097 batadv_ogm_packet->header.ttl,
1114 batadv_ogm_packet->header.version, has_directlink_flag); 1098 batadv_ogm_packet->header.version, has_directlink_flag);
1115 1099
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 55deb4dea842..cd59fcc9b79a 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -86,14 +86,21 @@ enum batadv_unicast_frag_flags {
86/* TT_QUERY subtypes */ 86/* TT_QUERY subtypes */
87#define BATADV_TT_QUERY_TYPE_MASK 0x3 87#define BATADV_TT_QUERY_TYPE_MASK 0x3
88 88
89enum batadv_tt_query_packettype { 89/* tt data subtypes */
90 BATADV_TT_REQUEST = 0, 90#define BATADV_TT_DATA_TYPE_MASK 0x0F
91 BATADV_TT_RESPONSE = 1,
92};
93 91
94/* TT_QUERY flags */ 92/**
95enum batadv_tt_query_flags { 93 * enum batadv_tt_data_flags - flags for tt data tvlv
96 BATADV_TT_FULL_TABLE = BIT(2), 94 * @BATADV_TT_OGM_DIFF: TT diff propagated through OGM
95 * @BATADV_TT_REQUEST: TT request message
96 * @BATADV_TT_RESPONSE: TT response message
97 * @BATADV_TT_FULL_TABLE: contains full table to replace existing table
98 */
99enum batadv_tt_data_flags {
100 BATADV_TT_OGM_DIFF = BIT(0),
101 BATADV_TT_REQUEST = BIT(1),
102 BATADV_TT_RESPONSE = BIT(2),
103 BATADV_TT_FULL_TABLE = BIT(4),
97}; 104};
98 105
99/* BATADV_TT_CLIENT flags. 106/* BATADV_TT_CLIENT flags.
@@ -123,11 +130,13 @@ enum batadv_bla_claimframe {
123 * @BATADV_TVLV_GW: gateway tvlv 130 * @BATADV_TVLV_GW: gateway tvlv
124 * @BATADV_TVLV_DAT: distributed arp table tvlv 131 * @BATADV_TVLV_DAT: distributed arp table tvlv
125 * @BATADV_TVLV_NC: network coding tvlv 132 * @BATADV_TVLV_NC: network coding tvlv
133 * @BATADV_TVLV_TT: translation table tvlv
126 */ 134 */
127enum batadv_tvlv_type { 135enum batadv_tvlv_type {
128 BATADV_TVLV_GW = 0x01, 136 BATADV_TVLV_GW = 0x01,
129 BATADV_TVLV_DAT = 0x02, 137 BATADV_TVLV_DAT = 0x02,
130 BATADV_TVLV_NC = 0x03, 138 BATADV_TVLV_NC = 0x03,
139 BATADV_TVLV_TT = 0x04,
131}; 140};
132 141
133/* the destination hardware field in the ARP frame is used to 142/* the destination hardware field in the ARP frame is used to
@@ -161,9 +170,6 @@ struct batadv_ogm_packet {
161 uint8_t prev_sender[ETH_ALEN]; 170 uint8_t prev_sender[ETH_ALEN];
162 uint8_t reserved; 171 uint8_t reserved;
163 uint8_t tq; 172 uint8_t tq;
164 uint8_t tt_num_changes;
165 uint8_t ttvn; /* translation table version number */
166 __be16 tt_crc;
167 __be16 tvlv_len; 173 __be16 tvlv_len;
168} __packed; 174} __packed;
169 175
@@ -375,4 +381,29 @@ struct batadv_tvlv_gateway_data {
375 __be32 bandwidth_up; 381 __be32 bandwidth_up;
376}; 382};
377 383
384/**
385 * struct batadv_tvlv_tt_data - tt data propagated through the tt tvlv container
386 * @flags: translation table flags (see batadv_tt_data_flags)
387 * @ttvn: translation table version number
388 * @crc: crc16 checksum of the local translation table
389 */
390struct batadv_tvlv_tt_data {
391 uint8_t flags;
392 uint8_t ttvn;
393 __be16 crc;
394};
395
396/**
397 * struct batadv_tvlv_tt_change - translation table diff data
398 * @flags: status indicators concerning the non-mesh client (see
399 * batadv_tt_client_flags)
400 * @reserved: reserved field
401 * @addr: mac address of non-mesh client that triggered this tt change
402 */
403struct batadv_tvlv_tt_change {
404 uint8_t flags;
405 uint8_t reserved;
406 uint8_t addr[ETH_ALEN];
407};
408
378#endif /* _NET_BATMAN_ADV_PACKET_H_ */ 409#endif /* _NET_BATMAN_ADV_PACKET_H_ */
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 34510f38708f..3fac67ffd524 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -180,11 +180,11 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
180 bool del_op_requested, del_op_entry; 180 bool del_op_requested, del_op_entry;
181 181
182 tt_change_node = kmalloc(sizeof(*tt_change_node), GFP_ATOMIC); 182 tt_change_node = kmalloc(sizeof(*tt_change_node), GFP_ATOMIC);
183
184 if (!tt_change_node) 183 if (!tt_change_node)
185 return; 184 return;
186 185
187 tt_change_node->change.flags = flags; 186 tt_change_node->change.flags = flags;
187 tt_change_node->change.reserved = 0;
188 memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN); 188 memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN);
189 189
190 del_op_requested = flags & BATADV_TT_CLIENT_DEL; 190 del_op_requested = flags & BATADV_TT_CLIENT_DEL;
@@ -376,71 +376,52 @@ out:
376 batadv_tt_global_entry_free_ref(tt_global); 376 batadv_tt_global_entry_free_ref(tt_global);
377} 377}
378 378
379static void batadv_tt_realloc_packet_buff(unsigned char **packet_buff, 379/**
380 int *packet_buff_len, 380 * batadv_tt_tvlv_container_update - update the translation table tvlv container
381 int min_packet_len, 381 * after local tt changes have been committed
382 int new_packet_len) 382 * @bat_priv: the bat priv with all the soft interface information
383{ 383 */
384 unsigned char *new_buff; 384static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
385
386 new_buff = kmalloc(new_packet_len, GFP_ATOMIC);
387
388 /* keep old buffer if kmalloc should fail */
389 if (new_buff) {
390 memcpy(new_buff, *packet_buff, min_packet_len);
391 kfree(*packet_buff);
392 *packet_buff = new_buff;
393 *packet_buff_len = new_packet_len;
394 }
395}
396
397static void batadv_tt_prepare_packet_buff(struct batadv_priv *bat_priv,
398 unsigned char **packet_buff,
399 int *packet_buff_len,
400 int min_packet_len)
401{ 385{
402 int req_len; 386 struct batadv_tt_change_node *entry, *safe;
387 struct batadv_tvlv_tt_data *tt_data;
388 struct batadv_tvlv_tt_change *tt_change;
389 int tt_diff_len = 0, tt_change_len = 0;
390 int tt_diff_entries_num = 0, tt_diff_entries_count = 0;
403 391
404 req_len = min_packet_len; 392 tt_diff_len += batadv_tt_len(atomic_read(&bat_priv->tt.local_changes));
405 req_len += batadv_tt_len(atomic_read(&bat_priv->tt.local_changes));
406 393
407 /* if we have too many changes for one packet don't send any 394 /* if we have too many changes for one packet don't send any
408 * and wait for the tt table request which will be fragmented 395 * and wait for the tt table request which will be fragmented
409 */ 396 */
410 if (req_len > bat_priv->soft_iface->mtu) 397 if (tt_diff_len > bat_priv->soft_iface->mtu)
411 req_len = min_packet_len; 398 tt_diff_len = 0;
412 399
413 batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len, 400 tt_data = kzalloc(sizeof(*tt_data) + tt_diff_len, GFP_ATOMIC);
414 min_packet_len, req_len); 401 if (!tt_data)
415} 402 return;
416
417static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv,
418 unsigned char **packet_buff,
419 int *packet_buff_len,
420 int min_packet_len)
421{
422 struct batadv_tt_change_node *entry, *safe;
423 int count = 0, tot_changes = 0, new_len;
424 unsigned char *tt_buff;
425 403
426 batadv_tt_prepare_packet_buff(bat_priv, packet_buff, 404 tt_data->flags = BATADV_TT_OGM_DIFF;
427 packet_buff_len, min_packet_len); 405 tt_data->ttvn = atomic_read(&bat_priv->tt.vn);
406 tt_data->crc = htons(bat_priv->tt.local_crc);
428 407
429 new_len = *packet_buff_len - min_packet_len; 408 if (tt_diff_len == 0)
430 tt_buff = *packet_buff + min_packet_len; 409 goto container_register;
431 410
432 if (new_len > 0) 411 tt_diff_entries_num = tt_diff_len / batadv_tt_len(1);
433 tot_changes = new_len / batadv_tt_len(1);
434 412
435 spin_lock_bh(&bat_priv->tt.changes_list_lock); 413 spin_lock_bh(&bat_priv->tt.changes_list_lock);
436 atomic_set(&bat_priv->tt.local_changes, 0); 414 atomic_set(&bat_priv->tt.local_changes, 0);
437 415
416 tt_change = (struct batadv_tvlv_tt_change *)(tt_data + 1);
417
438 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, 418 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
439 list) { 419 list) {
440 if (count < tot_changes) { 420 if (tt_diff_entries_count < tt_diff_entries_num) {
441 memcpy(tt_buff + batadv_tt_len(count), 421 memcpy(tt_change + tt_diff_entries_count,
442 &entry->change, sizeof(struct batadv_tt_change)); 422 &entry->change,
443 count++; 423 sizeof(struct batadv_tvlv_tt_change));
424 tt_diff_entries_count++;
444 } 425 }
445 list_del(&entry->list); 426 list_del(&entry->list);
446 kfree(entry); 427 kfree(entry);
@@ -452,20 +433,25 @@ static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv,
452 kfree(bat_priv->tt.last_changeset); 433 kfree(bat_priv->tt.last_changeset);
453 bat_priv->tt.last_changeset_len = 0; 434 bat_priv->tt.last_changeset_len = 0;
454 bat_priv->tt.last_changeset = NULL; 435 bat_priv->tt.last_changeset = NULL;
436 tt_change_len = batadv_tt_len(tt_diff_entries_count);
455 /* check whether this new OGM has no changes due to size problems */ 437 /* check whether this new OGM has no changes due to size problems */
456 if (new_len > 0) { 438 if (tt_diff_entries_count > 0) {
457 /* if kmalloc() fails we will reply with the full table 439 /* if kmalloc() fails we will reply with the full table
458 * instead of providing the diff 440 * instead of providing the diff
459 */ 441 */
460 bat_priv->tt.last_changeset = kmalloc(new_len, GFP_ATOMIC); 442 bat_priv->tt.last_changeset = kzalloc(tt_diff_len, GFP_ATOMIC);
461 if (bat_priv->tt.last_changeset) { 443 if (bat_priv->tt.last_changeset) {
462 memcpy(bat_priv->tt.last_changeset, tt_buff, new_len); 444 memcpy(bat_priv->tt.last_changeset,
463 bat_priv->tt.last_changeset_len = new_len; 445 tt_change, tt_change_len);
446 bat_priv->tt.last_changeset_len = tt_diff_len;
464 } 447 }
465 } 448 }
466 spin_unlock_bh(&bat_priv->tt.last_changeset_lock); 449 spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
467 450
468 return count; 451container_register:
452 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_TT, 1, tt_data,
453 sizeof(*tt_data) + tt_change_len);
454 kfree(tt_data);
469} 455}
470 456
471int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) 457int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
@@ -1504,7 +1490,7 @@ static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
1504static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv, 1490static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv,
1505 struct batadv_orig_node *orig_node, 1491 struct batadv_orig_node *orig_node,
1506 const unsigned char *tt_buff, 1492 const unsigned char *tt_buff,
1507 uint8_t tt_num_changes) 1493 uint16_t tt_num_changes)
1508{ 1494{
1509 uint16_t tt_buff_len = batadv_tt_len(tt_num_changes); 1495 uint16_t tt_buff_len = batadv_tt_len(tt_num_changes);
1510 1496
@@ -2126,25 +2112,6 @@ out:
2126 batadv_orig_node_free_ref(orig_node); 2112 batadv_orig_node_free_ref(orig_node);
2127} 2113}
2128 2114
2129int batadv_tt_init(struct batadv_priv *bat_priv)
2130{
2131 int ret;
2132
2133 ret = batadv_tt_local_init(bat_priv);
2134 if (ret < 0)
2135 return ret;
2136
2137 ret = batadv_tt_global_init(bat_priv);
2138 if (ret < 0)
2139 return ret;
2140
2141 INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge);
2142 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
2143 msecs_to_jiffies(BATADV_TT_WORK_PERIOD));
2144
2145 return 1;
2146}
2147
2148static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv) 2115static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv)
2149{ 2116{
2150 struct batadv_tt_roam_node *node, *safe; 2117 struct batadv_tt_roam_node *node, *safe;
@@ -2297,6 +2264,9 @@ static void batadv_tt_purge(struct work_struct *work)
2297 2264
2298void batadv_tt_free(struct batadv_priv *bat_priv) 2265void batadv_tt_free(struct batadv_priv *bat_priv)
2299{ 2266{
2267 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_TT, 1);
2268 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_TT, 1);
2269
2300 cancel_delayed_work_sync(&bat_priv->tt.work); 2270 cancel_delayed_work_sync(&bat_priv->tt.work);
2301 2271
2302 batadv_tt_local_table_free(bat_priv); 2272 batadv_tt_local_table_free(bat_priv);
@@ -2384,14 +2354,20 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
2384 } 2354 }
2385} 2355}
2386 2356
2387static int batadv_tt_commit_changes(struct batadv_priv *bat_priv, 2357/**
2388 unsigned char **packet_buff, 2358 * batadv_tt_local_commit_changes - commit all pending local tt changes which
2389 int *packet_buff_len, int packet_min_len) 2359 * have been queued in the time since the last commit
2360 * @bat_priv: the bat priv with all the soft interface information
2361 */
2362void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
2390{ 2363{
2391 uint16_t changed_num = 0; 2364 uint16_t changed_num = 0;
2392 2365
2393 if (atomic_read(&bat_priv->tt.local_changes) < 1) 2366 if (atomic_read(&bat_priv->tt.local_changes) < 1) {
2394 return -ENOENT; 2367 if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))
2368 batadv_tt_tvlv_container_update(bat_priv);
2369 return;
2370 }
2395 2371
2396 changed_num = batadv_tt_set_flags(bat_priv->tt.local_hash, 2372 changed_num = batadv_tt_set_flags(bat_priv->tt.local_hash,
2397 BATADV_TT_CLIENT_NEW, false); 2373 BATADV_TT_CLIENT_NEW, false);
@@ -2409,32 +2385,7 @@ static int batadv_tt_commit_changes(struct batadv_priv *bat_priv,
2409 2385
2410 /* reset the sending counter */ 2386 /* reset the sending counter */
2411 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); 2387 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
2412 2388 batadv_tt_tvlv_container_update(bat_priv);
2413 return batadv_tt_changes_fill_buff(bat_priv, packet_buff,
2414 packet_buff_len, packet_min_len);
2415}
2416
2417/* when calling this function (hard_iface == primary_if) has to be true */
2418int batadv_tt_append_diff(struct batadv_priv *bat_priv,
2419 unsigned char **packet_buff, int *packet_buff_len,
2420 int packet_min_len)
2421{
2422 int tt_num_changes;
2423
2424 /* if at least one change happened */
2425 tt_num_changes = batadv_tt_commit_changes(bat_priv, packet_buff,
2426 packet_buff_len,
2427 packet_min_len);
2428
2429 /* if the changes have been sent often enough */
2430 if ((tt_num_changes < 0) &&
2431 (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))) {
2432 batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len,
2433 packet_min_len, packet_min_len);
2434 tt_num_changes = 0;
2435 }
2436
2437 return tt_num_changes;
2438} 2389}
2439 2390
2440bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src, 2391bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
@@ -2468,10 +2419,21 @@ out:
2468 return ret; 2419 return ret;
2469} 2420}
2470 2421
2471void batadv_tt_update_orig(struct batadv_priv *bat_priv, 2422/**
2472 struct batadv_orig_node *orig_node, 2423 * batadv_tt_update_orig - update global translation table with new tt
2473 const unsigned char *tt_buff, uint8_t tt_num_changes, 2424 * information received via ogms
2474 uint8_t ttvn, uint16_t tt_crc) 2425 * @bat_priv: the bat priv with all the soft interface information
2426 * @orig: the orig_node of the ogm
2427 * @tt_buff: buffer holding the tt information
2428 * @tt_num_changes: number of tt changes inside the tt buffer
2429 * @ttvn: translation table version number of this changeset
2430 * @tt_crc: crc16 checksum of orig node's translation table
2431 */
2432static void batadv_tt_update_orig(struct batadv_priv *bat_priv,
2433 struct batadv_orig_node *orig_node,
2434 const unsigned char *tt_buff,
2435 uint16_t tt_num_changes, uint8_t ttvn,
2436 uint16_t tt_crc)
2475{ 2437{
2476 uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); 2438 uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
2477 bool full_table = true; 2439 bool full_table = true;
@@ -2605,3 +2567,61 @@ bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
2605out: 2567out:
2606 return ret; 2568 return ret;
2607} 2569}
2570
2571/**
2572 * batadv_tt_tvlv_ogm_handler_v1 - process incoming tt tvlv container
2573 * @bat_priv: the bat priv with all the soft interface information
2574 * @orig: the orig_node of the ogm
2575 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
2576 * @tvlv_value: tvlv buffer containing the gateway data
2577 * @tvlv_value_len: tvlv buffer length
2578 */
2579static void batadv_tt_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
2580 struct batadv_orig_node *orig,
2581 uint8_t flags,
2582 void *tvlv_value,
2583 uint16_t tvlv_value_len)
2584{
2585 struct batadv_tvlv_tt_data *tt_data;
2586 uint16_t num_entries;
2587
2588 if (tvlv_value_len < sizeof(*tt_data))
2589 return;
2590
2591 tt_data = (struct batadv_tvlv_tt_data *)tvlv_value;
2592 tvlv_value_len -= sizeof(*tt_data);
2593
2594 num_entries = tvlv_value_len / batadv_tt_len(1);
2595
2596 batadv_tt_update_orig(bat_priv, orig,
2597 (unsigned char *)(tt_data + 1),
2598 num_entries, tt_data->ttvn, ntohs(tt_data->crc));
2599}
2600
2601/**
2602 * batadv_tt_init - initialise the translation table internals
2603 * @bat_priv: the bat priv with all the soft interface information
2604 *
2605 * Return 0 on success or negative error number in case of failure.
2606 */
2607int batadv_tt_init(struct batadv_priv *bat_priv)
2608{
2609 int ret;
2610
2611 ret = batadv_tt_local_init(bat_priv);
2612 if (ret < 0)
2613 return ret;
2614
2615 ret = batadv_tt_global_init(bat_priv);
2616 if (ret < 0)
2617 return ret;
2618
2619 batadv_tvlv_handler_register(bat_priv, batadv_tt_tvlv_ogm_handler_v1,
2620 NULL, BATADV_TVLV_TT, 1, BATADV_NO_FLAGS);
2621
2622 INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge);
2623 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
2624 msecs_to_jiffies(BATADV_TT_WORK_PERIOD));
2625
2626 return 1;
2627}
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index 659a3bb759ce..a709249cf9d0 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -50,13 +50,7 @@ void batadv_handle_tt_response(struct batadv_priv *bat_priv,
50 struct batadv_tt_query_packet *tt_response); 50 struct batadv_tt_query_packet *tt_response);
51bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src, 51bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
52 uint8_t *dst); 52 uint8_t *dst);
53void batadv_tt_update_orig(struct batadv_priv *bat_priv, 53void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv);
54 struct batadv_orig_node *orig_node,
55 const unsigned char *tt_buff, uint8_t tt_num_changes,
56 uint8_t ttvn, uint16_t tt_crc);
57int batadv_tt_append_diff(struct batadv_priv *bat_priv,
58 unsigned char **packet_buff, int *packet_buff_len,
59 int packet_min_len);
60bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, 54bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
61 uint8_t *addr); 55 uint8_t *addr);
62bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv, 56bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index fa5cb0d99ed5..bdabbc21eb41 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -772,7 +772,7 @@ struct batadv_tt_orig_list_entry {
772 */ 772 */
773struct batadv_tt_change_node { 773struct batadv_tt_change_node {
774 struct list_head list; 774 struct list_head list;
775 struct batadv_tt_change change; 775 struct batadv_tvlv_tt_change change;
776}; 776};
777 777
778/** 778/**