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

batman-adv: network coding - detect coding nodes and remove these after timeout

To use network coding efficiently, a relay must know when neighbor nodes
are likely to have enough information to be able to decode a network
coded packet. This is detected by using OGMs from batman-adv to discover
when one neighbor is in range of another neighbor. The relay check the
TLL to detect when an OGM is forwarded from one neighbor by another
neighbor, and thereby knows that the two neighbors are in range and thus
overhear packets sent by each other.

This information is saved in the orig_node struct to be used when
searching for coding opportunities. Two lists are added to the
orig_node struct: One for neighbors that can hear the orig_node
(outgoing nc_nodes) and one for neighbors that the orig_node can hear
(incoming nc_nodes).

Information about nc_nodes is kept for 10 seconds and is available
through debugfs in batman_adv/nc_nodes to use when debugging network
coding.
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 d353d8d4
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "hard-interface.h" #include "hard-interface.h"
#include "send.h" #include "send.h"
#include "bat_algo.h" #include "bat_algo.h"
#include "network-coding.h"
static struct batadv_neigh_node * static struct batadv_neigh_node *
batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
...@@ -1185,6 +1186,10 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, ...@@ -1185,6 +1186,10 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
if (!orig_neigh_node) if (!orig_neigh_node)
goto out; goto out;
/* Update nc_nodes of the originator */
batadv_nc_update_nc_node(bat_priv, orig_node, orig_neigh_node,
batadv_ogm_packet, is_single_hop_neigh);
orig_neigh_router = batadv_orig_node_get_router(orig_neigh_node); orig_neigh_router = batadv_orig_node_get_router(orig_neigh_node);
/* drop packet if sender is not a direct neighbor and if we /* drop packet if sender is not a direct neighbor and if we
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "icmp_socket.h" #include "icmp_socket.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 struct dentry *batadv_debugfs; static struct dentry *batadv_debugfs;
...@@ -310,6 +311,14 @@ struct batadv_debuginfo { ...@@ -310,6 +311,14 @@ struct batadv_debuginfo {
const struct file_operations fops; const struct file_operations fops;
}; };
#ifdef CONFIG_BATMAN_ADV_NC
static int batadv_nc_nodes_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
return single_open(file, batadv_nc_nodes_seq_print_text, net_dev);
}
#endif
#define BATADV_DEBUGINFO(_name, _mode, _open) \ #define BATADV_DEBUGINFO(_name, _mode, _open) \
struct batadv_debuginfo batadv_debuginfo_##_name = { \ struct batadv_debuginfo batadv_debuginfo_##_name = { \
.attr = { .name = __stringify(_name), \ .attr = { .name = __stringify(_name), \
...@@ -348,6 +357,9 @@ static BATADV_DEBUGINFO(dat_cache, S_IRUGO, batadv_dat_cache_open); ...@@ -348,6 +357,9 @@ static BATADV_DEBUGINFO(dat_cache, S_IRUGO, batadv_dat_cache_open);
static BATADV_DEBUGINFO(transtable_local, S_IRUGO, static BATADV_DEBUGINFO(transtable_local, S_IRUGO,
batadv_transtable_local_open); batadv_transtable_local_open);
static BATADV_DEBUGINFO(vis_data, S_IRUGO, batadv_vis_data_open); static BATADV_DEBUGINFO(vis_data, S_IRUGO, batadv_vis_data_open);
#ifdef CONFIG_BATMAN_ADV_NC
static BATADV_DEBUGINFO(nc_nodes, S_IRUGO, batadv_nc_nodes_open);
#endif
static struct batadv_debuginfo *batadv_mesh_debuginfos[] = { static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
&batadv_debuginfo_originators, &batadv_debuginfo_originators,
...@@ -362,6 +374,9 @@ static struct batadv_debuginfo *batadv_mesh_debuginfos[] = { ...@@ -362,6 +374,9 @@ static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
#endif #endif
&batadv_debuginfo_transtable_local, &batadv_debuginfo_transtable_local,
&batadv_debuginfo_vis_data, &batadv_debuginfo_vis_data,
#ifdef CONFIG_BATMAN_ADV_NC
&batadv_debuginfo_nc_nodes,
#endif
NULL, NULL,
}; };
...@@ -431,6 +446,9 @@ int batadv_debugfs_add_meshif(struct net_device *dev) ...@@ -431,6 +446,9 @@ int batadv_debugfs_add_meshif(struct net_device *dev)
} }
} }
if (batadv_nc_init_debugfs(bat_priv) < 0)
goto rem_attr;
return 0; return 0;
rem_attr: rem_attr:
debugfs_remove_recursive(bat_priv->debug_dir); debugfs_remove_recursive(bat_priv->debug_dir);
......
...@@ -105,6 +105,8 @@ ...@@ -105,6 +105,8 @@
#define BATADV_RESET_PROTECTION_MS 30000 #define BATADV_RESET_PROTECTION_MS 30000
#define BATADV_EXPECTED_SEQNO_RANGE 65536 #define BATADV_EXPECTED_SEQNO_RANGE 65536
#define BATADV_NC_NODE_TIMEOUT 10000 /* Milliseconds */
enum batadv_mesh_state { enum batadv_mesh_state {
BATADV_MESH_INACTIVE, BATADV_MESH_INACTIVE,
BATADV_MESH_ACTIVE, BATADV_MESH_ACTIVE,
......
This diff is collapsed.
...@@ -24,7 +24,19 @@ ...@@ -24,7 +24,19 @@
int batadv_nc_init(struct batadv_priv *bat_priv); int batadv_nc_init(struct batadv_priv *bat_priv);
void batadv_nc_free(struct batadv_priv *bat_priv); void batadv_nc_free(struct batadv_priv *bat_priv);
void batadv_nc_update_nc_node(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
struct batadv_orig_node *orig_neigh_node,
struct batadv_ogm_packet *ogm_packet,
int is_single_hop_neigh);
void batadv_nc_purge_orig(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
bool (*to_purge)(struct batadv_priv *,
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);
int batadv_nc_nodes_seq_print_text(struct seq_file *seq, void *offset);
int batadv_nc_init_debugfs(struct batadv_priv *bat_priv);
#else /* ifdef CONFIG_BATMAN_ADV_NC */ #else /* ifdef CONFIG_BATMAN_ADV_NC */
...@@ -38,11 +50,46 @@ static inline void batadv_nc_free(struct batadv_priv *bat_priv) ...@@ -38,11 +50,46 @@ static inline void batadv_nc_free(struct batadv_priv *bat_priv)
return; return;
} }
static inline void
batadv_nc_update_nc_node(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
struct batadv_orig_node *orig_neigh_node,
struct batadv_ogm_packet *ogm_packet,
int is_single_hop_neigh)
{
return;
}
static inline void
batadv_nc_purge_orig(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
bool (*to_purge)(struct batadv_priv *,
struct batadv_nc_node *))
{
return;
}
static inline void batadv_nc_init_bat_priv(struct batadv_priv *bat_priv) static inline void batadv_nc_init_bat_priv(struct batadv_priv *bat_priv)
{ {
return; return;
} }
static inline void batadv_nc_init_orig(struct batadv_orig_node *orig_node)
{
return;
}
static inline int batadv_nc_nodes_seq_print_text(struct seq_file *seq,
void *offset)
{
return 0;
}
static inline int batadv_nc_init_debugfs(struct batadv_priv *bat_priv)
{
return 0;
}
#endif /* ifdef CONFIG_BATMAN_ADV_NC */ #endif /* ifdef CONFIG_BATMAN_ADV_NC */
#endif /* _NET_BATMAN_ADV_NETWORK_CODING_H_ */ #endif /* _NET_BATMAN_ADV_NETWORK_CODING_H_ */
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "unicast.h" #include "unicast.h"
#include "soft-interface.h" #include "soft-interface.h"
#include "bridge_loop_avoidance.h" #include "bridge_loop_avoidance.h"
#include "network-coding.h"
/* hash class keys */ /* hash class keys */
static struct lock_class_key batadv_orig_hash_lock_class_key; static struct lock_class_key batadv_orig_hash_lock_class_key;
...@@ -142,6 +143,9 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu) ...@@ -142,6 +143,9 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
spin_unlock_bh(&orig_node->neigh_list_lock); spin_unlock_bh(&orig_node->neigh_list_lock);
/* Free nc_nodes */
batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL);
batadv_frag_list_free(&orig_node->frag_list); batadv_frag_list_free(&orig_node->frag_list);
batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, batadv_tt_global_del_orig(orig_node->bat_priv, orig_node,
"originator timed out"); "originator timed out");
...@@ -219,6 +223,8 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv, ...@@ -219,6 +223,8 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
spin_lock_init(&orig_node->neigh_list_lock); spin_lock_init(&orig_node->neigh_list_lock);
spin_lock_init(&orig_node->tt_buff_lock); spin_lock_init(&orig_node->tt_buff_lock);
batadv_nc_init_orig(orig_node);
/* extra reference for return */ /* extra reference for return */
atomic_set(&orig_node->refcount, 2); atomic_set(&orig_node->refcount, 2);
......
...@@ -128,6 +128,10 @@ struct batadv_hard_iface { ...@@ -128,6 +128,10 @@ struct batadv_hard_iface {
* @bond_list: list of bonding candidates * @bond_list: list of bonding candidates
* @refcount: number of contexts the object is used * @refcount: number of contexts the object is used
* @rcu: struct used for freeing in an RCU-safe manner * @rcu: struct used for freeing in an RCU-safe manner
* @in_coding_list: list of nodes this orig can hear
* @out_coding_list: list of nodes that can hear this orig
* @in_coding_list_lock: protects in_coding_list
* @out_coding_list_lock: protects out_coding_list
*/ */
struct batadv_orig_node { struct batadv_orig_node {
uint8_t orig[ETH_ALEN]; uint8_t orig[ETH_ALEN];
...@@ -171,6 +175,12 @@ struct batadv_orig_node { ...@@ -171,6 +175,12 @@ struct batadv_orig_node {
struct list_head bond_list; struct list_head bond_list;
atomic_t refcount; atomic_t refcount;
struct rcu_head rcu; struct rcu_head rcu;
#ifdef CONFIG_BATMAN_ADV_NC
struct list_head in_coding_list;
struct list_head out_coding_list;
spinlock_t in_coding_list_lock; /* Protects in_coding_list */
spinlock_t out_coding_list_lock; /* Protects out_coding_list */
#endif
}; };
/** /**
...@@ -430,9 +440,13 @@ struct batadv_priv_dat { ...@@ -430,9 +440,13 @@ struct batadv_priv_dat {
/** /**
* struct batadv_priv_nc - per mesh interface network coding private data * struct batadv_priv_nc - per mesh interface network coding private data
* @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
* @min_tq: only consider neighbors for encoding if neigh_tq > min_tq
*/ */
struct batadv_priv_nc { struct batadv_priv_nc {
struct delayed_work work; struct delayed_work work;
struct dentry *debug_dir;
u8 min_tq;
}; };
/** /**
...@@ -715,6 +729,24 @@ struct batadv_tt_roam_node { ...@@ -715,6 +729,24 @@ struct batadv_tt_roam_node {
struct list_head list; struct list_head list;
}; };
/**
* struct batadv_nc_node - network coding node
* @list: next and prev pointer for the list handling
* @addr: the node's mac address
* @refcount: number of contexts the object is used by
* @rcu: struct used for freeing in an RCU-safe manner
* @orig_node: pointer to corresponding orig node struct
* @last_seen: timestamp of last ogm received from this node
*/
struct batadv_nc_node {
struct list_head list;
uint8_t addr[ETH_ALEN];
atomic_t refcount;
struct rcu_head rcu;
struct batadv_orig_node *orig_node;
unsigned long last_seen;
};
/** /**
* 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