aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/translation-table.c
diff options
context:
space:
mode:
authorMarek Lindner <lindner_marek@yahoo.de>2012-05-06 16:22:05 -0400
committerAntonio Quartulli <ordex@autistici.org>2012-06-18 12:01:05 -0400
commitbe9aa4c1e0d7124cf976831db098f1e852fdbd14 (patch)
tree652acbdcf0bc309de8e69ab76ca233d5a9c652a7 /net/batman-adv/translation-table.c
parentbeeb96a4142180c34ddf592aef5a278c2d676bf0 (diff)
batman-adv: turn tt commit code into routing protocol agnostic API
Prior to this patch the translation table code made assumptions about how the routing protocol works and where its buffers are stored (to directly modify them). Each protocol now calls the tt code with the relevant pointers, thereby abstracting the code. Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> Acked-by: Antonio Quartulli <ordex@autistici.org> Signed-off-by: Sven Eckelmann <sven@narfation.org>
Diffstat (limited to 'net/batman-adv/translation-table.c')
-rw-r--r--net/batman-adv/translation-table.c124
1 files changed, 104 insertions, 20 deletions
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 88cfe2a8ea4f..a1a51cc9d88e 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -275,14 +275,64 @@ out:
275 tt_global_entry_free_ref(tt_global_entry); 275 tt_global_entry_free_ref(tt_global_entry);
276} 276}
277 277
278int tt_changes_fill_buffer(struct bat_priv *bat_priv, 278static void tt_realloc_packet_buff(unsigned char **packet_buff,
279 unsigned char *buff, int buff_len) 279 int *packet_buff_len, int min_packet_len,
280 int new_packet_len)
281{
282 unsigned char *new_buff;
283
284 new_buff = kmalloc(new_packet_len, GFP_ATOMIC);
285
286 /* keep old buffer if kmalloc should fail */
287 if (new_buff) {
288 memcpy(new_buff, *packet_buff, min_packet_len);
289 kfree(*packet_buff);
290 *packet_buff = new_buff;
291 *packet_buff_len = new_packet_len;
292 }
293}
294
295static void tt_prepare_packet_buff(struct bat_priv *bat_priv,
296 unsigned char **packet_buff,
297 int *packet_buff_len, int min_packet_len)
298{
299 struct hard_iface *primary_if;
300 int req_len;
301
302 primary_if = primary_if_get_selected(bat_priv);
303
304 req_len = min_packet_len;
305 req_len += tt_len(atomic_read(&bat_priv->tt_local_changes));
306
307 /* if we have too many changes for one packet don't send any
308 * and wait for the tt table request which will be fragmented
309 */
310 if ((!primary_if) || (req_len > primary_if->soft_iface->mtu))
311 req_len = min_packet_len;
312
313 tt_realloc_packet_buff(packet_buff, packet_buff_len,
314 min_packet_len, req_len);
315
316 if (primary_if)
317 hardif_free_ref(primary_if);
318}
319
320static int tt_changes_fill_buff(struct bat_priv *bat_priv,
321 unsigned char **packet_buff,
322 int *packet_buff_len, int min_packet_len)
280{ 323{
281 int count = 0, tot_changes = 0;
282 struct tt_change_node *entry, *safe; 324 struct tt_change_node *entry, *safe;
325 int count = 0, tot_changes = 0, new_len;
326 unsigned char *tt_buff;
327
328 tt_prepare_packet_buff(bat_priv, packet_buff,
329 packet_buff_len, min_packet_len);
283 330
284 if (buff_len > 0) 331 new_len = *packet_buff_len - min_packet_len;
285 tot_changes = buff_len / tt_len(1); 332 tt_buff = *packet_buff + min_packet_len;
333
334 if (new_len > 0)
335 tot_changes = new_len / tt_len(1);
286 336
287 spin_lock_bh(&bat_priv->tt_changes_list_lock); 337 spin_lock_bh(&bat_priv->tt_changes_list_lock);
288 atomic_set(&bat_priv->tt_local_changes, 0); 338 atomic_set(&bat_priv->tt_local_changes, 0);
@@ -290,7 +340,7 @@ int tt_changes_fill_buffer(struct bat_priv *bat_priv,
290 list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, 340 list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list,
291 list) { 341 list) {
292 if (count < tot_changes) { 342 if (count < tot_changes) {
293 memcpy(buff + tt_len(count), 343 memcpy(tt_buff + tt_len(count),
294 &entry->change, sizeof(struct tt_change)); 344 &entry->change, sizeof(struct tt_change));
295 count++; 345 count++;
296 } 346 }
@@ -304,17 +354,15 @@ int tt_changes_fill_buffer(struct bat_priv *bat_priv,
304 kfree(bat_priv->tt_buff); 354 kfree(bat_priv->tt_buff);
305 bat_priv->tt_buff_len = 0; 355 bat_priv->tt_buff_len = 0;
306 bat_priv->tt_buff = NULL; 356 bat_priv->tt_buff = NULL;
307 /* We check whether this new OGM has no changes due to size 357 /* check whether this new OGM has no changes due to size problems */
308 * problems */ 358 if (new_len > 0) {
309 if (buff_len > 0) { 359 /* if kmalloc() fails we will reply with the full table
310 /**
311 * if kmalloc() fails we will reply with the full table
312 * instead of providing the diff 360 * instead of providing the diff
313 */ 361 */
314 bat_priv->tt_buff = kmalloc(buff_len, GFP_ATOMIC); 362 bat_priv->tt_buff = kmalloc(new_len, GFP_ATOMIC);
315 if (bat_priv->tt_buff) { 363 if (bat_priv->tt_buff) {
316 memcpy(bat_priv->tt_buff, buff, buff_len); 364 memcpy(bat_priv->tt_buff, tt_buff, new_len);
317 bat_priv->tt_buff_len = buff_len; 365 bat_priv->tt_buff_len = new_len;
318 } 366 }
319 } 367 }
320 spin_unlock_bh(&bat_priv->tt_buff_lock); 368 spin_unlock_bh(&bat_priv->tt_buff_lock);
@@ -1105,7 +1153,7 @@ static uint16_t tt_global_crc(struct bat_priv *bat_priv,
1105} 1153}
1106 1154
1107/* Calculates the checksum of the local table */ 1155/* Calculates the checksum of the local table */
1108uint16_t tt_local_crc(struct bat_priv *bat_priv) 1156static uint16_t batadv_tt_local_crc(struct bat_priv *bat_priv)
1109{ 1157{
1110 uint16_t total = 0, total_one; 1158 uint16_t total = 0, total_one;
1111 struct hashtable_t *hash = bat_priv->tt_local_hash; 1159 struct hashtable_t *hash = bat_priv->tt_local_hash;
@@ -2025,20 +2073,56 @@ static void tt_local_purge_pending_clients(struct bat_priv *bat_priv)
2025 2073
2026} 2074}
2027 2075
2028void tt_commit_changes(struct bat_priv *bat_priv) 2076static int tt_commit_changes(struct bat_priv *bat_priv,
2077 unsigned char **packet_buff, int *packet_buff_len,
2078 int packet_min_len)
2029{ 2079{
2030 uint16_t changed_num = tt_set_flags(bat_priv->tt_local_hash, 2080 uint16_t changed_num = 0;
2031 TT_CLIENT_NEW, false); 2081
2032 /* all the reset entries have now to be effectively counted as local 2082 if (atomic_read(&bat_priv->tt_local_changes) < 1)
2033 * entries */ 2083 return -ENOENT;
2084
2085 changed_num = tt_set_flags(bat_priv->tt_local_hash,
2086 TT_CLIENT_NEW, false);
2087
2088 /* all reset entries have to be counted as local entries */
2034 atomic_add(changed_num, &bat_priv->num_local_tt); 2089 atomic_add(changed_num, &bat_priv->num_local_tt);
2035 tt_local_purge_pending_clients(bat_priv); 2090 tt_local_purge_pending_clients(bat_priv);
2091 bat_priv->tt_crc = batadv_tt_local_crc(bat_priv);
2036 2092
2037 /* Increment the TTVN only once per OGM interval */ 2093 /* Increment the TTVN only once per OGM interval */
2038 atomic_inc(&bat_priv->ttvn); 2094 atomic_inc(&bat_priv->ttvn);
2039 bat_dbg(DBG_TT, bat_priv, "Local changes committed, updating to ttvn %u\n", 2095 bat_dbg(DBG_TT, bat_priv, "Local changes committed, updating to ttvn %u\n",
2040 (uint8_t)atomic_read(&bat_priv->ttvn)); 2096 (uint8_t)atomic_read(&bat_priv->ttvn));
2041 bat_priv->tt_poss_change = false; 2097 bat_priv->tt_poss_change = false;
2098
2099 /* reset the sending counter */
2100 atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX);
2101
2102 return tt_changes_fill_buff(bat_priv, packet_buff,
2103 packet_buff_len, packet_min_len);
2104}
2105
2106/* when calling this function (hard_iface == primary_if) has to be true */
2107int batadv_tt_append_diff(struct bat_priv *bat_priv,
2108 unsigned char **packet_buff, int *packet_buff_len,
2109 int packet_min_len)
2110{
2111 int tt_num_changes;
2112
2113 /* if at least one change happened */
2114 tt_num_changes = tt_commit_changes(bat_priv, packet_buff,
2115 packet_buff_len, packet_min_len);
2116
2117 /* if the changes have been sent often enough */
2118 if ((tt_num_changes < 0) &&
2119 (!atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt))) {
2120 tt_realloc_packet_buff(packet_buff, packet_buff_len,
2121 packet_min_len, packet_min_len);
2122 tt_num_changes = 0;
2123 }
2124
2125 return tt_num_changes;
2042} 2126}
2043 2127
2044bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst) 2128bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst)