Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge
Included changes: - introduction of the new Network Coding component. This new mechanism aims to increase throughput by fusing multiple packets in one transmission. - minor cleanups Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -67,6 +67,14 @@ Description:
|
|||||||
Defines the penalty which will be applied to an
|
Defines the penalty which will be applied to an
|
||||||
originator message's tq-field on every hop.
|
originator message's tq-field on every hop.
|
||||||
|
|
||||||
|
What: /sys/class/net/<mesh_iface>/mesh/network_coding
|
||||||
|
Date: Nov 2012
|
||||||
|
Contact: Martin Hundeboll <martin@hundeboll.net>
|
||||||
|
Description:
|
||||||
|
Controls whether Network Coding (using some magic
|
||||||
|
to send fewer wifi packets but still the same
|
||||||
|
content) is enabled or not.
|
||||||
|
|
||||||
What: /sys/class/net/<mesh_iface>/mesh/orig_interval
|
What: /sys/class/net/<mesh_iface>/mesh/orig_interval
|
||||||
Date: May 2010
|
Date: May 2010
|
||||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
||||||
|
@@ -36,6 +36,20 @@ config BATMAN_ADV_DAT
|
|||||||
mesh networks. If you think that your network does not need
|
mesh networks. If you think that your network does not need
|
||||||
this option you can safely remove it and save some space.
|
this option you can safely remove it and save some space.
|
||||||
|
|
||||||
|
config BATMAN_ADV_NC
|
||||||
|
bool "Network Coding"
|
||||||
|
depends on BATMAN_ADV
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This option enables network coding, a mechanism that aims to
|
||||||
|
increase the overall network throughput by fusing multiple
|
||||||
|
packets in one transmission.
|
||||||
|
Note that interfaces controlled by batman-adv must be manually
|
||||||
|
configured to have promiscuous mode enabled in order to make
|
||||||
|
network coding work.
|
||||||
|
If you think that your network does not need this feature you
|
||||||
|
can safely disable it and save some space.
|
||||||
|
|
||||||
config BATMAN_ADV_DEBUG
|
config BATMAN_ADV_DEBUG
|
||||||
bool "B.A.T.M.A.N. debugging"
|
bool "B.A.T.M.A.N. debugging"
|
||||||
depends on BATMAN_ADV
|
depends on BATMAN_ADV
|
||||||
|
@@ -30,6 +30,7 @@ batman-adv-y += hard-interface.o
|
|||||||
batman-adv-y += hash.o
|
batman-adv-y += hash.o
|
||||||
batman-adv-y += icmp_socket.o
|
batman-adv-y += icmp_socket.o
|
||||||
batman-adv-y += main.o
|
batman-adv-y += main.o
|
||||||
|
batman-adv-$(CONFIG_BATMAN_ADV_NC) += network-coding.o
|
||||||
batman-adv-y += originator.o
|
batman-adv-y += originator.o
|
||||||
batman-adv-y += ring_buffer.o
|
batman-adv-y += ring_buffer.o
|
||||||
batman-adv-y += routing.o
|
batman-adv-y += routing.o
|
||||||
|
@@ -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,
|
|||||||
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 @@
|
|||||||
#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 {
|
|||||||
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);
|
|||||||
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[] = {
|
|||||||
#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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
@@ -816,7 +816,6 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
|
|||||||
bool ret = false;
|
bool ret = false;
|
||||||
struct batadv_dat_entry *dat_entry = NULL;
|
struct batadv_dat_entry *dat_entry = NULL;
|
||||||
struct sk_buff *skb_new;
|
struct sk_buff *skb_new;
|
||||||
struct batadv_hard_iface *primary_if = NULL;
|
|
||||||
|
|
||||||
if (!atomic_read(&bat_priv->distributed_arp_table))
|
if (!atomic_read(&bat_priv->distributed_arp_table))
|
||||||
goto out;
|
goto out;
|
||||||
@@ -838,22 +837,18 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
|
|||||||
|
|
||||||
dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
|
dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
|
||||||
if (dat_entry) {
|
if (dat_entry) {
|
||||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
|
||||||
if (!primary_if)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
|
skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
|
||||||
primary_if->soft_iface, ip_dst, hw_src,
|
bat_priv->soft_iface, ip_dst, hw_src,
|
||||||
dat_entry->mac_addr, hw_src);
|
dat_entry->mac_addr, hw_src);
|
||||||
if (!skb_new)
|
if (!skb_new)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
skb_reset_mac_header(skb_new);
|
skb_reset_mac_header(skb_new);
|
||||||
skb_new->protocol = eth_type_trans(skb_new,
|
skb_new->protocol = eth_type_trans(skb_new,
|
||||||
primary_if->soft_iface);
|
bat_priv->soft_iface);
|
||||||
bat_priv->stats.rx_packets++;
|
bat_priv->stats.rx_packets++;
|
||||||
bat_priv->stats.rx_bytes += skb->len + ETH_HLEN;
|
bat_priv->stats.rx_bytes += skb->len + ETH_HLEN;
|
||||||
primary_if->soft_iface->last_rx = jiffies;
|
bat_priv->soft_iface->last_rx = jiffies;
|
||||||
|
|
||||||
netif_rx(skb_new);
|
netif_rx(skb_new);
|
||||||
batadv_dbg(BATADV_DBG_DAT, bat_priv, "ARP request replied locally\n");
|
batadv_dbg(BATADV_DBG_DAT, bat_priv, "ARP request replied locally\n");
|
||||||
@@ -866,8 +861,6 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
|
|||||||
out:
|
out:
|
||||||
if (dat_entry)
|
if (dat_entry)
|
||||||
batadv_dat_entry_free_ref(dat_entry);
|
batadv_dat_entry_free_ref(dat_entry);
|
||||||
if (primary_if)
|
|
||||||
batadv_hardif_free_ref(primary_if);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -887,7 +880,6 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
|
|||||||
__be32 ip_src, ip_dst;
|
__be32 ip_src, ip_dst;
|
||||||
uint8_t *hw_src;
|
uint8_t *hw_src;
|
||||||
struct sk_buff *skb_new;
|
struct sk_buff *skb_new;
|
||||||
struct batadv_hard_iface *primary_if = NULL;
|
|
||||||
struct batadv_dat_entry *dat_entry = NULL;
|
struct batadv_dat_entry *dat_entry = NULL;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
int err;
|
int err;
|
||||||
@@ -912,12 +904,8 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
|
|||||||
if (!dat_entry)
|
if (!dat_entry)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
|
||||||
if (!primary_if)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
|
skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
|
||||||
primary_if->soft_iface, ip_dst, hw_src,
|
bat_priv->soft_iface, ip_dst, hw_src,
|
||||||
dat_entry->mac_addr, hw_src);
|
dat_entry->mac_addr, hw_src);
|
||||||
|
|
||||||
if (!skb_new)
|
if (!skb_new)
|
||||||
@@ -941,8 +929,6 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
|
|||||||
out:
|
out:
|
||||||
if (dat_entry)
|
if (dat_entry)
|
||||||
batadv_dat_entry_free_ref(dat_entry);
|
batadv_dat_entry_free_ref(dat_entry);
|
||||||
if (primary_if)
|
|
||||||
batadv_hardif_free_ref(primary_if);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return ret;
|
return ret;
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#include "vis.h"
|
#include "vis.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "bat_algo.h"
|
#include "bat_algo.h"
|
||||||
|
#include "network-coding.h"
|
||||||
|
|
||||||
|
|
||||||
/* List manipulations on hardif_list have to be rtnl_lock()'ed,
|
/* List manipulations on hardif_list have to be rtnl_lock()'ed,
|
||||||
@@ -135,6 +136,10 @@ int batadv_mesh_init(struct net_device *soft_iface)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
ret = batadv_nc_init(bat_priv);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
atomic_set(&bat_priv->gw.reselect, 0);
|
atomic_set(&bat_priv->gw.reselect, 0);
|
||||||
atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE);
|
atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE);
|
||||||
|
|
||||||
@@ -157,6 +162,7 @@ void batadv_mesh_free(struct net_device *soft_iface)
|
|||||||
|
|
||||||
batadv_gw_node_purge(bat_priv);
|
batadv_gw_node_purge(bat_priv);
|
||||||
batadv_originator_free(bat_priv);
|
batadv_originator_free(bat_priv);
|
||||||
|
batadv_nc_free(bat_priv);
|
||||||
|
|
||||||
batadv_tt_free(bat_priv);
|
batadv_tt_free(bat_priv);
|
||||||
|
|
||||||
|
@@ -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,
|
||||||
@@ -185,6 +187,7 @@ __be32 batadv_skb_crc32(struct sk_buff *skb, u8 *payload_ptr);
|
|||||||
* @BATADV_DBG_TT: translation table messages
|
* @BATADV_DBG_TT: translation table messages
|
||||||
* @BATADV_DBG_BLA: bridge loop avoidance messages
|
* @BATADV_DBG_BLA: bridge loop avoidance messages
|
||||||
* @BATADV_DBG_DAT: ARP snooping and DAT related messages
|
* @BATADV_DBG_DAT: ARP snooping and DAT related messages
|
||||||
|
* @BATADV_DBG_NC: network coding related messages
|
||||||
* @BATADV_DBG_ALL: the union of all the above log levels
|
* @BATADV_DBG_ALL: the union of all the above log levels
|
||||||
*/
|
*/
|
||||||
enum batadv_dbg_level {
|
enum batadv_dbg_level {
|
||||||
@@ -193,7 +196,8 @@ enum batadv_dbg_level {
|
|||||||
BATADV_DBG_TT = BIT(2),
|
BATADV_DBG_TT = BIT(2),
|
||||||
BATADV_DBG_BLA = BIT(3),
|
BATADV_DBG_BLA = BIT(3),
|
||||||
BATADV_DBG_DAT = BIT(4),
|
BATADV_DBG_DAT = BIT(4),
|
||||||
BATADV_DBG_ALL = 31,
|
BATADV_DBG_NC = BIT(5),
|
||||||
|
BATADV_DBG_ALL = 63,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
||||||
@@ -298,4 +302,10 @@ static inline uint64_t batadv_sum_counter(struct batadv_priv *bat_priv,
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Define a macro to reach the control buffer of the skb. The members of the
|
||||||
|
* control buffer are defined in struct batadv_skb_cb in types.h.
|
||||||
|
* The macro is inspired by the similar macro TCP_SKB_CB() in tcp.h.
|
||||||
|
*/
|
||||||
|
#define BATADV_SKB_CB(__skb) ((struct batadv_skb_cb *)&((__skb)->cb[0]))
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_MAIN_H_ */
|
#endif /* _NET_BATMAN_ADV_MAIN_H_ */
|
||||||
|
1821
net/batman-adv/network-coding.c
Normal file
1821
net/batman-adv/network-coding.c
Normal file
File diff suppressed because it is too large
Load Diff
123
net/batman-adv/network-coding.h
Normal file
123
net/batman-adv/network-coding.h
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/* Copyright (C) 2012-2013 B.A.T.M.A.N. contributors:
|
||||||
|
*
|
||||||
|
* Martin Hundebøll, Jeppe Ledet-Pedersen
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of version 2 of the GNU General Public
|
||||||
|
* License as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NET_BATMAN_ADV_NETWORK_CODING_H_
|
||||||
|
#define _NET_BATMAN_ADV_NETWORK_CODING_H_
|
||||||
|
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_NC
|
||||||
|
|
||||||
|
int batadv_nc_init(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_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);
|
||||||
|
void batadv_nc_skb_store_for_decoding(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb);
|
||||||
|
void batadv_nc_skb_store_sniffed_unicast(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb);
|
||||||
|
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 */
|
||||||
|
|
||||||
|
static inline int batadv_nc_init(struct batadv_priv *bat_priv)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void batadv_nc_free(struct batadv_priv *bat_priv)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void batadv_nc_init_orig(struct batadv_orig_node *orig_node)
|
||||||
|
{
|
||||||
|
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 void
|
||||||
|
batadv_nc_skb_store_for_decoding(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
batadv_nc_skb_store_sniffed_unicast(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
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 /* _NET_BATMAN_ADV_NETWORK_CODING_H_ */
|
@@ -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)
|
|||||||
|
|
||||||
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,
|
|||||||
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);
|
||||||
|
|
||||||
|
@@ -30,6 +30,7 @@ enum batadv_packettype {
|
|||||||
BATADV_TT_QUERY = 0x07,
|
BATADV_TT_QUERY = 0x07,
|
||||||
BATADV_ROAM_ADV = 0x08,
|
BATADV_ROAM_ADV = 0x08,
|
||||||
BATADV_UNICAST_4ADDR = 0x09,
|
BATADV_UNICAST_4ADDR = 0x09,
|
||||||
|
BATADV_CODED = 0x0a,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -278,4 +279,36 @@ struct batadv_tt_change {
|
|||||||
uint8_t addr[ETH_ALEN];
|
uint8_t addr[ETH_ALEN];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct batadv_coded_packet - network coded packet
|
||||||
|
* @header: common batman packet header and ttl of first included packet
|
||||||
|
* @reserved: Align following fields to 2-byte boundaries
|
||||||
|
* @first_source: original source of first included packet
|
||||||
|
* @first_orig_dest: original destinal of first included packet
|
||||||
|
* @first_crc: checksum of first included packet
|
||||||
|
* @first_ttvn: tt-version number of first included packet
|
||||||
|
* @second_ttl: ttl of second packet
|
||||||
|
* @second_dest: second receiver of this coded packet
|
||||||
|
* @second_source: original source of second included packet
|
||||||
|
* @second_orig_dest: original destination of second included packet
|
||||||
|
* @second_crc: checksum of second included packet
|
||||||
|
* @second_ttvn: tt version number of second included packet
|
||||||
|
* @coded_len: length of network coded part of the payload
|
||||||
|
*/
|
||||||
|
struct batadv_coded_packet {
|
||||||
|
struct batadv_header header;
|
||||||
|
uint8_t first_ttvn;
|
||||||
|
/* uint8_t first_dest[ETH_ALEN]; - saved in mac header destination */
|
||||||
|
uint8_t first_source[ETH_ALEN];
|
||||||
|
uint8_t first_orig_dest[ETH_ALEN];
|
||||||
|
__be32 first_crc;
|
||||||
|
uint8_t second_ttl;
|
||||||
|
uint8_t second_ttvn;
|
||||||
|
uint8_t second_dest[ETH_ALEN];
|
||||||
|
uint8_t second_source[ETH_ALEN];
|
||||||
|
uint8_t second_orig_dest[ETH_ALEN];
|
||||||
|
__be32 second_crc;
|
||||||
|
uint16_t coded_len;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_PACKET_H_ */
|
#endif /* _NET_BATMAN_ADV_PACKET_H_ */
|
||||||
|
@@ -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);
|
||||||
@@ -548,27 +549,37 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig,
|
|||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_check_unicast_packet - Check for malformed unicast packets
|
||||||
|
* @skb: packet to check
|
||||||
|
* @hdr_size: size of header to pull
|
||||||
|
*
|
||||||
|
* Check for short header and bad addresses in given packet. Returns negative
|
||||||
|
* value when check fails and 0 otherwise. The negative value depends on the
|
||||||
|
* reason: -ENODATA for bad header, -EBADR for broadcast destination or source,
|
||||||
|
* and -EREMOTE for non-local (other host) destination.
|
||||||
|
*/
|
||||||
static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size)
|
static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size)
|
||||||
{
|
{
|
||||||
struct ethhdr *ethhdr;
|
struct ethhdr *ethhdr;
|
||||||
|
|
||||||
/* drop packet if it has not necessary minimum size */
|
/* drop packet if it has not necessary minimum size */
|
||||||
if (unlikely(!pskb_may_pull(skb, hdr_size)))
|
if (unlikely(!pskb_may_pull(skb, hdr_size)))
|
||||||
return -1;
|
return -ENODATA;
|
||||||
|
|
||||||
ethhdr = (struct ethhdr *)skb_mac_header(skb);
|
ethhdr = (struct ethhdr *)skb_mac_header(skb);
|
||||||
|
|
||||||
/* packet with unicast indication but broadcast recipient */
|
/* packet with unicast indication but broadcast recipient */
|
||||||
if (is_broadcast_ether_addr(ethhdr->h_dest))
|
if (is_broadcast_ether_addr(ethhdr->h_dest))
|
||||||
return -1;
|
return -EBADR;
|
||||||
|
|
||||||
/* packet with broadcast sender address */
|
/* packet with broadcast sender address */
|
||||||
if (is_broadcast_ether_addr(ethhdr->h_source))
|
if (is_broadcast_ether_addr(ethhdr->h_source))
|
||||||
return -1;
|
return -EBADR;
|
||||||
|
|
||||||
/* not for me */
|
/* not for me */
|
||||||
if (!batadv_is_my_mac(ethhdr->h_dest))
|
if (!batadv_is_my_mac(ethhdr->h_dest))
|
||||||
return -1;
|
return -EREMOTE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -850,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)
|
||||||
@@ -1033,7 +1047,7 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
|
|||||||
struct batadv_unicast_4addr_packet *unicast_4addr_packet;
|
struct batadv_unicast_4addr_packet *unicast_4addr_packet;
|
||||||
uint8_t *orig_addr;
|
uint8_t *orig_addr;
|
||||||
struct batadv_orig_node *orig_node = NULL;
|
struct batadv_orig_node *orig_node = NULL;
|
||||||
int hdr_size = sizeof(*unicast_packet);
|
int check, hdr_size = sizeof(*unicast_packet);
|
||||||
bool is4addr;
|
bool is4addr;
|
||||||
|
|
||||||
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
||||||
@@ -1044,7 +1058,16 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
|
|||||||
if (is4addr)
|
if (is4addr)
|
||||||
hdr_size = sizeof(*unicast_4addr_packet);
|
hdr_size = sizeof(*unicast_4addr_packet);
|
||||||
|
|
||||||
if (batadv_check_unicast_packet(skb, hdr_size) < 0)
|
/* function returns -EREMOTE for promiscuous packets */
|
||||||
|
check = batadv_check_unicast_packet(skb, hdr_size);
|
||||||
|
|
||||||
|
/* Even though the packet is not for us, we might save it to use for
|
||||||
|
* decoding a later received coded packet
|
||||||
|
*/
|
||||||
|
if (check == -EREMOTE)
|
||||||
|
batadv_nc_skb_store_sniffed_unicast(bat_priv, skb);
|
||||||
|
|
||||||
|
if (check < 0)
|
||||||
return NET_RX_DROP;
|
return NET_RX_DROP;
|
||||||
|
|
||||||
if (!batadv_check_unicast_ttvn(bat_priv, skb))
|
if (!batadv_check_unicast_ttvn(bat_priv, skb))
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#include "vis.h"
|
#include "vis.h"
|
||||||
#include "gateway_common.h"
|
#include "gateway_common.h"
|
||||||
#include "originator.h"
|
#include "originator.h"
|
||||||
|
#include "network-coding.h"
|
||||||
|
|
||||||
#include <linux/if_ether.h>
|
#include <linux/if_ether.h>
|
||||||
|
|
||||||
@@ -39,6 +40,7 @@ int batadv_send_skb_packet(struct sk_buff *skb,
|
|||||||
struct batadv_hard_iface *hard_iface,
|
struct batadv_hard_iface *hard_iface,
|
||||||
const uint8_t *dst_addr)
|
const uint8_t *dst_addr)
|
||||||
{
|
{
|
||||||
|
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
|
||||||
struct ethhdr *ethhdr;
|
struct ethhdr *ethhdr;
|
||||||
|
|
||||||
if (hard_iface->if_status != BATADV_IF_ACTIVE)
|
if (hard_iface->if_status != BATADV_IF_ACTIVE)
|
||||||
@@ -70,6 +72,9 @@ int batadv_send_skb_packet(struct sk_buff *skb,
|
|||||||
|
|
||||||
skb->dev = hard_iface->net_dev;
|
skb->dev = hard_iface->net_dev;
|
||||||
|
|
||||||
|
/* Save a clone of the skb to use when decoding coded packets */
|
||||||
|
batadv_nc_skb_store_for_decoding(bat_priv, skb);
|
||||||
|
|
||||||
/* dev_queue_xmit() returns a negative result on error. However on
|
/* dev_queue_xmit() returns a negative result on error. However on
|
||||||
* congestion and traffic shaping, it drops and returns NET_XMIT_DROP
|
* congestion and traffic shaping, it drops and returns NET_XMIT_DROP
|
||||||
* (which is > 0). This will not be treated as an error.
|
* (which is > 0). This will not be treated as an error.
|
||||||
|
@@ -37,6 +37,7 @@
|
|||||||
#include <linux/if_ether.h>
|
#include <linux/if_ether.h>
|
||||||
#include "unicast.h"
|
#include "unicast.h"
|
||||||
#include "bridge_loop_avoidance.h"
|
#include "bridge_loop_avoidance.h"
|
||||||
|
#include "network-coding.h"
|
||||||
|
|
||||||
|
|
||||||
static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
|
static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
|
||||||
@@ -544,6 +545,8 @@ struct net_device *batadv_softif_create(const char *name)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto unreg_soft_iface;
|
goto unreg_soft_iface;
|
||||||
|
|
||||||
|
batadv_nc_init_bat_priv(bat_priv);
|
||||||
|
|
||||||
ret = batadv_sysfs_add_meshif(soft_iface);
|
ret = batadv_sysfs_add_meshif(soft_iface);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto unreg_soft_iface;
|
goto unreg_soft_iface;
|
||||||
@@ -662,6 +665,17 @@ static const struct {
|
|||||||
{ "dat_put_rx" },
|
{ "dat_put_rx" },
|
||||||
{ "dat_cached_reply_tx" },
|
{ "dat_cached_reply_tx" },
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_NC
|
||||||
|
{ "nc_code" },
|
||||||
|
{ "nc_code_bytes" },
|
||||||
|
{ "nc_recode" },
|
||||||
|
{ "nc_recode_bytes" },
|
||||||
|
{ "nc_buffer" },
|
||||||
|
{ "nc_decode" },
|
||||||
|
{ "nc_decode_bytes" },
|
||||||
|
{ "nc_decode_failed" },
|
||||||
|
{ "nc_sniffed" },
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static void batadv_get_strings(struct net_device *dev, uint32_t stringset,
|
static void batadv_get_strings(struct net_device *dev, uint32_t stringset,
|
||||||
|
@@ -442,6 +442,9 @@ static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth,
|
|||||||
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
||||||
BATADV_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, BATADV_DBG_ALL, NULL);
|
BATADV_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, BATADV_DBG_ALL, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_NC
|
||||||
|
BATADV_ATTR_SIF_BOOL(network_coding, S_IRUGO | S_IWUSR, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct batadv_attribute *batadv_mesh_attrs[] = {
|
static struct batadv_attribute *batadv_mesh_attrs[] = {
|
||||||
&batadv_attr_aggregated_ogms,
|
&batadv_attr_aggregated_ogms,
|
||||||
@@ -463,6 +466,9 @@ static struct batadv_attribute *batadv_mesh_attrs[] = {
|
|||||||
&batadv_attr_gw_bandwidth,
|
&batadv_attr_gw_bandwidth,
|
||||||
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
||||||
&batadv_attr_log_level,
|
&batadv_attr_log_level,
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_NC
|
||||||
|
&batadv_attr_network_coding,
|
||||||
#endif
|
#endif
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
@@ -688,15 +694,10 @@ int batadv_throw_uevent(struct batadv_priv *bat_priv, enum batadv_uev_type type,
|
|||||||
enum batadv_uev_action action, const char *data)
|
enum batadv_uev_action action, const char *data)
|
||||||
{
|
{
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
struct batadv_hard_iface *primary_if;
|
|
||||||
struct kobject *bat_kobj;
|
struct kobject *bat_kobj;
|
||||||
char *uevent_env[4] = { NULL, NULL, NULL, NULL };
|
char *uevent_env[4] = { NULL, NULL, NULL, NULL };
|
||||||
|
|
||||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
bat_kobj = &bat_priv->soft_iface->dev.kobj;
|
||||||
if (!primary_if)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
bat_kobj = &primary_if->soft_iface->dev.kobj;
|
|
||||||
|
|
||||||
uevent_env[0] = kmalloc(strlen(BATADV_UEV_TYPE_VAR) +
|
uevent_env[0] = kmalloc(strlen(BATADV_UEV_TYPE_VAR) +
|
||||||
strlen(batadv_uev_type_str[type]) + 1,
|
strlen(batadv_uev_type_str[type]) + 1,
|
||||||
@@ -732,9 +733,6 @@ out:
|
|||||||
kfree(uevent_env[1]);
|
kfree(uevent_env[1]);
|
||||||
kfree(uevent_env[2]);
|
kfree(uevent_env[2]);
|
||||||
|
|
||||||
if (primary_if)
|
|
||||||
batadv_hardif_free_ref(primary_if);
|
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
|
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
|
||||||
"Impossible to send uevent for (%s,%s,%s) event (err: %d)\n",
|
"Impossible to send uevent for (%s,%s,%s) event (err: %d)\n",
|
||||||
|
@@ -385,25 +385,19 @@ static void batadv_tt_prepare_packet_buff(struct batadv_priv *bat_priv,
|
|||||||
int *packet_buff_len,
|
int *packet_buff_len,
|
||||||
int min_packet_len)
|
int min_packet_len)
|
||||||
{
|
{
|
||||||
struct batadv_hard_iface *primary_if;
|
|
||||||
int req_len;
|
int req_len;
|
||||||
|
|
||||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
|
||||||
|
|
||||||
req_len = min_packet_len;
|
req_len = min_packet_len;
|
||||||
req_len += batadv_tt_len(atomic_read(&bat_priv->tt.local_changes));
|
req_len += batadv_tt_len(atomic_read(&bat_priv->tt.local_changes));
|
||||||
|
|
||||||
/* if we have too many changes for one packet don't send any
|
/* if we have too many changes for one packet don't send any
|
||||||
* and wait for the tt table request which will be fragmented
|
* and wait for the tt table request which will be fragmented
|
||||||
*/
|
*/
|
||||||
if ((!primary_if) || (req_len > primary_if->soft_iface->mtu))
|
if (req_len > bat_priv->soft_iface->mtu)
|
||||||
req_len = min_packet_len;
|
req_len = min_packet_len;
|
||||||
|
|
||||||
batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len,
|
batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len,
|
||||||
min_packet_len, req_len);
|
min_packet_len, req_len);
|
||||||
|
|
||||||
if (primary_if)
|
|
||||||
batadv_hardif_free_ref(primary_if);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv,
|
static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv,
|
||||||
@@ -908,7 +902,7 @@ out_remove:
|
|||||||
/* remove address from local hash if present */
|
/* remove address from local hash if present */
|
||||||
local_flags = batadv_tt_local_remove(bat_priv, tt_addr,
|
local_flags = batadv_tt_local_remove(bat_priv, tt_addr,
|
||||||
"global tt received",
|
"global tt received",
|
||||||
!!(flags & BATADV_TT_CLIENT_ROAM));
|
flags & BATADV_TT_CLIENT_ROAM);
|
||||||
tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI;
|
tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI;
|
||||||
|
|
||||||
if (!(flags & BATADV_TT_CLIENT_ROAM))
|
if (!(flags & BATADV_TT_CLIENT_ROAM))
|
||||||
@@ -1580,7 +1574,7 @@ static int batadv_tt_global_valid(const void *entry_ptr,
|
|||||||
static struct sk_buff *
|
static struct sk_buff *
|
||||||
batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
|
batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
|
||||||
struct batadv_hashtable *hash,
|
struct batadv_hashtable *hash,
|
||||||
struct batadv_hard_iface *primary_if,
|
struct batadv_priv *bat_priv,
|
||||||
int (*valid_cb)(const void *, const void *),
|
int (*valid_cb)(const void *, const void *),
|
||||||
void *cb_data)
|
void *cb_data)
|
||||||
{
|
{
|
||||||
@@ -1594,8 +1588,8 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
|
|||||||
uint32_t i;
|
uint32_t i;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if (tt_query_size + tt_len > primary_if->soft_iface->mtu) {
|
if (tt_query_size + tt_len > bat_priv->soft_iface->mtu) {
|
||||||
tt_len = primary_if->soft_iface->mtu - tt_query_size;
|
tt_len = bat_priv->soft_iface->mtu - tt_query_size;
|
||||||
tt_len -= tt_len % sizeof(struct batadv_tt_change);
|
tt_len -= tt_len % sizeof(struct batadv_tt_change);
|
||||||
}
|
}
|
||||||
tt_tot = tt_len / sizeof(struct batadv_tt_change);
|
tt_tot = tt_len / sizeof(struct batadv_tt_change);
|
||||||
@@ -1715,7 +1709,6 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
|
|||||||
{
|
{
|
||||||
struct batadv_orig_node *req_dst_orig_node;
|
struct batadv_orig_node *req_dst_orig_node;
|
||||||
struct batadv_orig_node *res_dst_orig_node = NULL;
|
struct batadv_orig_node *res_dst_orig_node = NULL;
|
||||||
struct batadv_hard_iface *primary_if = NULL;
|
|
||||||
uint8_t orig_ttvn, req_ttvn, ttvn;
|
uint8_t orig_ttvn, req_ttvn, ttvn;
|
||||||
int ret = false;
|
int ret = false;
|
||||||
unsigned char *tt_buff;
|
unsigned char *tt_buff;
|
||||||
@@ -1740,10 +1733,6 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
|
|||||||
if (!res_dst_orig_node)
|
if (!res_dst_orig_node)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
|
||||||
if (!primary_if)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
|
orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
|
||||||
req_ttvn = tt_request->ttvn;
|
req_ttvn = tt_request->ttvn;
|
||||||
|
|
||||||
@@ -1791,7 +1780,7 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
|
|||||||
|
|
||||||
skb = batadv_tt_response_fill_table(tt_len, ttvn,
|
skb = batadv_tt_response_fill_table(tt_len, ttvn,
|
||||||
bat_priv->tt.global_hash,
|
bat_priv->tt.global_hash,
|
||||||
primary_if,
|
bat_priv,
|
||||||
batadv_tt_global_valid,
|
batadv_tt_global_valid,
|
||||||
req_dst_orig_node);
|
req_dst_orig_node);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
@@ -1828,8 +1817,6 @@ out:
|
|||||||
batadv_orig_node_free_ref(res_dst_orig_node);
|
batadv_orig_node_free_ref(res_dst_orig_node);
|
||||||
if (req_dst_orig_node)
|
if (req_dst_orig_node)
|
||||||
batadv_orig_node_free_ref(req_dst_orig_node);
|
batadv_orig_node_free_ref(req_dst_orig_node);
|
||||||
if (primary_if)
|
|
||||||
batadv_hardif_free_ref(primary_if);
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1907,7 +1894,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
|
|||||||
|
|
||||||
skb = batadv_tt_response_fill_table(tt_len, ttvn,
|
skb = batadv_tt_response_fill_table(tt_len, ttvn,
|
||||||
bat_priv->tt.local_hash,
|
bat_priv->tt.local_hash,
|
||||||
primary_if,
|
bat_priv,
|
||||||
batadv_tt_local_valid_entry,
|
batadv_tt_local_valid_entry,
|
||||||
NULL);
|
NULL);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
@@ -2528,7 +2515,7 @@ bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
|
|||||||
if (!tt_global_entry)
|
if (!tt_global_entry)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = !!(tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM);
|
ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM;
|
||||||
batadv_tt_global_entry_free_ref(tt_global_entry);
|
batadv_tt_global_entry_free_ref(tt_global_entry);
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
@@ -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 {
|
|||||||
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
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -265,6 +275,17 @@ struct batadv_bcast_duplist_entry {
|
|||||||
* @BATADV_CNT_DAT_PUT_RX: received dht PUT traffic packet counter
|
* @BATADV_CNT_DAT_PUT_RX: received dht PUT traffic packet counter
|
||||||
* @BATADV_CNT_DAT_CACHED_REPLY_TX: transmitted dat cache reply traffic packet
|
* @BATADV_CNT_DAT_CACHED_REPLY_TX: transmitted dat cache reply traffic packet
|
||||||
* counter
|
* counter
|
||||||
|
* @BATADV_CNT_NC_CODE: transmitted nc-combined traffic packet counter
|
||||||
|
* @BATADV_CNT_NC_CODE_BYTES: transmitted nc-combined traffic bytes counter
|
||||||
|
* @BATADV_CNT_NC_RECODE: transmitted nc-recombined traffic packet counter
|
||||||
|
* @BATADV_CNT_NC_RECODE_BYTES: transmitted nc-recombined traffic bytes counter
|
||||||
|
* @BATADV_CNT_NC_BUFFER: counter for packets buffered for later nc decoding
|
||||||
|
* @BATADV_CNT_NC_DECODE: received and nc-decoded traffic packet counter
|
||||||
|
* @BATADV_CNT_NC_DECODE_BYTES: received and nc-decoded traffic bytes counter
|
||||||
|
* @BATADV_CNT_NC_DECODE_FAILED: received and decode-failed traffic packet
|
||||||
|
* counter
|
||||||
|
* @BATADV_CNT_NC_SNIFFED: counter for nc-decoded packets received in promisc
|
||||||
|
* mode.
|
||||||
* @BATADV_CNT_NUM: number of traffic counters
|
* @BATADV_CNT_NUM: number of traffic counters
|
||||||
*/
|
*/
|
||||||
enum batadv_counters {
|
enum batadv_counters {
|
||||||
@@ -291,6 +312,17 @@ enum batadv_counters {
|
|||||||
BATADV_CNT_DAT_PUT_TX,
|
BATADV_CNT_DAT_PUT_TX,
|
||||||
BATADV_CNT_DAT_PUT_RX,
|
BATADV_CNT_DAT_PUT_RX,
|
||||||
BATADV_CNT_DAT_CACHED_REPLY_TX,
|
BATADV_CNT_DAT_CACHED_REPLY_TX,
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_NC
|
||||||
|
BATADV_CNT_NC_CODE,
|
||||||
|
BATADV_CNT_NC_CODE_BYTES,
|
||||||
|
BATADV_CNT_NC_RECODE,
|
||||||
|
BATADV_CNT_NC_RECODE_BYTES,
|
||||||
|
BATADV_CNT_NC_BUFFER,
|
||||||
|
BATADV_CNT_NC_DECODE,
|
||||||
|
BATADV_CNT_NC_DECODE_BYTES,
|
||||||
|
BATADV_CNT_NC_DECODE_FAILED,
|
||||||
|
BATADV_CNT_NC_SNIFFED,
|
||||||
#endif
|
#endif
|
||||||
BATADV_CNT_NUM,
|
BATADV_CNT_NUM,
|
||||||
};
|
};
|
||||||
@@ -427,6 +459,35 @@ struct batadv_priv_dat {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct batadv_priv_nc - per mesh interface network coding private data
|
||||||
|
* @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
|
||||||
|
* @max_fwd_delay: maximum packet forward delay to allow coding of packets
|
||||||
|
* @max_buffer_time: buffer time for sniffed packets used to decoding
|
||||||
|
* @timestamp_fwd_flush: timestamp of last forward packet queue flush
|
||||||
|
* @timestamp_sniffed_purge: timestamp of last sniffed packet queue purge
|
||||||
|
* @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
|
||||||
|
* @decoding_hash: Hash table used to buffer skbs that might be needed to decode
|
||||||
|
* a received coded skb. The buffer is used for 1) skbs arriving on the
|
||||||
|
* soft-interface; 2) skbs overheard on the hard-interface; and 3) skbs
|
||||||
|
* forwarded by batman-adv.
|
||||||
|
*/
|
||||||
|
struct batadv_priv_nc {
|
||||||
|
struct delayed_work work;
|
||||||
|
struct dentry *debug_dir;
|
||||||
|
u8 min_tq;
|
||||||
|
u32 max_fwd_delay;
|
||||||
|
u32 max_buffer_time;
|
||||||
|
unsigned long timestamp_fwd_flush;
|
||||||
|
unsigned long timestamp_sniffed_purge;
|
||||||
|
struct batadv_hashtable *coding_hash;
|
||||||
|
struct batadv_hashtable *decoding_hash;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct batadv_priv - per mesh interface data
|
* struct batadv_priv - per mesh interface data
|
||||||
* @mesh_state: current status of the mesh (inactive/active/deactivating)
|
* @mesh_state: current status of the mesh (inactive/active/deactivating)
|
||||||
@@ -470,6 +531,8 @@ struct batadv_priv_dat {
|
|||||||
* @tt: translation table data
|
* @tt: translation table data
|
||||||
* @vis: vis data
|
* @vis: vis data
|
||||||
* @dat: distributed arp table data
|
* @dat: distributed arp table data
|
||||||
|
* @network_coding: bool indicating whether network coding is enabled
|
||||||
|
* @batadv_priv_nc: network coding data
|
||||||
*/
|
*/
|
||||||
struct batadv_priv {
|
struct batadv_priv {
|
||||||
atomic_t mesh_state;
|
atomic_t mesh_state;
|
||||||
@@ -522,6 +585,10 @@ struct batadv_priv {
|
|||||||
#ifdef CONFIG_BATMAN_ADV_DAT
|
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||||
struct batadv_priv_dat dat;
|
struct batadv_priv_dat dat;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_NC
|
||||||
|
atomic_t network_coding;
|
||||||
|
struct batadv_priv_nc nc;
|
||||||
|
#endif /* CONFIG_BATMAN_ADV_NC */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -701,6 +768,75 @@ 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_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;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_skb_cb - control buffer structure used to store private data relevant
|
||||||
|
* to batman-adv in the skb->cb buffer in skbs.
|
||||||
|
* @decoded: Marks a skb as decoded, which is checked when searching for coding
|
||||||
|
* opportunities in network-coding.c
|
||||||
|
*/
|
||||||
|
struct batadv_skb_cb {
|
||||||
|
bool decoded;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
|
@@ -122,7 +122,7 @@ batadv_frag_search_packet(struct list_head *head,
|
|||||||
{
|
{
|
||||||
struct batadv_frag_packet_list_entry *tfp;
|
struct batadv_frag_packet_list_entry *tfp;
|
||||||
struct batadv_unicast_frag_packet *tmp_up = NULL;
|
struct batadv_unicast_frag_packet *tmp_up = NULL;
|
||||||
int is_head_tmp, is_head;
|
bool is_head_tmp, is_head;
|
||||||
uint16_t search_seqno;
|
uint16_t search_seqno;
|
||||||
|
|
||||||
if (up->flags & BATADV_UNI_FRAG_HEAD)
|
if (up->flags & BATADV_UNI_FRAG_HEAD)
|
||||||
@@ -130,7 +130,7 @@ batadv_frag_search_packet(struct list_head *head,
|
|||||||
else
|
else
|
||||||
search_seqno = ntohs(up->seqno)-1;
|
search_seqno = ntohs(up->seqno)-1;
|
||||||
|
|
||||||
is_head = !!(up->flags & BATADV_UNI_FRAG_HEAD);
|
is_head = up->flags & BATADV_UNI_FRAG_HEAD;
|
||||||
|
|
||||||
list_for_each_entry(tfp, head, list) {
|
list_for_each_entry(tfp, head, list) {
|
||||||
if (!tfp->skb)
|
if (!tfp->skb)
|
||||||
@@ -142,7 +142,7 @@ batadv_frag_search_packet(struct list_head *head,
|
|||||||
tmp_up = (struct batadv_unicast_frag_packet *)tfp->skb->data;
|
tmp_up = (struct batadv_unicast_frag_packet *)tfp->skb->data;
|
||||||
|
|
||||||
if (tfp->seqno == search_seqno) {
|
if (tfp->seqno == search_seqno) {
|
||||||
is_head_tmp = !!(tmp_up->flags & BATADV_UNI_FRAG_HEAD);
|
is_head_tmp = tmp_up->flags & BATADV_UNI_FRAG_HEAD;
|
||||||
if (is_head_tmp != is_head)
|
if (is_head_tmp != is_head)
|
||||||
return tfp;
|
return tfp;
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user