diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/batman-adv/bat_iv_ogm.c | 44 | ||||
-rw-r--r-- | net/batman-adv/packet.h | 51 | ||||
-rw-r--r-- | net/batman-adv/translation-table.c | 240 | ||||
-rw-r--r-- | net/batman-adv/translation-table.h | 8 | ||||
-rw-r--r-- | net/batman-adv/types.h | 2 |
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 | |||
845 | update_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 | ||
858 | unlock: | 844 | unlock: |
@@ -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 | ||
89 | enum 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 | /** |
95 | enum 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 | */ | ||
99 | enum 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 | */ |
127 | enum batadv_tvlv_type { | 135 | enum 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 | */ | ||
390 | struct 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 | */ | ||
403 | struct 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 | ||
379 | static 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; | 384 | static 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 | |||
397 | static 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 | |||
417 | static 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; | 451 | container_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 | ||
471 | int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) | 457 | int 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) | |||
1504 | static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv, | 1490 | static 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 | ||
2129 | int 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 | |||
2148 | static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv) | 2115 | static 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 | ||
2298 | void batadv_tt_free(struct batadv_priv *bat_priv) | 2265 | void 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 | ||
2387 | static 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 | */ | ||
2362 | void 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 */ | ||
2418 | int 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 | ||
2440 | bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src, | 2391 | bool 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 | ||
2471 | void 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 | */ | ||
2432 | static 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, | |||
2605 | out: | 2567 | out: |
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 | */ | ||
2579 | static 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 | */ | ||
2607 | int 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); |
51 | bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src, | 51 | bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src, |
52 | uint8_t *dst); | 52 | uint8_t *dst); |
53 | void batadv_tt_update_orig(struct batadv_priv *bat_priv, | 53 | void 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); | ||
57 | int batadv_tt_append_diff(struct batadv_priv *bat_priv, | ||
58 | unsigned char **packet_buff, int *packet_buff_len, | ||
59 | int packet_min_len); | ||
60 | bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, | 54 | bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, |
61 | uint8_t *addr); | 55 | uint8_t *addr); |
62 | bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv, | 56 | bool 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 | */ |
773 | struct batadv_tt_change_node { | 773 | struct 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 | /** |