aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/batman-adv/network-coding.c208
-rw-r--r--net/batman-adv/network-coding.h18
-rw-r--r--net/batman-adv/routing.c13
-rw-r--r--net/batman-adv/send.c5
-rw-r--r--net/batman-adv/soft-interface.c1
-rw-r--r--net/batman-adv/types.h11
6 files changed, 253 insertions, 3 deletions
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c
index fce2846e9656..3d2ed2fe5421 100644
--- a/net/batman-adv/network-coding.c
+++ b/net/batman-adv/network-coding.c
@@ -27,6 +27,7 @@
27#include "hard-interface.h" 27#include "hard-interface.h"
28 28
29static struct lock_class_key batadv_nc_coding_hash_lock_class_key; 29static struct lock_class_key batadv_nc_coding_hash_lock_class_key;
30static struct lock_class_key batadv_nc_decoding_hash_lock_class_key;
30 31
31static void batadv_nc_worker(struct work_struct *work); 32static void batadv_nc_worker(struct work_struct *work);
32 33
@@ -47,8 +48,9 @@ static void batadv_nc_start_timer(struct batadv_priv *bat_priv)
47int batadv_nc_init(struct batadv_priv *bat_priv) 48int batadv_nc_init(struct batadv_priv *bat_priv)
48{ 49{
49 bat_priv->nc.timestamp_fwd_flush = jiffies; 50 bat_priv->nc.timestamp_fwd_flush = jiffies;
51 bat_priv->nc.timestamp_sniffed_purge = jiffies;
50 52
51 if (bat_priv->nc.coding_hash) 53 if (bat_priv->nc.coding_hash || bat_priv->nc.decoding_hash)
52 return 0; 54 return 0;
53 55
54 bat_priv->nc.coding_hash = batadv_hash_new(128); 56 bat_priv->nc.coding_hash = batadv_hash_new(128);
@@ -58,6 +60,13 @@ int batadv_nc_init(struct batadv_priv *bat_priv)
58 batadv_hash_set_lock_class(bat_priv->nc.coding_hash, 60 batadv_hash_set_lock_class(bat_priv->nc.coding_hash,
59 &batadv_nc_coding_hash_lock_class_key); 61 &batadv_nc_coding_hash_lock_class_key);
60 62
63 bat_priv->nc.decoding_hash = batadv_hash_new(128);
64 if (!bat_priv->nc.decoding_hash)
65 goto err;
66
67 batadv_hash_set_lock_class(bat_priv->nc.coding_hash,
68 &batadv_nc_decoding_hash_lock_class_key);
69
61 INIT_DELAYED_WORK(&bat_priv->nc.work, batadv_nc_worker); 70 INIT_DELAYED_WORK(&bat_priv->nc.work, batadv_nc_worker);
62 batadv_nc_start_timer(bat_priv); 71 batadv_nc_start_timer(bat_priv);
63 72
@@ -76,6 +85,7 @@ void batadv_nc_init_bat_priv(struct batadv_priv *bat_priv)
76 atomic_set(&bat_priv->network_coding, 1); 85 atomic_set(&bat_priv->network_coding, 1);
77 bat_priv->nc.min_tq = 200; 86 bat_priv->nc.min_tq = 200;
78 bat_priv->nc.max_fwd_delay = 10; 87 bat_priv->nc.max_fwd_delay = 10;
88 bat_priv->nc.max_buffer_time = 200;
79} 89}
80 90
81/** 91/**
@@ -176,6 +186,26 @@ static bool batadv_nc_to_purge_nc_path_coding(struct batadv_priv *bat_priv,
176} 186}
177 187
178/** 188/**
189 * batadv_nc_to_purge_nc_path_decoding - checks whether an nc path has timed out
190 * @bat_priv: the bat priv with all the soft interface information
191 * @nc_path: the nc path to check
192 *
193 * Returns true if the entry has to be purged now, false otherwise
194 */
195static bool batadv_nc_to_purge_nc_path_decoding(struct batadv_priv *bat_priv,
196 struct batadv_nc_path *nc_path)
197{
198 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
199 return true;
200
201 /* purge the path when no packets has been added for 10 times the
202 * max_buffer time
203 */
204 return batadv_has_timed_out(nc_path->last_valid,
205 bat_priv->nc.max_buffer_time*10);
206}
207
208/**
179 * batadv_nc_purge_orig_nc_nodes - go through list of nc nodes and purge stale 209 * batadv_nc_purge_orig_nc_nodes - go through list of nc nodes and purge stale
180 * entries 210 * entries
181 * @bat_priv: the bat priv with all the soft interface information 211 * @bat_priv: the bat priv with all the soft interface information
@@ -441,6 +471,43 @@ static void batadv_nc_send_packet(struct batadv_nc_packet *nc_packet)
441} 471}
442 472
443/** 473/**
474 * batadv_nc_sniffed_purge - Checks timestamp of given sniffed nc_packet.
475 * @bat_priv: the bat priv with all the soft interface information
476 * @nc_path: the nc path the packet belongs to
477 * @nc_packet: the nc packet to be checked
478 *
479 * Checks whether the given sniffed (overheard) nc_packet has hit its buffering
480 * timeout. If so, the packet is no longer kept and the entry deleted from the
481 * queue. Has to be called with the appropriate locks.
482 *
483 * Returns false as soon as the entry in the fifo queue has not been timed out
484 * yet and true otherwise.
485 */
486static bool batadv_nc_sniffed_purge(struct batadv_priv *bat_priv,
487 struct batadv_nc_path *nc_path,
488 struct batadv_nc_packet *nc_packet)
489{
490 unsigned long timeout = bat_priv->nc.max_buffer_time;
491 bool res = false;
492
493 /* Packets are added to tail, so the remaining packets did not time
494 * out and we can stop processing the current queue
495 */
496 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE &&
497 !batadv_has_timed_out(nc_packet->timestamp, timeout))
498 goto out;
499
500 /* purge nc packet */
501 list_del(&nc_packet->list);
502 batadv_nc_packet_free(nc_packet);
503
504 res = true;
505
506out:
507 return res;
508}
509
510/**
444 * batadv_nc_fwd_flush - Checks the timestamp of the given nc packet. 511 * batadv_nc_fwd_flush - Checks the timestamp of the given nc packet.
445 * @bat_priv: the bat priv with all the soft interface information 512 * @bat_priv: the bat priv with all the soft interface information
446 * @nc_path: the nc path the packet belongs to 513 * @nc_path: the nc path the packet belongs to
@@ -540,6 +607,8 @@ static void batadv_nc_worker(struct work_struct *work)
540 batadv_nc_purge_orig_hash(bat_priv); 607 batadv_nc_purge_orig_hash(bat_priv);
541 batadv_nc_purge_paths(bat_priv, bat_priv->nc.coding_hash, 608 batadv_nc_purge_paths(bat_priv, bat_priv->nc.coding_hash,
542 batadv_nc_to_purge_nc_path_coding); 609 batadv_nc_to_purge_nc_path_coding);
610 batadv_nc_purge_paths(bat_priv, bat_priv->nc.decoding_hash,
611 batadv_nc_to_purge_nc_path_decoding);
543 612
544 timeout = bat_priv->nc.max_fwd_delay; 613 timeout = bat_priv->nc.max_fwd_delay;
545 614
@@ -549,6 +618,13 @@ static void batadv_nc_worker(struct work_struct *work)
549 bat_priv->nc.timestamp_fwd_flush = jiffies; 618 bat_priv->nc.timestamp_fwd_flush = jiffies;
550 } 619 }
551 620
621 if (batadv_has_timed_out(bat_priv->nc.timestamp_sniffed_purge,
622 bat_priv->nc.max_buffer_time)) {
623 batadv_nc_process_nc_paths(bat_priv, bat_priv->nc.decoding_hash,
624 batadv_nc_sniffed_purge);
625 bat_priv->nc.timestamp_sniffed_purge = jiffies;
626 }
627
552 /* Schedule a new check */ 628 /* Schedule a new check */
553 batadv_nc_start_timer(bat_priv); 629 batadv_nc_start_timer(bat_priv);
554} 630}
@@ -1143,6 +1219,41 @@ batadv_nc_skb_src_search(struct batadv_priv *bat_priv,
1143} 1219}
1144 1220
1145/** 1221/**
1222 * batadv_nc_skb_store_before_coding - set the ethernet src and dst of the
1223 * unicast skb before it is stored for use in later decoding
1224 * @bat_priv: the bat priv with all the soft interface information
1225 * @skb: data skb to store
1226 * @eth_dst_new: new destination mac address of skb
1227 */
1228static void batadv_nc_skb_store_before_coding(struct batadv_priv *bat_priv,
1229 struct sk_buff *skb,
1230 uint8_t *eth_dst_new)
1231{
1232 struct ethhdr *ethhdr;
1233
1234 /* Copy skb header to change the mac header */
1235 skb = pskb_copy(skb, GFP_ATOMIC);
1236 if (!skb)
1237 return;
1238
1239 /* Set the mac header as if we actually sent the packet uncoded */
1240 ethhdr = (struct ethhdr *)skb_mac_header(skb);
1241 memcpy(ethhdr->h_source, ethhdr->h_dest, ETH_ALEN);
1242 memcpy(ethhdr->h_dest, eth_dst_new, ETH_ALEN);
1243
1244 /* Set data pointer to MAC header to mimic packets from our tx path */
1245 skb_push(skb, ETH_HLEN);
1246
1247 /* Add the packet to the decoding packet pool */
1248 batadv_nc_skb_store_for_decoding(bat_priv, skb);
1249
1250 /* batadv_nc_skb_store_for_decoding() clones the skb, so we must free
1251 * our ref
1252 */
1253 kfree_skb(skb);
1254}
1255
1256/**
1146 * batadv_nc_skb_dst_search - Loops through list of neighboring nodes to dst. 1257 * batadv_nc_skb_dst_search - Loops through list of neighboring nodes to dst.
1147 * @skb: data skb to forward 1258 * @skb: data skb to forward
1148 * @neigh_node: next hop to forward packet to 1259 * @neigh_node: next hop to forward packet to
@@ -1181,6 +1292,12 @@ static bool batadv_nc_skb_dst_search(struct sk_buff *skb,
1181 if (!nc_packet) 1292 if (!nc_packet)
1182 return false; 1293 return false;
1183 1294
1295 /* Save packets for later decoding */
1296 batadv_nc_skb_store_before_coding(bat_priv, skb,
1297 neigh_node->addr);
1298 batadv_nc_skb_store_before_coding(bat_priv, nc_packet->skb,
1299 nc_packet->neigh_node->addr);
1300
1184 /* Code and send packets */ 1301 /* Code and send packets */
1185 if (batadv_nc_code_packets(bat_priv, skb, ethhdr, nc_packet, 1302 if (batadv_nc_code_packets(bat_priv, skb, ethhdr, nc_packet,
1186 neigh_node)) 1303 neigh_node))
@@ -1288,14 +1405,98 @@ out:
1288} 1405}
1289 1406
1290/** 1407/**
1408 * batadv_nc_skb_store_for_decoding - save a clone of the skb which can be used
1409 * when decoding coded packets
1410 * @bat_priv: the bat priv with all the soft interface information
1411 * @skb: data skb to store
1412 */
1413void batadv_nc_skb_store_for_decoding(struct batadv_priv *bat_priv,
1414 struct sk_buff *skb)
1415{
1416 struct batadv_unicast_packet *packet;
1417 struct batadv_nc_path *nc_path;
1418 struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
1419 __be32 packet_id;
1420 u8 *payload;
1421
1422 /* Check if network coding is enabled */
1423 if (!atomic_read(&bat_priv->network_coding))
1424 goto out;
1425
1426 /* Check for supported packet type */
1427 payload = skb_network_header(skb);
1428 packet = (struct batadv_unicast_packet *)payload;
1429 if (packet->header.packet_type != BATADV_UNICAST)
1430 goto out;
1431
1432 /* Find existing nc_path or create a new */
1433 nc_path = batadv_nc_get_path(bat_priv,
1434 bat_priv->nc.decoding_hash,
1435 ethhdr->h_source,
1436 ethhdr->h_dest);
1437
1438 if (!nc_path)
1439 goto out;
1440
1441 /* Clone skb and adjust skb->data to point at batman header */
1442 skb = skb_clone(skb, GFP_ATOMIC);
1443 if (unlikely(!skb))
1444 goto free_nc_path;
1445
1446 if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
1447 goto free_skb;
1448
1449 if (unlikely(!skb_pull_rcsum(skb, ETH_HLEN)))
1450 goto free_skb;
1451
1452 /* Add skb to nc_path */
1453 packet_id = batadv_skb_crc32(skb, payload + sizeof(*packet));
1454 if (!batadv_nc_skb_add_to_path(skb, nc_path, NULL, packet_id))
1455 goto free_skb;
1456
1457 batadv_inc_counter(bat_priv, BATADV_CNT_NC_BUFFER);
1458 return;
1459
1460free_skb:
1461 kfree_skb(skb);
1462free_nc_path:
1463 batadv_nc_path_free_ref(nc_path);
1464out:
1465 return;
1466}
1467
1468/**
1469 * batadv_nc_skb_store_sniffed_unicast - check if a received unicast packet
1470 * should be saved in the decoding buffer and, if so, store it there
1471 * @bat_priv: the bat priv with all the soft interface information
1472 * @skb: unicast skb to store
1473 */
1474void batadv_nc_skb_store_sniffed_unicast(struct batadv_priv *bat_priv,
1475 struct sk_buff *skb)
1476{
1477 struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
1478
1479 if (batadv_is_my_mac(ethhdr->h_dest))
1480 return;
1481
1482 /* Set data pointer to MAC header to mimic packets from our tx path */
1483 skb_push(skb, ETH_HLEN);
1484
1485 batadv_nc_skb_store_for_decoding(bat_priv, skb);
1486}
1487
1488/**
1291 * batadv_nc_free - clean up network coding memory 1489 * batadv_nc_free - clean up network coding memory
1292 * @bat_priv: the bat priv with all the soft interface information 1490 * @bat_priv: the bat priv with all the soft interface information
1293 */ 1491 */
1294void batadv_nc_free(struct batadv_priv *bat_priv) 1492void batadv_nc_free(struct batadv_priv *bat_priv)
1295{ 1493{
1296 cancel_delayed_work_sync(&bat_priv->nc.work); 1494 cancel_delayed_work_sync(&bat_priv->nc.work);
1495
1297 batadv_nc_purge_paths(bat_priv, bat_priv->nc.coding_hash, NULL); 1496 batadv_nc_purge_paths(bat_priv, bat_priv->nc.coding_hash, NULL);
1298 batadv_hash_destroy(bat_priv->nc.coding_hash); 1497 batadv_hash_destroy(bat_priv->nc.coding_hash);
1498 batadv_nc_purge_paths(bat_priv, bat_priv->nc.decoding_hash, NULL);
1499 batadv_hash_destroy(bat_priv->nc.decoding_hash);
1299} 1500}
1300 1501
1301/** 1502/**
@@ -1376,6 +1577,11 @@ int batadv_nc_init_debugfs(struct batadv_priv *bat_priv)
1376 if (!file) 1577 if (!file)
1377 goto out; 1578 goto out;
1378 1579
1580 file = debugfs_create_u32("max_buffer_time", S_IRUGO | S_IWUSR, nc_dir,
1581 &bat_priv->nc.max_buffer_time);
1582 if (!file)
1583 goto out;
1584
1379 return 0; 1585 return 0;
1380 1586
1381out: 1587out:
diff --git a/net/batman-adv/network-coding.h b/net/batman-adv/network-coding.h
index c32602a3939a..4fa6d0caddbd 100644
--- a/net/batman-adv/network-coding.h
+++ b/net/batman-adv/network-coding.h
@@ -38,6 +38,10 @@ void batadv_nc_init_orig(struct batadv_orig_node *orig_node);
38bool batadv_nc_skb_forward(struct sk_buff *skb, 38bool batadv_nc_skb_forward(struct sk_buff *skb,
39 struct batadv_neigh_node *neigh_node, 39 struct batadv_neigh_node *neigh_node,
40 struct ethhdr *ethhdr); 40 struct ethhdr *ethhdr);
41void batadv_nc_skb_store_for_decoding(struct batadv_priv *bat_priv,
42 struct sk_buff *skb);
43void batadv_nc_skb_store_sniffed_unicast(struct batadv_priv *bat_priv,
44 struct sk_buff *skb);
41int batadv_nc_nodes_seq_print_text(struct seq_file *seq, void *offset); 45int batadv_nc_nodes_seq_print_text(struct seq_file *seq, void *offset);
42int batadv_nc_init_debugfs(struct batadv_priv *bat_priv); 46int batadv_nc_init_debugfs(struct batadv_priv *bat_priv);
43 47
@@ -89,6 +93,20 @@ static inline bool batadv_nc_skb_forward(struct sk_buff *skb,
89 return false; 93 return false;
90} 94}
91 95
96static inline void
97batadv_nc_skb_store_for_decoding(struct batadv_priv *bat_priv,
98 struct sk_buff *skb)
99{
100 return;
101}
102
103static inline void
104batadv_nc_skb_store_sniffed_unicast(struct batadv_priv *bat_priv,
105 struct sk_buff *skb)
106{
107 return;
108}
109
92static inline int batadv_nc_nodes_seq_print_text(struct seq_file *seq, 110static inline int batadv_nc_nodes_seq_print_text(struct seq_file *seq,
93 void *offset) 111 void *offset)
94{ 112{
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 44fda7c6171e..8f88967ff14b 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -1047,7 +1047,7 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
1047 struct batadv_unicast_4addr_packet *unicast_4addr_packet; 1047 struct batadv_unicast_4addr_packet *unicast_4addr_packet;
1048 uint8_t *orig_addr; 1048 uint8_t *orig_addr;
1049 struct batadv_orig_node *orig_node = NULL; 1049 struct batadv_orig_node *orig_node = NULL;
1050 int hdr_size = sizeof(*unicast_packet); 1050 int check, hdr_size = sizeof(*unicast_packet);
1051 bool is4addr; 1051 bool is4addr;
1052 1052
1053 unicast_packet = (struct batadv_unicast_packet *)skb->data; 1053 unicast_packet = (struct batadv_unicast_packet *)skb->data;
@@ -1058,7 +1058,16 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
1058 if (is4addr) 1058 if (is4addr)
1059 hdr_size = sizeof(*unicast_4addr_packet); 1059 hdr_size = sizeof(*unicast_4addr_packet);
1060 1060
1061 if (batadv_check_unicast_packet(skb, hdr_size) < 0) 1061 /* function returns -EREMOTE for promiscuous packets */
1062 check = batadv_check_unicast_packet(skb, hdr_size);
1063
1064 /* Even though the packet is not for us, we might save it to use for
1065 * decoding a later received coded packet
1066 */
1067 if (check == -EREMOTE)
1068 batadv_nc_skb_store_sniffed_unicast(bat_priv, skb);
1069
1070 if (check < 0)
1062 return NET_RX_DROP; 1071 return NET_RX_DROP;
1063 1072
1064 if (!batadv_check_unicast_ttvn(bat_priv, skb)) 1073 if (!batadv_check_unicast_ttvn(bat_priv, skb))
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index a67cffde37ae..263cfd1ccee7 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -27,6 +27,7 @@
27#include "vis.h" 27#include "vis.h"
28#include "gateway_common.h" 28#include "gateway_common.h"
29#include "originator.h" 29#include "originator.h"
30#include "network-coding.h"
30 31
31#include <linux/if_ether.h> 32#include <linux/if_ether.h>
32 33
@@ -39,6 +40,7 @@ int batadv_send_skb_packet(struct sk_buff *skb,
39 struct batadv_hard_iface *hard_iface, 40 struct batadv_hard_iface *hard_iface,
40 const uint8_t *dst_addr) 41 const uint8_t *dst_addr)
41{ 42{
43 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
42 struct ethhdr *ethhdr; 44 struct ethhdr *ethhdr;
43 45
44 if (hard_iface->if_status != BATADV_IF_ACTIVE) 46 if (hard_iface->if_status != BATADV_IF_ACTIVE)
@@ -70,6 +72,9 @@ int batadv_send_skb_packet(struct sk_buff *skb,
70 72
71 skb->dev = hard_iface->net_dev; 73 skb->dev = hard_iface->net_dev;
72 74
75 /* Save a clone of the skb to use when decoding coded packets */
76 batadv_nc_skb_store_for_decoding(bat_priv, skb);
77
73 /* dev_queue_xmit() returns a negative result on error. However on 78 /* dev_queue_xmit() returns a negative result on error. However on
74 * congestion and traffic shaping, it drops and returns NET_XMIT_DROP 79 * congestion and traffic shaping, it drops and returns NET_XMIT_DROP
75 * (which is > 0). This will not be treated as an error. 80 * (which is > 0). This will not be treated as an error.
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 7e463c3ae1d9..75204ec1eee4 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -670,6 +670,7 @@ static const struct {
670 { "nc_code_bytes" }, 670 { "nc_code_bytes" },
671 { "nc_recode" }, 671 { "nc_recode" },
672 { "nc_recode_bytes" }, 672 { "nc_recode_bytes" },
673 { "nc_buffer" },
673#endif 674#endif
674}; 675};
675 676
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 42d743850ec2..5f3640d15dd2 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -279,6 +279,7 @@ struct batadv_bcast_duplist_entry {
279 * @BATADV_CNT_NC_CODE_BYTES: transmitted nc-combined traffic bytes counter 279 * @BATADV_CNT_NC_CODE_BYTES: transmitted nc-combined traffic bytes counter
280 * @BATADV_CNT_NC_RECODE: transmitted nc-recombined traffic packet counter 280 * @BATADV_CNT_NC_RECODE: transmitted nc-recombined traffic packet counter
281 * @BATADV_CNT_NC_RECODE_BYTES: transmitted nc-recombined traffic bytes counter 281 * @BATADV_CNT_NC_RECODE_BYTES: transmitted nc-recombined traffic bytes counter
282 * @BATADV_CNT_NC_BUFFER: counter for packets buffered for later nc decoding
282 * @BATADV_CNT_NUM: number of traffic counters 283 * @BATADV_CNT_NUM: number of traffic counters
283 */ 284 */
284enum batadv_counters { 285enum batadv_counters {
@@ -311,6 +312,7 @@ enum batadv_counters {
311 BATADV_CNT_NC_CODE_BYTES, 312 BATADV_CNT_NC_CODE_BYTES,
312 BATADV_CNT_NC_RECODE, 313 BATADV_CNT_NC_RECODE,
313 BATADV_CNT_NC_RECODE_BYTES, 314 BATADV_CNT_NC_RECODE_BYTES,
315 BATADV_CNT_NC_BUFFER,
314#endif 316#endif
315 BATADV_CNT_NUM, 317 BATADV_CNT_NUM,
316}; 318};
@@ -453,18 +455,27 @@ struct batadv_priv_dat {
453 * @debug_dir: dentry for nc subdir in batman-adv directory in debugfs 455 * @debug_dir: dentry for nc subdir in batman-adv directory in debugfs
454 * @min_tq: only consider neighbors for encoding if neigh_tq > min_tq 456 * @min_tq: only consider neighbors for encoding if neigh_tq > min_tq
455 * @max_fwd_delay: maximum packet forward delay to allow coding of packets 457 * @max_fwd_delay: maximum packet forward delay to allow coding of packets
458 * @max_buffer_time: buffer time for sniffed packets used to decoding
456 * @timestamp_fwd_flush: timestamp of last forward packet queue flush 459 * @timestamp_fwd_flush: timestamp of last forward packet queue flush
460 * @timestamp_sniffed_purge: timestamp of last sniffed packet queue purge
457 * @coding_hash: Hash table used to buffer skbs while waiting for another 461 * @coding_hash: Hash table used to buffer skbs while waiting for another
458 * incoming skb to code it with. Skbs are added to the buffer just before being 462 * incoming skb to code it with. Skbs are added to the buffer just before being
459 * forwarded in routing.c 463 * forwarded in routing.c
464 * @decoding_hash: Hash table used to buffer skbs that might be needed to decode
465 * a received coded skb. The buffer is used for 1) skbs arriving on the
466 * soft-interface; 2) skbs overheard on the hard-interface; and 3) skbs
467 * forwarded by batman-adv.
460 */ 468 */
461struct batadv_priv_nc { 469struct batadv_priv_nc {
462 struct delayed_work work; 470 struct delayed_work work;
463 struct dentry *debug_dir; 471 struct dentry *debug_dir;
464 u8 min_tq; 472 u8 min_tq;
465 u32 max_fwd_delay; 473 u32 max_fwd_delay;
474 u32 max_buffer_time;
466 unsigned long timestamp_fwd_flush; 475 unsigned long timestamp_fwd_flush;
476 unsigned long timestamp_sniffed_purge;
467 struct batadv_hashtable *coding_hash; 477 struct batadv_hashtable *coding_hash;
478 struct batadv_hashtable *decoding_hash;
468}; 479};
469 480
470/** 481/**