Included changes:
- Increase batman-adv version - Bridge Loop Avoidance: compute checksum (using crc32) on skb fragments instead of linearising it - sort the sysfs documentation - some other minor cleanups -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iEYEABECAAYFAlCsvK0ACgkQpGgxIkP9cwfqxACeOAPgCi+t6skliCgCmvsxU0GZ shkAoJA7K4n6cqCzVz89xixoLWb2WOdg =uoM7 -----END PGP SIGNATURE----- Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge Included changes: - Increase batman-adv version - Bridge Loop Avoidance: compute checksum (using crc32) on skb fragments instead of linearising it - sort the sysfs documentation - some other minor cleanups Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
76e0d67a08
16 changed files with 268 additions and 194 deletions
|
@ -1,4 +1,10 @@
|
||||||
|
|
||||||
|
What: /sys/class/net/<iface>/batman-adv/iface_status
|
||||||
|
Date: May 2010
|
||||||
|
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
||||||
|
Description:
|
||||||
|
Indicates the status of <iface> as it is seen by batman.
|
||||||
|
|
||||||
What: /sys/class/net/<iface>/batman-adv/mesh_iface
|
What: /sys/class/net/<iface>/batman-adv/mesh_iface
|
||||||
Date: May 2010
|
Date: May 2010
|
||||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
||||||
|
@ -7,8 +13,3 @@ Description:
|
||||||
displays the batman mesh interface this <iface>
|
displays the batman mesh interface this <iface>
|
||||||
currently is associated with.
|
currently is associated with.
|
||||||
|
|
||||||
What: /sys/class/net/<iface>/batman-adv/iface_status
|
|
||||||
Date: May 2010
|
|
||||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
|
||||||
Description:
|
|
||||||
Indicates the status of <iface> as it is seen by batman.
|
|
||||||
|
|
|
@ -6,6 +6,14 @@ Description:
|
||||||
Indicates whether the batman protocol messages of the
|
Indicates whether the batman protocol messages of the
|
||||||
mesh <mesh_iface> shall be aggregated or not.
|
mesh <mesh_iface> shall be aggregated or not.
|
||||||
|
|
||||||
|
What: /sys/class/net/<mesh_iface>/mesh/ap_isolation
|
||||||
|
Date: May 2011
|
||||||
|
Contact: Antonio Quartulli <ordex@autistici.org>
|
||||||
|
Description:
|
||||||
|
Indicates whether the data traffic going from a
|
||||||
|
wireless client to another wireless client will be
|
||||||
|
silently dropped.
|
||||||
|
|
||||||
What: /sys/class/net/<mesh_iface>/mesh/bonding
|
What: /sys/class/net/<mesh_iface>/mesh/bonding
|
||||||
Date: June 2010
|
Date: June 2010
|
||||||
Contact: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
|
Contact: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
|
||||||
|
@ -31,14 +39,6 @@ Description:
|
||||||
mesh will be fragmented or silently discarded if the
|
mesh will be fragmented or silently discarded if the
|
||||||
packet size exceeds the outgoing interface MTU.
|
packet size exceeds the outgoing interface MTU.
|
||||||
|
|
||||||
What: /sys/class/net/<mesh_iface>/mesh/ap_isolation
|
|
||||||
Date: May 2011
|
|
||||||
Contact: Antonio Quartulli <ordex@autistici.org>
|
|
||||||
Description:
|
|
||||||
Indicates whether the data traffic going from a
|
|
||||||
wireless client to another wireless client will be
|
|
||||||
silently dropped.
|
|
||||||
|
|
||||||
What: /sys/class/net/<mesh_iface>/mesh/gw_bandwidth
|
What: /sys/class/net/<mesh_iface>/mesh/gw_bandwidth
|
||||||
Date: October 2010
|
Date: October 2010
|
||||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
||||||
|
@ -60,6 +60,13 @@ Description:
|
||||||
Defines the selection criteria this node will use
|
Defines the selection criteria this node will use
|
||||||
to choose a gateway if gw_mode was set to 'client'.
|
to choose a gateway if gw_mode was set to 'client'.
|
||||||
|
|
||||||
|
What: /sys/class/net/<mesh_iface>/mesh/hop_penalty
|
||||||
|
Date: Oct 2010
|
||||||
|
Contact: Linus Lüssing <linus.luessing@web.de>
|
||||||
|
Description:
|
||||||
|
Defines the penalty which will be applied to an
|
||||||
|
originator message's tq-field on every hop.
|
||||||
|
|
||||||
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>
|
||||||
|
@ -67,19 +74,12 @@ Description:
|
||||||
Defines the interval in milliseconds in which batman
|
Defines the interval in milliseconds in which batman
|
||||||
sends its protocol messages.
|
sends its protocol messages.
|
||||||
|
|
||||||
What: /sys/class/net/<mesh_iface>/mesh/hop_penalty
|
What: /sys/class/net/<mesh_iface>/mesh/routing_algo
|
||||||
Date: Oct 2010
|
Date: Dec 2011
|
||||||
Contact: Linus Lüssing <linus.luessing@web.de>
|
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
||||||
Description:
|
Description:
|
||||||
Defines the penalty which will be applied to an
|
Defines the routing procotol this mesh instance
|
||||||
originator message's tq-field on every hop.
|
uses to find the optimal paths through the mesh.
|
||||||
|
|
||||||
What: /sys/class/net/<mesh_iface>/mesh/routing_algo
|
|
||||||
Date: Dec 2011
|
|
||||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
|
||||||
Description:
|
|
||||||
Defines the routing procotol this mesh instance
|
|
||||||
uses to find the optimal paths through the mesh.
|
|
||||||
|
|
||||||
What: /sys/class/net/<mesh_iface>/mesh/vis_mode
|
What: /sys/class/net/<mesh_iface>/mesh/vis_mode
|
||||||
Date: May 2010
|
Date: May 2010
|
||||||
|
|
|
@ -6,6 +6,7 @@ config BATMAN_ADV
|
||||||
tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
|
tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
|
||||||
depends on NET
|
depends on NET
|
||||||
select CRC16
|
select CRC16
|
||||||
|
select LIBCRC32C
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is
|
B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is
|
||||||
|
|
|
@ -77,8 +77,15 @@ static int batadv_compare_backbone_gw(const struct hlist_node *node,
|
||||||
{
|
{
|
||||||
const void *data1 = container_of(node, struct batadv_backbone_gw,
|
const void *data1 = container_of(node, struct batadv_backbone_gw,
|
||||||
hash_entry);
|
hash_entry);
|
||||||
|
const struct batadv_backbone_gw *gw1 = data1, *gw2 = data2;
|
||||||
|
|
||||||
return (memcmp(data1, data2, ETH_ALEN + sizeof(short)) == 0 ? 1 : 0);
|
if (!batadv_compare_eth(gw1->orig, gw2->orig))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (gw1->vid != gw2->vid)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compares address and vid of two claims */
|
/* compares address and vid of two claims */
|
||||||
|
@ -87,8 +94,15 @@ static int batadv_compare_claim(const struct hlist_node *node,
|
||||||
{
|
{
|
||||||
const void *data1 = container_of(node, struct batadv_claim,
|
const void *data1 = container_of(node, struct batadv_claim,
|
||||||
hash_entry);
|
hash_entry);
|
||||||
|
const struct batadv_claim *cl1 = data1, *cl2 = data2;
|
||||||
|
|
||||||
return (memcmp(data1, data2, ETH_ALEN + sizeof(short)) == 0 ? 1 : 0);
|
if (!batadv_compare_eth(cl1->addr, cl2->addr))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (cl1->vid != cl2->vid)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free a backbone gw */
|
/* free a backbone gw */
|
||||||
|
@ -1235,8 +1249,7 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
|
||||||
/**
|
/**
|
||||||
* batadv_bla_check_bcast_duplist
|
* batadv_bla_check_bcast_duplist
|
||||||
* @bat_priv: the bat priv with all the soft interface information
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
* @bcast_packet: encapsulated broadcast frame plus batman header
|
* @skb: contains the bcast_packet to be checked
|
||||||
* @bcast_packet_len: length of encapsulated broadcast frame plus batman header
|
|
||||||
*
|
*
|
||||||
* check if it is on our broadcast list. Another gateway might
|
* check if it is on our broadcast list. Another gateway might
|
||||||
* have sent the same packet because it is connected to the same backbone,
|
* have sent the same packet because it is connected to the same backbone,
|
||||||
|
@ -1248,20 +1261,17 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
|
||||||
* the same host however as this might be intended.
|
* the same host however as this might be intended.
|
||||||
*/
|
*/
|
||||||
int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
||||||
struct batadv_bcast_packet *bcast_packet,
|
struct sk_buff *skb)
|
||||||
int bcast_packet_len)
|
|
||||||
{
|
{
|
||||||
int i, length, curr, ret = 0;
|
int i, curr, ret = 0;
|
||||||
uint8_t *content;
|
__be32 crc;
|
||||||
uint16_t crc;
|
struct batadv_bcast_packet *bcast_packet;
|
||||||
struct batadv_bcast_duplist_entry *entry;
|
struct batadv_bcast_duplist_entry *entry;
|
||||||
|
|
||||||
length = bcast_packet_len - sizeof(*bcast_packet);
|
bcast_packet = (struct batadv_bcast_packet *)skb->data;
|
||||||
content = (uint8_t *)bcast_packet;
|
|
||||||
content += sizeof(*bcast_packet);
|
|
||||||
|
|
||||||
/* calculate the crc ... */
|
/* calculate the crc ... */
|
||||||
crc = crc16(0, content, length);
|
crc = batadv_skb_crc32(skb, (u8 *)(bcast_packet + 1));
|
||||||
|
|
||||||
spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
|
spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,7 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq,
|
||||||
void *offset);
|
void *offset);
|
||||||
int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig);
|
int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig);
|
||||||
int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
||||||
struct batadv_bcast_packet *bcast_packet,
|
struct sk_buff *skb);
|
||||||
int hdr_size);
|
|
||||||
void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
|
void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
|
||||||
struct batadv_hard_iface *primary_if,
|
struct batadv_hard_iface *primary_if,
|
||||||
struct batadv_hard_iface *oldif);
|
struct batadv_hard_iface *oldif);
|
||||||
|
@ -81,8 +80,7 @@ static inline int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv,
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
||||||
struct batadv_bcast_packet *bcast_packet,
|
struct sk_buff *skb)
|
||||||
int hdr_size)
|
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,7 +323,17 @@ struct batadv_debuginfo batadv_debuginfo_##_name = { \
|
||||||
} \
|
} \
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* the following attributes are general and therefore they will be directly
|
||||||
|
* placed in the BATADV_DEBUGFS_SUBDIR subdirectory of debugfs
|
||||||
|
*/
|
||||||
static BATADV_DEBUGINFO(routing_algos, S_IRUGO, batadv_algorithms_open);
|
static BATADV_DEBUGINFO(routing_algos, S_IRUGO, batadv_algorithms_open);
|
||||||
|
|
||||||
|
static struct batadv_debuginfo *batadv_general_debuginfos[] = {
|
||||||
|
&batadv_debuginfo_routing_algos,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The following attributes are per soft interface */
|
||||||
static BATADV_DEBUGINFO(originators, S_IRUGO, batadv_originators_open);
|
static BATADV_DEBUGINFO(originators, S_IRUGO, batadv_originators_open);
|
||||||
static BATADV_DEBUGINFO(gateways, S_IRUGO, batadv_gateways_open);
|
static BATADV_DEBUGINFO(gateways, S_IRUGO, batadv_gateways_open);
|
||||||
static BATADV_DEBUGINFO(transtable_global, S_IRUGO,
|
static BATADV_DEBUGINFO(transtable_global, S_IRUGO,
|
||||||
|
@ -358,7 +368,7 @@ static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
|
||||||
|
|
||||||
void batadv_debugfs_init(void)
|
void batadv_debugfs_init(void)
|
||||||
{
|
{
|
||||||
struct batadv_debuginfo *bat_debug;
|
struct batadv_debuginfo **bat_debug;
|
||||||
struct dentry *file;
|
struct dentry *file;
|
||||||
|
|
||||||
batadv_debugfs = debugfs_create_dir(BATADV_DEBUGFS_SUBDIR, NULL);
|
batadv_debugfs = debugfs_create_dir(BATADV_DEBUGFS_SUBDIR, NULL);
|
||||||
|
@ -366,17 +376,23 @@ void batadv_debugfs_init(void)
|
||||||
batadv_debugfs = NULL;
|
batadv_debugfs = NULL;
|
||||||
|
|
||||||
if (!batadv_debugfs)
|
if (!batadv_debugfs)
|
||||||
goto out;
|
goto err;
|
||||||
|
|
||||||
bat_debug = &batadv_debuginfo_routing_algos;
|
for (bat_debug = batadv_general_debuginfos; *bat_debug; ++bat_debug) {
|
||||||
file = debugfs_create_file(bat_debug->attr.name,
|
file = debugfs_create_file(((*bat_debug)->attr).name,
|
||||||
S_IFREG | bat_debug->attr.mode,
|
S_IFREG | ((*bat_debug)->attr).mode,
|
||||||
batadv_debugfs, NULL, &bat_debug->fops);
|
batadv_debugfs, NULL,
|
||||||
if (!file)
|
&(*bat_debug)->fops);
|
||||||
pr_err("Can't add debugfs file: %s\n", bat_debug->attr.name);
|
if (!file) {
|
||||||
|
pr_err("Can't add general debugfs file: %s\n",
|
||||||
|
((*bat_debug)->attr).name);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
return;
|
return;
|
||||||
|
err:
|
||||||
|
debugfs_remove_recursive(batadv_debugfs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void batadv_debugfs_destroy(void)
|
void batadv_debugfs_destroy(void)
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
* 02110-1301, USA
|
* 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/crc32c.h>
|
||||||
|
#include <linux/highmem.h>
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "sysfs.h"
|
#include "sysfs.h"
|
||||||
#include "debugfs.h"
|
#include "debugfs.h"
|
||||||
|
@ -420,6 +422,38 @@ int batadv_algo_seq_print_text(struct seq_file *seq, void *offset)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_skb_crc32 - calculate CRC32 of the whole packet and skip bytes in
|
||||||
|
* the header
|
||||||
|
* @skb: skb pointing to fragmented socket buffers
|
||||||
|
* @payload_ptr: Pointer to position inside the head buffer of the skb
|
||||||
|
* marking the start of the data to be CRC'ed
|
||||||
|
*
|
||||||
|
* payload_ptr must always point to an address in the skb head buffer and not to
|
||||||
|
* a fragment.
|
||||||
|
*/
|
||||||
|
__be32 batadv_skb_crc32(struct sk_buff *skb, u8 *payload_ptr)
|
||||||
|
{
|
||||||
|
u32 crc = 0;
|
||||||
|
unsigned int from;
|
||||||
|
unsigned int to = skb->len;
|
||||||
|
struct skb_seq_state st;
|
||||||
|
const u8 *data;
|
||||||
|
unsigned int len;
|
||||||
|
unsigned int consumed = 0;
|
||||||
|
|
||||||
|
from = (unsigned int)(payload_ptr - skb->data);
|
||||||
|
|
||||||
|
skb_prepare_seq_read(skb, from, to, &st);
|
||||||
|
while ((len = skb_seq_read(consumed, &data, &st)) != 0) {
|
||||||
|
crc = crc32c(crc, data, len);
|
||||||
|
consumed += len;
|
||||||
|
}
|
||||||
|
skb_abort_seq_read(&st);
|
||||||
|
|
||||||
|
return htonl(crc);
|
||||||
|
}
|
||||||
|
|
||||||
static int batadv_param_set_ra(const char *val, const struct kernel_param *kp)
|
static int batadv_param_set_ra(const char *val, const struct kernel_param *kp)
|
||||||
{
|
{
|
||||||
struct batadv_algo_ops *bat_algo_ops;
|
struct batadv_algo_ops *bat_algo_ops;
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#define BATADV_DRIVER_DEVICE "batman-adv"
|
#define BATADV_DRIVER_DEVICE "batman-adv"
|
||||||
|
|
||||||
#ifndef BATADV_SOURCE_VERSION
|
#ifndef BATADV_SOURCE_VERSION
|
||||||
#define BATADV_SOURCE_VERSION "2012.4.0"
|
#define BATADV_SOURCE_VERSION "2012.5.0"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* B.A.T.M.A.N. parameters */
|
/* B.A.T.M.A.N. parameters */
|
||||||
|
@ -174,6 +174,7 @@ void batadv_recv_handler_unregister(uint8_t packet_type);
|
||||||
int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops);
|
int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops);
|
||||||
int batadv_algo_select(struct batadv_priv *bat_priv, char *name);
|
int batadv_algo_select(struct batadv_priv *bat_priv, char *name);
|
||||||
int batadv_algo_seq_print_text(struct seq_file *seq, void *offset);
|
int batadv_algo_seq_print_text(struct seq_file *seq, void *offset);
|
||||||
|
__be32 batadv_skb_crc32(struct sk_buff *skb, u8 *payload_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum batadv_dbg_level - available log levels
|
* enum batadv_dbg_level - available log levels
|
||||||
|
|
|
@ -173,6 +173,18 @@ struct batadv_icmp_packet_rr {
|
||||||
uint8_t rr[BATADV_RR_LEN][ETH_ALEN];
|
uint8_t rr[BATADV_RR_LEN][ETH_ALEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* All packet headers in front of an ethernet header have to be completely
|
||||||
|
* divisible by 2 but not by 4 to make the payload after the ethernet
|
||||||
|
* header again 4 bytes boundary aligned.
|
||||||
|
*
|
||||||
|
* A packing of 2 is necessary to avoid extra padding at the end of the struct
|
||||||
|
* caused by a structure member which is larger than two bytes. Otherwise
|
||||||
|
* the structure would not fulfill the previously mentioned rule to avoid the
|
||||||
|
* misalignment of the payload after the ethernet header. It may also lead to
|
||||||
|
* leakage of information when the padding it not initialized before sending.
|
||||||
|
*/
|
||||||
|
#pragma pack(2)
|
||||||
|
|
||||||
struct batadv_unicast_packet {
|
struct batadv_unicast_packet {
|
||||||
struct batadv_header header;
|
struct batadv_header header;
|
||||||
uint8_t ttvn; /* destination translation table version number */
|
uint8_t ttvn; /* destination translation table version number */
|
||||||
|
@ -216,7 +228,9 @@ struct batadv_bcast_packet {
|
||||||
/* "4 bytes boundary + 2 bytes" long to make the payload after the
|
/* "4 bytes boundary + 2 bytes" long to make the payload after the
|
||||||
* following ethernet header again 4 bytes boundary aligned
|
* following ethernet header again 4 bytes boundary aligned
|
||||||
*/
|
*/
|
||||||
} __packed;
|
};
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
struct batadv_vis_packet {
|
struct batadv_vis_packet {
|
||||||
struct batadv_header header;
|
struct batadv_header header;
|
||||||
|
|
|
@ -285,7 +285,6 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
|
||||||
{
|
{
|
||||||
struct batadv_hard_iface *primary_if = NULL;
|
struct batadv_hard_iface *primary_if = NULL;
|
||||||
struct batadv_orig_node *orig_node = NULL;
|
struct batadv_orig_node *orig_node = NULL;
|
||||||
struct batadv_neigh_node *router = NULL;
|
|
||||||
struct batadv_icmp_packet_rr *icmp_packet;
|
struct batadv_icmp_packet_rr *icmp_packet;
|
||||||
int ret = NET_RX_DROP;
|
int ret = NET_RX_DROP;
|
||||||
|
|
||||||
|
@ -307,10 +306,6 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
|
||||||
if (!orig_node)
|
if (!orig_node)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
router = batadv_orig_node_get_router(orig_node);
|
|
||||||
if (!router)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* create a copy of the skb, if needed, to modify it. */
|
/* create a copy of the skb, if needed, to modify it. */
|
||||||
if (skb_cow(skb, ETH_HLEN) < 0)
|
if (skb_cow(skb, ETH_HLEN) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -322,14 +317,12 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
|
||||||
icmp_packet->msg_type = BATADV_ECHO_REPLY;
|
icmp_packet->msg_type = BATADV_ECHO_REPLY;
|
||||||
icmp_packet->header.ttl = BATADV_TTL;
|
icmp_packet->header.ttl = BATADV_TTL;
|
||||||
|
|
||||||
batadv_send_skb_packet(skb, router->if_incoming, router->addr);
|
if (batadv_send_skb_to_orig(skb, orig_node, NULL))
|
||||||
ret = NET_RX_SUCCESS;
|
ret = NET_RX_SUCCESS;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (primary_if)
|
if (primary_if)
|
||||||
batadv_hardif_free_ref(primary_if);
|
batadv_hardif_free_ref(primary_if);
|
||||||
if (router)
|
|
||||||
batadv_neigh_node_free_ref(router);
|
|
||||||
if (orig_node)
|
if (orig_node)
|
||||||
batadv_orig_node_free_ref(orig_node);
|
batadv_orig_node_free_ref(orig_node);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -340,7 +333,6 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
|
||||||
{
|
{
|
||||||
struct batadv_hard_iface *primary_if = NULL;
|
struct batadv_hard_iface *primary_if = NULL;
|
||||||
struct batadv_orig_node *orig_node = NULL;
|
struct batadv_orig_node *orig_node = NULL;
|
||||||
struct batadv_neigh_node *router = NULL;
|
|
||||||
struct batadv_icmp_packet *icmp_packet;
|
struct batadv_icmp_packet *icmp_packet;
|
||||||
int ret = NET_RX_DROP;
|
int ret = NET_RX_DROP;
|
||||||
|
|
||||||
|
@ -362,10 +354,6 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
|
||||||
if (!orig_node)
|
if (!orig_node)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
router = batadv_orig_node_get_router(orig_node);
|
|
||||||
if (!router)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* create a copy of the skb, if needed, to modify it. */
|
/* create a copy of the skb, if needed, to modify it. */
|
||||||
if (skb_cow(skb, ETH_HLEN) < 0)
|
if (skb_cow(skb, ETH_HLEN) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -377,14 +365,12 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
|
||||||
icmp_packet->msg_type = BATADV_TTL_EXCEEDED;
|
icmp_packet->msg_type = BATADV_TTL_EXCEEDED;
|
||||||
icmp_packet->header.ttl = BATADV_TTL;
|
icmp_packet->header.ttl = BATADV_TTL;
|
||||||
|
|
||||||
batadv_send_skb_packet(skb, router->if_incoming, router->addr);
|
if (batadv_send_skb_to_orig(skb, orig_node, NULL))
|
||||||
ret = NET_RX_SUCCESS;
|
ret = NET_RX_SUCCESS;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (primary_if)
|
if (primary_if)
|
||||||
batadv_hardif_free_ref(primary_if);
|
batadv_hardif_free_ref(primary_if);
|
||||||
if (router)
|
|
||||||
batadv_neigh_node_free_ref(router);
|
|
||||||
if (orig_node)
|
if (orig_node)
|
||||||
batadv_orig_node_free_ref(orig_node);
|
batadv_orig_node_free_ref(orig_node);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -398,7 +384,6 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
|
||||||
struct batadv_icmp_packet_rr *icmp_packet;
|
struct batadv_icmp_packet_rr *icmp_packet;
|
||||||
struct ethhdr *ethhdr;
|
struct ethhdr *ethhdr;
|
||||||
struct batadv_orig_node *orig_node = NULL;
|
struct batadv_orig_node *orig_node = NULL;
|
||||||
struct batadv_neigh_node *router = NULL;
|
|
||||||
int hdr_size = sizeof(struct batadv_icmp_packet);
|
int hdr_size = sizeof(struct batadv_icmp_packet);
|
||||||
int ret = NET_RX_DROP;
|
int ret = NET_RX_DROP;
|
||||||
|
|
||||||
|
@ -447,10 +432,6 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
|
||||||
if (!orig_node)
|
if (!orig_node)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
router = batadv_orig_node_get_router(orig_node);
|
|
||||||
if (!router)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* create a copy of the skb, if needed, to modify it. */
|
/* create a copy of the skb, if needed, to modify it. */
|
||||||
if (skb_cow(skb, ETH_HLEN) < 0)
|
if (skb_cow(skb, ETH_HLEN) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -461,12 +442,10 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
|
||||||
icmp_packet->header.ttl--;
|
icmp_packet->header.ttl--;
|
||||||
|
|
||||||
/* route it */
|
/* route it */
|
||||||
batadv_send_skb_packet(skb, router->if_incoming, router->addr);
|
if (batadv_send_skb_to_orig(skb, orig_node, recv_if))
|
||||||
ret = NET_RX_SUCCESS;
|
ret = NET_RX_SUCCESS;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (router)
|
|
||||||
batadv_neigh_node_free_ref(router);
|
|
||||||
if (orig_node)
|
if (orig_node)
|
||||||
batadv_orig_node_free_ref(orig_node);
|
batadv_orig_node_free_ref(orig_node);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -882,8 +861,8 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
|
||||||
skb->len + ETH_HLEN);
|
skb->len + ETH_HLEN);
|
||||||
|
|
||||||
/* route it */
|
/* route it */
|
||||||
batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
|
if (batadv_send_skb_to_orig(skb, orig_node, recv_if))
|
||||||
ret = NET_RX_SUCCESS;
|
ret = NET_RX_SUCCESS;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (neigh_node)
|
if (neigh_node)
|
||||||
|
@ -1217,14 +1196,8 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
|
||||||
|
|
||||||
spin_unlock_bh(&orig_node->bcast_seqno_lock);
|
spin_unlock_bh(&orig_node->bcast_seqno_lock);
|
||||||
|
|
||||||
/* keep skb linear for crc calculation */
|
|
||||||
if (skb_linearize(skb) < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
bcast_packet = (struct batadv_bcast_packet *)skb->data;
|
|
||||||
|
|
||||||
/* check whether this has been sent by another originator before */
|
/* check whether this has been sent by another originator before */
|
||||||
if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, skb->len))
|
if (batadv_bla_check_bcast_duplist(bat_priv, skb))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* rebroadcast packet */
|
/* rebroadcast packet */
|
||||||
|
|
|
@ -78,6 +78,39 @@ send_skb_err:
|
||||||
return NET_XMIT_DROP;
|
return NET_XMIT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_send_skb_to_orig - Lookup next-hop and transmit skb.
|
||||||
|
* @skb: Packet to be transmitted.
|
||||||
|
* @orig_node: Final destination of the packet.
|
||||||
|
* @recv_if: Interface used when receiving the packet (can be NULL).
|
||||||
|
*
|
||||||
|
* Looks up the best next-hop towards the passed originator and passes the
|
||||||
|
* skb on for preparation of MAC header. If the packet originated from this
|
||||||
|
* host, NULL can be passed as recv_if and no interface alternating is
|
||||||
|
* attempted.
|
||||||
|
*
|
||||||
|
* Returns TRUE on success; FALSE otherwise.
|
||||||
|
*/
|
||||||
|
bool batadv_send_skb_to_orig(struct sk_buff *skb,
|
||||||
|
struct batadv_orig_node *orig_node,
|
||||||
|
struct batadv_hard_iface *recv_if)
|
||||||
|
{
|
||||||
|
struct batadv_priv *bat_priv = orig_node->bat_priv;
|
||||||
|
struct batadv_neigh_node *neigh_node;
|
||||||
|
|
||||||
|
/* batadv_find_router() increases neigh_nodes refcount if found. */
|
||||||
|
neigh_node = batadv_find_router(bat_priv, orig_node, recv_if);
|
||||||
|
if (!neigh_node)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* route it */
|
||||||
|
batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
|
||||||
|
|
||||||
|
batadv_neigh_node_free_ref(neigh_node);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface)
|
void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface)
|
||||||
{
|
{
|
||||||
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
|
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
int batadv_send_skb_packet(struct sk_buff *skb,
|
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);
|
||||||
|
bool batadv_send_skb_to_orig(struct sk_buff *skb,
|
||||||
|
struct batadv_orig_node *orig_node,
|
||||||
|
struct batadv_hard_iface *recv_if);
|
||||||
void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface);
|
void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface);
|
||||||
int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv,
|
int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
|
|
|
@ -911,8 +911,44 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* print all orig nodes who announce the address for this global entry.
|
/* batadv_transtable_best_orig - Get best originator list entry from tt entry
|
||||||
* it is assumed that the caller holds rcu_read_lock();
|
* @tt_global_entry: global translation table entry to be analyzed
|
||||||
|
*
|
||||||
|
* This functon assumes the caller holds rcu_read_lock().
|
||||||
|
* Returns best originator list entry or NULL on errors.
|
||||||
|
*/
|
||||||
|
static struct batadv_tt_orig_list_entry *
|
||||||
|
batadv_transtable_best_orig(struct batadv_tt_global_entry *tt_global_entry)
|
||||||
|
{
|
||||||
|
struct batadv_neigh_node *router = NULL;
|
||||||
|
struct hlist_head *head;
|
||||||
|
struct hlist_node *node;
|
||||||
|
struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL;
|
||||||
|
int best_tq = 0;
|
||||||
|
|
||||||
|
head = &tt_global_entry->orig_list;
|
||||||
|
hlist_for_each_entry_rcu(orig_entry, node, head, list) {
|
||||||
|
router = batadv_orig_node_get_router(orig_entry->orig_node);
|
||||||
|
if (!router)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (router->tq_avg > best_tq) {
|
||||||
|
best_entry = orig_entry;
|
||||||
|
best_tq = router->tq_avg;
|
||||||
|
}
|
||||||
|
|
||||||
|
batadv_neigh_node_free_ref(router);
|
||||||
|
}
|
||||||
|
|
||||||
|
return best_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* batadv_tt_global_print_entry - print all orig nodes who announce the address
|
||||||
|
* for this global entry
|
||||||
|
* @tt_global_entry: global translation table entry to be printed
|
||||||
|
* @seq: debugfs table seq_file struct
|
||||||
|
*
|
||||||
|
* This functon assumes the caller holds rcu_read_lock().
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
|
batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
|
||||||
|
@ -920,21 +956,37 @@ batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
|
||||||
{
|
{
|
||||||
struct hlist_head *head;
|
struct hlist_head *head;
|
||||||
struct hlist_node *node;
|
struct hlist_node *node;
|
||||||
struct batadv_tt_orig_list_entry *orig_entry;
|
struct batadv_tt_orig_list_entry *orig_entry, *best_entry;
|
||||||
struct batadv_tt_common_entry *tt_common_entry;
|
struct batadv_tt_common_entry *tt_common_entry;
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
uint8_t last_ttvn;
|
uint8_t last_ttvn;
|
||||||
|
|
||||||
tt_common_entry = &tt_global_entry->common;
|
tt_common_entry = &tt_global_entry->common;
|
||||||
|
flags = tt_common_entry->flags;
|
||||||
|
|
||||||
|
best_entry = batadv_transtable_best_orig(tt_global_entry);
|
||||||
|
if (best_entry) {
|
||||||
|
last_ttvn = atomic_read(&best_entry->orig_node->last_ttvn);
|
||||||
|
seq_printf(seq, " %c %pM (%3u) via %pM (%3u) [%c%c%c]\n",
|
||||||
|
'*', tt_global_entry->common.addr,
|
||||||
|
best_entry->ttvn, best_entry->orig_node->orig,
|
||||||
|
last_ttvn,
|
||||||
|
(flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
|
||||||
|
(flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
|
||||||
|
(flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
|
||||||
|
}
|
||||||
|
|
||||||
head = &tt_global_entry->orig_list;
|
head = &tt_global_entry->orig_list;
|
||||||
|
|
||||||
hlist_for_each_entry_rcu(orig_entry, node, head, list) {
|
hlist_for_each_entry_rcu(orig_entry, node, head, list) {
|
||||||
flags = tt_common_entry->flags;
|
if (best_entry == orig_entry)
|
||||||
|
continue;
|
||||||
|
|
||||||
last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn);
|
last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn);
|
||||||
seq_printf(seq, " * %pM (%3u) via %pM (%3u) [%c%c%c]\n",
|
seq_printf(seq, " %c %pM (%3u) via %pM (%3u) [%c%c%c]\n",
|
||||||
tt_global_entry->common.addr, orig_entry->ttvn,
|
'+', tt_global_entry->common.addr,
|
||||||
orig_entry->orig_node->orig, last_ttvn,
|
orig_entry->ttvn, orig_entry->orig_node->orig,
|
||||||
|
last_ttvn,
|
||||||
(flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
|
(flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
|
||||||
(flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
|
(flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
|
||||||
(flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
|
(flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
|
||||||
|
@ -1280,11 +1332,7 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
|
||||||
struct batadv_tt_local_entry *tt_local_entry = NULL;
|
struct batadv_tt_local_entry *tt_local_entry = NULL;
|
||||||
struct batadv_tt_global_entry *tt_global_entry = NULL;
|
struct batadv_tt_global_entry *tt_global_entry = NULL;
|
||||||
struct batadv_orig_node *orig_node = NULL;
|
struct batadv_orig_node *orig_node = NULL;
|
||||||
struct batadv_neigh_node *router = NULL;
|
struct batadv_tt_orig_list_entry *best_entry;
|
||||||
struct hlist_head *head;
|
|
||||||
struct hlist_node *node;
|
|
||||||
struct batadv_tt_orig_list_entry *orig_entry;
|
|
||||||
int best_tq;
|
|
||||||
|
|
||||||
if (src && atomic_read(&bat_priv->ap_isolation)) {
|
if (src && atomic_read(&bat_priv->ap_isolation)) {
|
||||||
tt_local_entry = batadv_tt_local_hash_find(bat_priv, src);
|
tt_local_entry = batadv_tt_local_hash_find(bat_priv, src);
|
||||||
|
@ -1304,25 +1352,15 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
|
||||||
_batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
|
_batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
best_tq = 0;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
head = &tt_global_entry->orig_list;
|
best_entry = batadv_transtable_best_orig(tt_global_entry);
|
||||||
hlist_for_each_entry_rcu(orig_entry, node, head, list) {
|
|
||||||
router = batadv_orig_node_get_router(orig_entry->orig_node);
|
|
||||||
if (!router)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (router->tq_avg > best_tq) {
|
|
||||||
orig_node = orig_entry->orig_node;
|
|
||||||
best_tq = router->tq_avg;
|
|
||||||
}
|
|
||||||
batadv_neigh_node_free_ref(router);
|
|
||||||
}
|
|
||||||
/* found anything? */
|
/* found anything? */
|
||||||
|
if (best_entry)
|
||||||
|
orig_node = best_entry->orig_node;
|
||||||
if (orig_node && !atomic_inc_not_zero(&orig_node->refcount))
|
if (orig_node && !atomic_inc_not_zero(&orig_node->refcount))
|
||||||
orig_node = NULL;
|
orig_node = NULL;
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (tt_global_entry)
|
if (tt_global_entry)
|
||||||
batadv_tt_global_entry_free_ref(tt_global_entry);
|
batadv_tt_global_entry_free_ref(tt_global_entry);
|
||||||
|
@ -1604,7 +1642,6 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
|
||||||
{
|
{
|
||||||
struct sk_buff *skb = NULL;
|
struct sk_buff *skb = NULL;
|
||||||
struct batadv_tt_query_packet *tt_request;
|
struct batadv_tt_query_packet *tt_request;
|
||||||
struct batadv_neigh_node *neigh_node = NULL;
|
|
||||||
struct batadv_hard_iface *primary_if;
|
struct batadv_hard_iface *primary_if;
|
||||||
struct batadv_tt_req_node *tt_req_node = NULL;
|
struct batadv_tt_req_node *tt_req_node = NULL;
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
@ -1642,23 +1679,15 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
|
||||||
if (full_table)
|
if (full_table)
|
||||||
tt_request->flags |= BATADV_TT_FULL_TABLE;
|
tt_request->flags |= BATADV_TT_FULL_TABLE;
|
||||||
|
|
||||||
neigh_node = batadv_orig_node_get_router(dst_orig_node);
|
batadv_dbg(BATADV_DBG_TT, bat_priv, "Sending TT_REQUEST to %pM [%c]\n",
|
||||||
if (!neigh_node)
|
dst_orig_node->orig, (full_table ? 'F' : '.'));
|
||||||
goto out;
|
|
||||||
|
|
||||||
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
|
||||||
"Sending TT_REQUEST to %pM via %pM [%c]\n",
|
|
||||||
dst_orig_node->orig, neigh_node->addr,
|
|
||||||
(full_table ? 'F' : '.'));
|
|
||||||
|
|
||||||
batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX);
|
batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX);
|
||||||
|
|
||||||
batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
|
if (batadv_send_skb_to_orig(skb, dst_orig_node, NULL))
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (neigh_node)
|
|
||||||
batadv_neigh_node_free_ref(neigh_node);
|
|
||||||
if (primary_if)
|
if (primary_if)
|
||||||
batadv_hardif_free_ref(primary_if);
|
batadv_hardif_free_ref(primary_if);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -1678,7 +1707,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_neigh_node *neigh_node = NULL;
|
|
||||||
struct batadv_hard_iface *primary_if = 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;
|
||||||
|
@ -1704,10 +1732,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;
|
||||||
|
|
||||||
neigh_node = batadv_orig_node_get_router(res_dst_orig_node);
|
|
||||||
if (!neigh_node)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
primary_if = batadv_primary_if_get_selected(bat_priv);
|
||||||
if (!primary_if)
|
if (!primary_if)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1779,14 +1803,13 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
|
||||||
tt_response->flags |= BATADV_TT_FULL_TABLE;
|
tt_response->flags |= BATADV_TT_FULL_TABLE;
|
||||||
|
|
||||||
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
||||||
"Sending TT_RESPONSE %pM via %pM for %pM (ttvn: %u)\n",
|
"Sending TT_RESPONSE %pM for %pM (ttvn: %u)\n",
|
||||||
res_dst_orig_node->orig, neigh_node->addr,
|
res_dst_orig_node->orig, req_dst_orig_node->orig, req_ttvn);
|
||||||
req_dst_orig_node->orig, req_ttvn);
|
|
||||||
|
|
||||||
batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
|
batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
|
||||||
|
|
||||||
batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
|
if (batadv_send_skb_to_orig(skb, res_dst_orig_node, NULL))
|
||||||
ret = true;
|
ret = true;
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
|
@ -1797,8 +1820,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 (neigh_node)
|
|
||||||
batadv_neigh_node_free_ref(neigh_node);
|
|
||||||
if (primary_if)
|
if (primary_if)
|
||||||
batadv_hardif_free_ref(primary_if);
|
batadv_hardif_free_ref(primary_if);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
@ -1812,7 +1833,6 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
|
||||||
struct batadv_tt_query_packet *tt_request)
|
struct batadv_tt_query_packet *tt_request)
|
||||||
{
|
{
|
||||||
struct batadv_orig_node *orig_node;
|
struct batadv_orig_node *orig_node;
|
||||||
struct batadv_neigh_node *neigh_node = NULL;
|
|
||||||
struct batadv_hard_iface *primary_if = NULL;
|
struct batadv_hard_iface *primary_if = NULL;
|
||||||
uint8_t my_ttvn, req_ttvn, ttvn;
|
uint8_t my_ttvn, req_ttvn, ttvn;
|
||||||
int ret = false;
|
int ret = false;
|
||||||
|
@ -1837,10 +1857,6 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
|
||||||
if (!orig_node)
|
if (!orig_node)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
neigh_node = batadv_orig_node_get_router(orig_node);
|
|
||||||
if (!neigh_node)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
primary_if = batadv_primary_if_get_selected(bat_priv);
|
||||||
if (!primary_if)
|
if (!primary_if)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1904,14 +1920,14 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
|
||||||
tt_response->flags |= BATADV_TT_FULL_TABLE;
|
tt_response->flags |= BATADV_TT_FULL_TABLE;
|
||||||
|
|
||||||
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
||||||
"Sending TT_RESPONSE to %pM via %pM [%c]\n",
|
"Sending TT_RESPONSE to %pM [%c]\n",
|
||||||
orig_node->orig, neigh_node->addr,
|
orig_node->orig,
|
||||||
(tt_response->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
|
(tt_response->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
|
||||||
|
|
||||||
batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
|
batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
|
||||||
|
|
||||||
batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
|
if (batadv_send_skb_to_orig(skb, orig_node, NULL))
|
||||||
ret = true;
|
ret = true;
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
|
@ -1919,8 +1935,6 @@ unlock:
|
||||||
out:
|
out:
|
||||||
if (orig_node)
|
if (orig_node)
|
||||||
batadv_orig_node_free_ref(orig_node);
|
batadv_orig_node_free_ref(orig_node);
|
||||||
if (neigh_node)
|
|
||||||
batadv_neigh_node_free_ref(neigh_node);
|
|
||||||
if (primary_if)
|
if (primary_if)
|
||||||
batadv_hardif_free_ref(primary_if);
|
batadv_hardif_free_ref(primary_if);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
@ -2185,7 +2199,6 @@ unlock:
|
||||||
static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
|
static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
|
||||||
struct batadv_orig_node *orig_node)
|
struct batadv_orig_node *orig_node)
|
||||||
{
|
{
|
||||||
struct batadv_neigh_node *neigh_node = NULL;
|
|
||||||
struct sk_buff *skb = NULL;
|
struct sk_buff *skb = NULL;
|
||||||
struct batadv_roam_adv_packet *roam_adv_packet;
|
struct batadv_roam_adv_packet *roam_adv_packet;
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
@ -2218,23 +2231,17 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
|
||||||
memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN);
|
memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN);
|
||||||
memcpy(roam_adv_packet->client, client, ETH_ALEN);
|
memcpy(roam_adv_packet->client, client, ETH_ALEN);
|
||||||
|
|
||||||
neigh_node = batadv_orig_node_get_router(orig_node);
|
|
||||||
if (!neigh_node)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
||||||
"Sending ROAMING_ADV to %pM (client %pM) via %pM\n",
|
"Sending ROAMING_ADV to %pM (client %pM)\n",
|
||||||
orig_node->orig, client, neigh_node->addr);
|
orig_node->orig, client);
|
||||||
|
|
||||||
batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX);
|
batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX);
|
||||||
|
|
||||||
batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
|
if (batadv_send_skb_to_orig(skb, orig_node, NULL))
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (neigh_node)
|
if (ret && skb)
|
||||||
batadv_neigh_node_free_ref(neigh_node);
|
|
||||||
if (ret)
|
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,7 +156,7 @@ struct batadv_neigh_node {
|
||||||
#ifdef CONFIG_BATMAN_ADV_BLA
|
#ifdef CONFIG_BATMAN_ADV_BLA
|
||||||
struct batadv_bcast_duplist_entry {
|
struct batadv_bcast_duplist_entry {
|
||||||
uint8_t orig[ETH_ALEN];
|
uint8_t orig[ETH_ALEN];
|
||||||
uint16_t crc;
|
__be32 crc;
|
||||||
unsigned long entrytime;
|
unsigned long entrytime;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -402,7 +402,7 @@ int batadv_unicast_generic_send_skb(struct batadv_priv *bat_priv,
|
||||||
struct batadv_orig_node *orig_node;
|
struct batadv_orig_node *orig_node;
|
||||||
struct batadv_neigh_node *neigh_node;
|
struct batadv_neigh_node *neigh_node;
|
||||||
int data_len = skb->len;
|
int data_len = skb->len;
|
||||||
int ret = 1;
|
int ret = NET_RX_DROP;
|
||||||
unsigned int dev_mtu;
|
unsigned int dev_mtu;
|
||||||
|
|
||||||
/* get routing information */
|
/* get routing information */
|
||||||
|
@ -466,15 +466,15 @@ find_router:
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
|
if (batadv_send_skb_to_orig(skb, orig_node, NULL))
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (neigh_node)
|
if (neigh_node)
|
||||||
batadv_neigh_node_free_ref(neigh_node);
|
batadv_neigh_node_free_ref(neigh_node);
|
||||||
if (orig_node)
|
if (orig_node)
|
||||||
batadv_orig_node_free_ref(orig_node);
|
batadv_orig_node_free_ref(orig_node);
|
||||||
if (ret == 1)
|
if (ret == NET_RX_DROP)
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -698,15 +698,12 @@ static void batadv_purge_vis_packets(struct batadv_priv *bat_priv)
|
||||||
static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
|
static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
|
||||||
struct batadv_vis_info *info)
|
struct batadv_vis_info *info)
|
||||||
{
|
{
|
||||||
struct batadv_neigh_node *router;
|
|
||||||
struct batadv_hashtable *hash = bat_priv->orig_hash;
|
struct batadv_hashtable *hash = bat_priv->orig_hash;
|
||||||
struct hlist_node *node;
|
struct hlist_node *node;
|
||||||
struct hlist_head *head;
|
struct hlist_head *head;
|
||||||
struct batadv_orig_node *orig_node;
|
struct batadv_orig_node *orig_node;
|
||||||
struct batadv_vis_packet *packet;
|
struct batadv_vis_packet *packet;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
struct batadv_hard_iface *hard_iface;
|
|
||||||
uint8_t dstaddr[ETH_ALEN];
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
|
|
||||||
|
@ -722,30 +719,20 @@ static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
|
||||||
if (!(orig_node->flags & BATADV_VIS_SERVER))
|
if (!(orig_node->flags & BATADV_VIS_SERVER))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
router = batadv_orig_node_get_router(orig_node);
|
|
||||||
if (!router)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* don't send it if we already received the packet from
|
/* don't send it if we already received the packet from
|
||||||
* this node.
|
* this node.
|
||||||
*/
|
*/
|
||||||
if (batadv_recv_list_is_in(bat_priv, &info->recv_list,
|
if (batadv_recv_list_is_in(bat_priv, &info->recv_list,
|
||||||
orig_node->orig)) {
|
orig_node->orig))
|
||||||
batadv_neigh_node_free_ref(router);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
|
memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
|
||||||
hard_iface = router->if_incoming;
|
|
||||||
memcpy(dstaddr, router->addr, ETH_ALEN);
|
|
||||||
|
|
||||||
batadv_neigh_node_free_ref(router);
|
|
||||||
|
|
||||||
skb = skb_clone(info->skb_packet, GFP_ATOMIC);
|
skb = skb_clone(info->skb_packet, GFP_ATOMIC);
|
||||||
if (skb)
|
if (!skb)
|
||||||
batadv_send_skb_packet(skb, hard_iface,
|
continue;
|
||||||
dstaddr);
|
|
||||||
|
|
||||||
|
if (!batadv_send_skb_to_orig(skb, orig_node, NULL))
|
||||||
|
kfree_skb(skb);
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
@ -755,7 +742,6 @@ static void batadv_unicast_vis_packet(struct batadv_priv *bat_priv,
|
||||||
struct batadv_vis_info *info)
|
struct batadv_vis_info *info)
|
||||||
{
|
{
|
||||||
struct batadv_orig_node *orig_node;
|
struct batadv_orig_node *orig_node;
|
||||||
struct batadv_neigh_node *router = NULL;
|
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
struct batadv_vis_packet *packet;
|
struct batadv_vis_packet *packet;
|
||||||
|
|
||||||
|
@ -765,17 +751,14 @@ static void batadv_unicast_vis_packet(struct batadv_priv *bat_priv,
|
||||||
if (!orig_node)
|
if (!orig_node)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
router = batadv_orig_node_get_router(orig_node);
|
skb = skb_clone(info->skb_packet, GFP_ATOMIC);
|
||||||
if (!router)
|
if (!skb)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
skb = skb_clone(info->skb_packet, GFP_ATOMIC);
|
if (!batadv_send_skb_to_orig(skb, orig_node, NULL))
|
||||||
if (skb)
|
kfree_skb(skb);
|
||||||
batadv_send_skb_packet(skb, router->if_incoming, router->addr);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (router)
|
|
||||||
batadv_neigh_node_free_ref(router);
|
|
||||||
if (orig_node)
|
if (orig_node)
|
||||||
batadv_orig_node_free_ref(orig_node);
|
batadv_orig_node_free_ref(orig_node);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue