Commit 95332477 authored by Martin Hundebøll's avatar Martin Hundebøll Committed by Antonio Quartulli

batman-adv: network coding - buffer unicast packets before forward

Two be able to network code two packets, one packet must be buffered
until the next is available. This is done in a "coding buffer", which is
essentially a hash table with lists of packets. Each entry in the hash
table corresponds to a specific src-dst pair, which has a linked list of
packets that are buffered.

This patch adds skbs to the buffer just before forwarding them. The
buffer is traversed every 10 ms, where timed skbs are removed from the
buffer and transmitted. To allow experiments with the network coding
scheme, the timeout is tunable through a file in debugfs.
Signed-off-by: default avatarMartin Hundebøll <martin@hundeboll.net>
Signed-off-by: default avatarMarek Lindner <lindner_marek@yahoo.de>
Signed-off-by: default avatarAntonio Quartulli <ordex@autistici.org>
parent d56b1705
This diff is collapsed.
...@@ -35,6 +35,9 @@ void batadv_nc_purge_orig(struct batadv_priv *bat_priv, ...@@ -35,6 +35,9 @@ void batadv_nc_purge_orig(struct batadv_priv *bat_priv,
struct batadv_nc_node *)); struct batadv_nc_node *));
void batadv_nc_init_bat_priv(struct batadv_priv *bat_priv); void batadv_nc_init_bat_priv(struct batadv_priv *bat_priv);
void batadv_nc_init_orig(struct batadv_orig_node *orig_node); void batadv_nc_init_orig(struct batadv_orig_node *orig_node);
bool batadv_nc_skb_forward(struct sk_buff *skb,
struct batadv_neigh_node *neigh_node,
struct ethhdr *ethhdr);
int batadv_nc_nodes_seq_print_text(struct seq_file *seq, void *offset); int batadv_nc_nodes_seq_print_text(struct seq_file *seq, void *offset);
int batadv_nc_init_debugfs(struct batadv_priv *bat_priv); int batadv_nc_init_debugfs(struct batadv_priv *bat_priv);
...@@ -79,6 +82,13 @@ static inline void batadv_nc_init_orig(struct batadv_orig_node *orig_node) ...@@ -79,6 +82,13 @@ static inline void batadv_nc_init_orig(struct batadv_orig_node *orig_node)
return; return;
} }
static inline bool batadv_nc_skb_forward(struct sk_buff *skb,
struct batadv_neigh_node *neigh_node,
struct ethhdr *ethhdr)
{
return false;
}
static inline int batadv_nc_nodes_seq_print_text(struct seq_file *seq, static inline int batadv_nc_nodes_seq_print_text(struct seq_file *seq,
void *offset) void *offset)
{ {
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "unicast.h" #include "unicast.h"
#include "bridge_loop_avoidance.h" #include "bridge_loop_avoidance.h"
#include "distributed-arp-table.h" #include "distributed-arp-table.h"
#include "network-coding.h"
static int batadv_route_unicast_packet(struct sk_buff *skb, static int batadv_route_unicast_packet(struct sk_buff *skb,
struct batadv_hard_iface *recv_if); struct batadv_hard_iface *recv_if);
...@@ -860,14 +861,17 @@ static int batadv_route_unicast_packet(struct sk_buff *skb, ...@@ -860,14 +861,17 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
/* decrement ttl */ /* decrement ttl */
unicast_packet->header.ttl--; unicast_packet->header.ttl--;
/* network code packet if possible */
if (batadv_nc_skb_forward(skb, neigh_node, ethhdr)) {
ret = NET_RX_SUCCESS;
} else if (batadv_send_skb_to_orig(skb, orig_node, recv_if)) {
ret = NET_RX_SUCCESS;
/* Update stats counter */ /* Update stats counter */
batadv_inc_counter(bat_priv, BATADV_CNT_FORWARD); batadv_inc_counter(bat_priv, BATADV_CNT_FORWARD);
batadv_add_counter(bat_priv, BATADV_CNT_FORWARD_BYTES, batadv_add_counter(bat_priv, BATADV_CNT_FORWARD_BYTES,
skb->len + ETH_HLEN); skb->len + ETH_HLEN);
}
/* route it */
if (batadv_send_skb_to_orig(skb, orig_node, recv_if))
ret = NET_RX_SUCCESS;
out: out:
if (neigh_node) if (neigh_node)
......
...@@ -442,11 +442,19 @@ struct batadv_priv_dat { ...@@ -442,11 +442,19 @@ struct batadv_priv_dat {
* @work: work queue callback item for cleanup * @work: work queue callback item for cleanup
* @debug_dir: dentry for nc subdir in batman-adv directory in debugfs * @debug_dir: dentry for nc subdir in batman-adv directory in debugfs
* @min_tq: only consider neighbors for encoding if neigh_tq > min_tq * @min_tq: only consider neighbors for encoding if neigh_tq > min_tq
* @max_fwd_delay: maximum packet forward delay to allow coding of packets
* @timestamp_fwd_flush: timestamp of last forward packet queue flush
* @coding_hash: Hash table used to buffer skbs while waiting for another
* incoming skb to code it with. Skbs are added to the buffer just before being
* forwarded in routing.c
*/ */
struct batadv_priv_nc { struct batadv_priv_nc {
struct delayed_work work; struct delayed_work work;
struct dentry *debug_dir; struct dentry *debug_dir;
u8 min_tq; u8 min_tq;
u32 max_fwd_delay;
unsigned long timestamp_fwd_flush;
struct batadv_hashtable *coding_hash;
}; };
/** /**
...@@ -747,6 +755,47 @@ struct batadv_nc_node { ...@@ -747,6 +755,47 @@ struct batadv_nc_node {
unsigned long last_seen; unsigned long last_seen;
}; };
/**
* struct batadv_nc_path - network coding path
* @hash_entry: next and prev pointer for the list handling
* @rcu: struct used for freeing in an RCU-safe manner
* @refcount: number of contexts the object is used by
* @packet_list: list of buffered packets for this path
* @packet_list_lock: access lock for packet list
* @next_hop: next hop (destination) of path
* @prev_hop: previous hop (source) of path
* @last_valid: timestamp for last validation of path
*/
struct batadv_nc_path {
struct hlist_node hash_entry;
struct rcu_head rcu;
atomic_t refcount;
struct list_head packet_list;
spinlock_t packet_list_lock; /* Protects packet_list */
uint8_t next_hop[ETH_ALEN];
uint8_t prev_hop[ETH_ALEN];
unsigned long last_valid;
};
/**
* struct batadv_nc_packet - network coding packet used when coding and
* decoding packets
* @list: next and prev pointer for the list handling
* @packet_id: crc32 checksum of skb data
* @timestamp: field containing the info when the packet was added to path
* @neigh_node: pointer to original next hop neighbor of skb
* @skb: skb which can be encoded or used for decoding
* @nc_path: pointer to path this nc packet is attached to
*/
struct batadv_nc_packet {
struct list_head list;
__be32 packet_id;
unsigned long timestamp;
struct batadv_neigh_node *neigh_node;
struct sk_buff *skb;
struct batadv_nc_path *nc_path;
};
/** /**
* struct batadv_forw_packet - structure for bcast packets to be sent/forwarded * struct batadv_forw_packet - structure for bcast packets to be sent/forwarded
* @list: list node for batadv_socket_client::queue_list * @list: list node for batadv_socket_client::queue_list
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment