Included changes:
- minimal fixes to the packet layout to avoid the __packed attribute when not needed - new packet type called UNICAST_4ADDR: in this packet it is possible to find both source and destination node (in the classic UNICAST header only the destination field exists). - a new feature: Distributed ARP Table (D.A.T.). It aims to reduce ARP lookups latency by means of a simil-DHT approach. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iEYEABECAAYFAlCasB8ACgkQpGgxIkP9cwd2kACeOhRvj9EA2hWo1vKQUN6OvTi0 nOcAn08Rvyf+gUPAFQcA9HEUAr8kAebT =c3ey -----END PGP SIGNATURE----- Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge Included changes: - minimal fixes to the packet layout to avoid the __packed attribute when not needed - new packet type called UNICAST_4ADDR: in this packet it is possible to find both source and destination node (in the classic UNICAST header only the destination field exists). - a new feature: Distributed ARP Table (D.A.T.). It aims to reduce ARP lookups latency by means of a simil-DHT approach.
This commit is contained in:
commit
f1e0b5b4f1
|
@ -203,7 +203,8 @@ abled during run time. Following log_levels are defined:
|
||||||
2 - Enable messages related to route added / changed / deleted
|
2 - Enable messages related to route added / changed / deleted
|
||||||
4 - Enable messages related to translation table operations
|
4 - Enable messages related to translation table operations
|
||||||
8 - Enable messages related to bridge loop avoidance
|
8 - Enable messages related to bridge loop avoidance
|
||||||
15 - enable all messages
|
16 - Enable messaged related to DAT, ARP snooping and parsing
|
||||||
|
31 - Enable all messages
|
||||||
|
|
||||||
The debug output can be changed at runtime using the file
|
The debug output can be changed at runtime using the file
|
||||||
/sys/class/net/bat0/mesh/log_level. e.g.
|
/sys/class/net/bat0/mesh/log_level. e.g.
|
||||||
|
|
|
@ -25,6 +25,16 @@ config BATMAN_ADV_BLA
|
||||||
more than one mesh node in the same LAN, you can safely remove
|
more than one mesh node in the same LAN, you can safely remove
|
||||||
this feature and save some space.
|
this feature and save some space.
|
||||||
|
|
||||||
|
config BATMAN_ADV_DAT
|
||||||
|
bool "Distributed ARP Table"
|
||||||
|
depends on BATMAN_ADV && INET
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This option enables DAT (Distributed ARP Table), a DHT based
|
||||||
|
mechanism that increases ARP reliability on sparse wireless
|
||||||
|
mesh networks. If you think that your network does not need
|
||||||
|
this option you can safely remove 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
|
||||||
|
|
|
@ -23,6 +23,7 @@ batman-adv-y += bat_iv_ogm.o
|
||||||
batman-adv-y += bitarray.o
|
batman-adv-y += bitarray.o
|
||||||
batman-adv-$(CONFIG_BATMAN_ADV_BLA) += bridge_loop_avoidance.o
|
batman-adv-$(CONFIG_BATMAN_ADV_BLA) += bridge_loop_avoidance.o
|
||||||
batman-adv-y += debugfs.o
|
batman-adv-y += debugfs.o
|
||||||
|
batman-adv-$(CONFIG_BATMAN_ADV_DAT) += distributed-arp-table.o
|
||||||
batman-adv-y += gateway_client.o
|
batman-adv-y += gateway_client.o
|
||||||
batman-adv-y += gateway_common.o
|
batman-adv-y += gateway_common.o
|
||||||
batman-adv-y += hard-interface.o
|
batman-adv-y += hard-interface.o
|
||||||
|
|
|
@ -411,9 +411,11 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
|
||||||
|
|
||||||
if ((atomic_read(&bat_priv->aggregated_ogms)) &&
|
if ((atomic_read(&bat_priv->aggregated_ogms)) &&
|
||||||
(packet_len < BATADV_MAX_AGGREGATION_BYTES))
|
(packet_len < BATADV_MAX_AGGREGATION_BYTES))
|
||||||
skb_size = BATADV_MAX_AGGREGATION_BYTES + ETH_HLEN;
|
skb_size = BATADV_MAX_AGGREGATION_BYTES;
|
||||||
else
|
else
|
||||||
skb_size = packet_len + ETH_HLEN;
|
skb_size = packet_len;
|
||||||
|
|
||||||
|
skb_size += ETH_HLEN + NET_IP_ALIGN;
|
||||||
|
|
||||||
forw_packet_aggr->skb = dev_alloc_skb(skb_size);
|
forw_packet_aggr->skb = dev_alloc_skb(skb_size);
|
||||||
if (!forw_packet_aggr->skb) {
|
if (!forw_packet_aggr->skb) {
|
||||||
|
@ -422,7 +424,7 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
|
||||||
kfree(forw_packet_aggr);
|
kfree(forw_packet_aggr);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
skb_reserve(forw_packet_aggr->skb, ETH_HLEN);
|
skb_reserve(forw_packet_aggr->skb, ETH_HLEN + NET_IP_ALIGN);
|
||||||
|
|
||||||
INIT_HLIST_NODE(&forw_packet_aggr->list);
|
INIT_HLIST_NODE(&forw_packet_aggr->list);
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "vis.h"
|
#include "vis.h"
|
||||||
#include "icmp_socket.h"
|
#include "icmp_socket.h"
|
||||||
#include "bridge_loop_avoidance.h"
|
#include "bridge_loop_avoidance.h"
|
||||||
|
#include "distributed-arp-table.h"
|
||||||
|
|
||||||
static struct dentry *batadv_debugfs;
|
static struct dentry *batadv_debugfs;
|
||||||
|
|
||||||
|
@ -280,6 +281,19 @@ static int batadv_bla_backbone_table_open(struct inode *inode,
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||||
|
/**
|
||||||
|
* batadv_dat_cache_open - Prepare file handler for reads from dat_chache
|
||||||
|
* @inode: inode which was opened
|
||||||
|
* @file: file handle to be initialized
|
||||||
|
*/
|
||||||
|
static int batadv_dat_cache_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
struct net_device *net_dev = (struct net_device *)inode->i_private;
|
||||||
|
return single_open(file, batadv_dat_cache_seq_print_text, net_dev);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int batadv_transtable_local_open(struct inode *inode, struct file *file)
|
static int batadv_transtable_local_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
struct net_device *net_dev = (struct net_device *)inode->i_private;
|
struct net_device *net_dev = (struct net_device *)inode->i_private;
|
||||||
|
@ -319,6 +333,9 @@ static BATADV_DEBUGINFO(bla_claim_table, S_IRUGO, batadv_bla_claim_table_open);
|
||||||
static BATADV_DEBUGINFO(bla_backbone_table, S_IRUGO,
|
static BATADV_DEBUGINFO(bla_backbone_table, S_IRUGO,
|
||||||
batadv_bla_backbone_table_open);
|
batadv_bla_backbone_table_open);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||||
|
static BATADV_DEBUGINFO(dat_cache, S_IRUGO, batadv_dat_cache_open);
|
||||||
|
#endif
|
||||||
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);
|
||||||
|
@ -330,6 +347,9 @@ static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
|
||||||
#ifdef CONFIG_BATMAN_ADV_BLA
|
#ifdef CONFIG_BATMAN_ADV_BLA
|
||||||
&batadv_debuginfo_bla_claim_table,
|
&batadv_debuginfo_bla_claim_table,
|
||||||
&batadv_debuginfo_bla_backbone_table,
|
&batadv_debuginfo_bla_backbone_table,
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||||
|
&batadv_debuginfo_dat_cache,
|
||||||
#endif
|
#endif
|
||||||
&batadv_debuginfo_transtable_local,
|
&batadv_debuginfo_transtable_local,
|
||||||
&batadv_debuginfo_vis_data,
|
&batadv_debuginfo_vis_data,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,167 @@
|
||||||
|
/* Copyright (C) 2011-2012 B.A.T.M.A.N. contributors:
|
||||||
|
*
|
||||||
|
* Antonio Quartulli
|
||||||
|
*
|
||||||
|
* 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_ARP_H_
|
||||||
|
#define _NET_BATMAN_ADV_ARP_H_
|
||||||
|
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "originator.h"
|
||||||
|
|
||||||
|
#include <linux/if_arp.h>
|
||||||
|
|
||||||
|
#define BATADV_DAT_ADDR_MAX ((batadv_dat_addr_t)~(batadv_dat_addr_t)0)
|
||||||
|
|
||||||
|
bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb);
|
||||||
|
bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb, int hdr_size);
|
||||||
|
void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb);
|
||||||
|
bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb, int hdr_size);
|
||||||
|
bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv,
|
||||||
|
struct batadv_forw_packet *forw_packet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_dat_init_orig_node_addr - assign a DAT address to the orig_node
|
||||||
|
* @orig_node: the node to assign the DAT address to
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
batadv_dat_init_orig_node_addr(struct batadv_orig_node *orig_node)
|
||||||
|
{
|
||||||
|
uint32_t addr;
|
||||||
|
|
||||||
|
addr = batadv_choose_orig(orig_node->orig, BATADV_DAT_ADDR_MAX);
|
||||||
|
orig_node->dat_addr = (batadv_dat_addr_t)addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_dat_init_own_addr - assign a DAT address to the node itself
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
* @primary_if: a pointer to the primary interface
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
batadv_dat_init_own_addr(struct batadv_priv *bat_priv,
|
||||||
|
struct batadv_hard_iface *primary_if)
|
||||||
|
{
|
||||||
|
uint32_t addr;
|
||||||
|
|
||||||
|
addr = batadv_choose_orig(primary_if->net_dev->dev_addr,
|
||||||
|
BATADV_DAT_ADDR_MAX);
|
||||||
|
|
||||||
|
bat_priv->dat.addr = (batadv_dat_addr_t)addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int batadv_dat_init(struct batadv_priv *bat_priv);
|
||||||
|
void batadv_dat_free(struct batadv_priv *bat_priv);
|
||||||
|
int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_dat_inc_counter - increment the correct DAT packet counter
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
* @subtype: the 4addr subtype of the packet to be counted
|
||||||
|
*
|
||||||
|
* Updates the ethtool statistics for the received packet if it is a DAT subtype
|
||||||
|
*/
|
||||||
|
static inline void batadv_dat_inc_counter(struct batadv_priv *bat_priv,
|
||||||
|
uint8_t subtype)
|
||||||
|
{
|
||||||
|
switch (subtype) {
|
||||||
|
case BATADV_P_DAT_DHT_GET:
|
||||||
|
batadv_inc_counter(bat_priv,
|
||||||
|
BATADV_CNT_DAT_GET_RX);
|
||||||
|
break;
|
||||||
|
case BATADV_P_DAT_DHT_PUT:
|
||||||
|
batadv_inc_counter(bat_priv,
|
||||||
|
BATADV_CNT_DAT_PUT_RX);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb, int hdr_size)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb, int hdr_size)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv,
|
||||||
|
struct batadv_forw_packet *forw_packet)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
batadv_dat_init_orig_node_addr(struct batadv_orig_node *orig_node)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void batadv_dat_init_own_addr(struct batadv_priv *bat_priv,
|
||||||
|
struct batadv_hard_iface *iface)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void batadv_arp_change_timeout(struct net_device *soft_iface,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int batadv_dat_init(struct batadv_priv *bat_priv)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void batadv_dat_free(struct batadv_priv *bat_priv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void batadv_dat_inc_counter(struct batadv_priv *bat_priv,
|
||||||
|
uint8_t subtype)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_BATMAN_ADV_DAT */
|
||||||
|
|
||||||
|
#endif /* _NET_BATMAN_ADV_ARP_H_ */
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "distributed-arp-table.h"
|
||||||
#include "hard-interface.h"
|
#include "hard-interface.h"
|
||||||
#include "soft-interface.h"
|
#include "soft-interface.h"
|
||||||
#include "send.h"
|
#include "send.h"
|
||||||
|
@ -109,6 +110,8 @@ static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv,
|
||||||
if (!primary_if)
|
if (!primary_if)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
batadv_dat_init_own_addr(bat_priv, primary_if);
|
||||||
|
|
||||||
skb = bat_priv->vis.my_info->skb_packet;
|
skb = bat_priv->vis.my_info->skb_packet;
|
||||||
vis_packet = (struct batadv_vis_packet *)skb->data;
|
vis_packet = (struct batadv_vis_packet *)skb->data;
|
||||||
memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
|
memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
|
||||||
|
|
|
@ -177,13 +177,13 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
|
||||||
if (len >= sizeof(struct batadv_icmp_packet_rr))
|
if (len >= sizeof(struct batadv_icmp_packet_rr))
|
||||||
packet_len = sizeof(struct batadv_icmp_packet_rr);
|
packet_len = sizeof(struct batadv_icmp_packet_rr);
|
||||||
|
|
||||||
skb = dev_alloc_skb(packet_len + ETH_HLEN);
|
skb = dev_alloc_skb(packet_len + ETH_HLEN + NET_IP_ALIGN);
|
||||||
if (!skb) {
|
if (!skb) {
|
||||||
len = -ENOMEM;
|
len = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
skb_reserve(skb, ETH_HLEN);
|
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
|
||||||
icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len);
|
icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len);
|
||||||
|
|
||||||
if (copy_from_user(icmp_packet, buff, packet_len)) {
|
if (copy_from_user(icmp_packet, buff, packet_len)) {
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "hard-interface.h"
|
#include "hard-interface.h"
|
||||||
#include "gateway_client.h"
|
#include "gateway_client.h"
|
||||||
#include "bridge_loop_avoidance.h"
|
#include "bridge_loop_avoidance.h"
|
||||||
|
#include "distributed-arp-table.h"
|
||||||
#include "vis.h"
|
#include "vis.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "bat_algo.h"
|
#include "bat_algo.h"
|
||||||
|
@ -128,6 +129,10 @@ int batadv_mesh_init(struct net_device *soft_iface)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
ret = batadv_dat_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);
|
||||||
|
|
||||||
|
@ -155,6 +160,8 @@ void batadv_mesh_free(struct net_device *soft_iface)
|
||||||
|
|
||||||
batadv_bla_free(bat_priv);
|
batadv_bla_free(bat_priv);
|
||||||
|
|
||||||
|
batadv_dat_free(bat_priv);
|
||||||
|
|
||||||
free_percpu(bat_priv->bat_counters);
|
free_percpu(bat_priv->bat_counters);
|
||||||
|
|
||||||
atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
|
atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
|
||||||
|
@ -300,6 +307,8 @@ static void batadv_recv_handler_init(void)
|
||||||
|
|
||||||
/* batman icmp packet */
|
/* batman icmp packet */
|
||||||
batadv_rx_handler[BATADV_ICMP] = batadv_recv_icmp_packet;
|
batadv_rx_handler[BATADV_ICMP] = batadv_recv_icmp_packet;
|
||||||
|
/* unicast with 4 addresses packet */
|
||||||
|
batadv_rx_handler[BATADV_UNICAST_4ADDR] = batadv_recv_unicast_packet;
|
||||||
/* unicast packet */
|
/* unicast packet */
|
||||||
batadv_rx_handler[BATADV_UNICAST] = batadv_recv_unicast_packet;
|
batadv_rx_handler[BATADV_UNICAST] = batadv_recv_unicast_packet;
|
||||||
/* fragmented unicast packet */
|
/* fragmented unicast packet */
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in milliseconds */
|
#define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in milliseconds */
|
||||||
#define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in milliseconds */
|
#define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in milliseconds */
|
||||||
#define BATADV_TT_CLIENT_TEMP_TIMEOUT 600000 /* in milliseconds */
|
#define BATADV_TT_CLIENT_TEMP_TIMEOUT 600000 /* in milliseconds */
|
||||||
|
#define BATADV_DAT_ENTRY_TIMEOUT (5*60000) /* 5 mins in milliseconds */
|
||||||
/* sliding packet range of received originator messages in sequence numbers
|
/* sliding packet range of received originator messages in sequence numbers
|
||||||
* (should be a multiple of our word size)
|
* (should be a multiple of our word size)
|
||||||
*/
|
*/
|
||||||
|
@ -73,6 +74,11 @@
|
||||||
|
|
||||||
#define BATADV_LOG_BUF_LEN 8192 /* has to be a power of 2 */
|
#define BATADV_LOG_BUF_LEN 8192 /* has to be a power of 2 */
|
||||||
|
|
||||||
|
/* msecs after which an ARP_REQUEST is sent in broadcast as fallback */
|
||||||
|
#define ARP_REQ_DELAY 250
|
||||||
|
/* numbers of originator to contact for any PUT/GET DHT operation */
|
||||||
|
#define BATADV_DAT_CANDIDATES_NUM 3
|
||||||
|
|
||||||
#define BATADV_VIS_INTERVAL 5000 /* 5 seconds */
|
#define BATADV_VIS_INTERVAL 5000 /* 5 seconds */
|
||||||
|
|
||||||
/* how much worse secondary interfaces may be to be considered as bonding
|
/* how much worse secondary interfaces may be to be considered as bonding
|
||||||
|
@ -117,6 +123,9 @@ enum batadv_uev_type {
|
||||||
|
|
||||||
#define BATADV_GW_THRESHOLD 50
|
#define BATADV_GW_THRESHOLD 50
|
||||||
|
|
||||||
|
#define BATADV_DAT_CANDIDATE_NOT_FOUND 0
|
||||||
|
#define BATADV_DAT_CANDIDATE_ORIG 1
|
||||||
|
|
||||||
/* Debug Messages */
|
/* Debug Messages */
|
||||||
#ifdef pr_fmt
|
#ifdef pr_fmt
|
||||||
#undef pr_fmt
|
#undef pr_fmt
|
||||||
|
@ -171,6 +180,7 @@ int batadv_algo_seq_print_text(struct seq_file *seq, void *offset);
|
||||||
* @BATADV_DBG_ROUTES: route added / changed / deleted
|
* @BATADV_DBG_ROUTES: route added / changed / deleted
|
||||||
* @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_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 {
|
||||||
|
@ -178,7 +188,8 @@ enum batadv_dbg_level {
|
||||||
BATADV_DBG_ROUTES = BIT(1),
|
BATADV_DBG_ROUTES = BIT(1),
|
||||||
BATADV_DBG_TT = BIT(2),
|
BATADV_DBG_TT = BIT(2),
|
||||||
BATADV_DBG_BLA = BIT(3),
|
BATADV_DBG_BLA = BIT(3),
|
||||||
BATADV_DBG_ALL = 15,
|
BATADV_DBG_DAT = BIT(4),
|
||||||
|
BATADV_DBG_ALL = 31,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "distributed-arp-table.h"
|
||||||
#include "originator.h"
|
#include "originator.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "translation-table.h"
|
#include "translation-table.h"
|
||||||
|
@ -223,6 +224,7 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
|
||||||
orig_node->tt_poss_change = false;
|
orig_node->tt_poss_change = false;
|
||||||
orig_node->bat_priv = bat_priv;
|
orig_node->bat_priv = bat_priv;
|
||||||
memcpy(orig_node->orig, addr, ETH_ALEN);
|
memcpy(orig_node->orig, addr, ETH_ALEN);
|
||||||
|
batadv_dat_init_orig_node_addr(orig_node);
|
||||||
orig_node->router = NULL;
|
orig_node->router = NULL;
|
||||||
orig_node->tt_crc = 0;
|
orig_node->tt_crc = 0;
|
||||||
atomic_set(&orig_node->last_ttvn, 0);
|
atomic_set(&orig_node->last_ttvn, 0);
|
||||||
|
|
|
@ -23,14 +23,29 @@
|
||||||
#define BATADV_ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */
|
#define BATADV_ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */
|
||||||
|
|
||||||
enum batadv_packettype {
|
enum batadv_packettype {
|
||||||
BATADV_IV_OGM = 0x01,
|
BATADV_IV_OGM = 0x01,
|
||||||
BATADV_ICMP = 0x02,
|
BATADV_ICMP = 0x02,
|
||||||
BATADV_UNICAST = 0x03,
|
BATADV_UNICAST = 0x03,
|
||||||
BATADV_BCAST = 0x04,
|
BATADV_BCAST = 0x04,
|
||||||
BATADV_VIS = 0x05,
|
BATADV_VIS = 0x05,
|
||||||
BATADV_UNICAST_FRAG = 0x06,
|
BATADV_UNICAST_FRAG = 0x06,
|
||||||
BATADV_TT_QUERY = 0x07,
|
BATADV_TT_QUERY = 0x07,
|
||||||
BATADV_ROAM_ADV = 0x08,
|
BATADV_ROAM_ADV = 0x08,
|
||||||
|
BATADV_UNICAST_4ADDR = 0x09,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum batadv_subtype - packet subtype for unicast4addr
|
||||||
|
* @BATADV_P_DATA: user payload
|
||||||
|
* @BATADV_P_DAT_DHT_GET: DHT request message
|
||||||
|
* @BATADV_P_DAT_DHT_PUT: DHT store message
|
||||||
|
* @BATADV_P_DAT_CACHE_REPLY: ARP reply generated by DAT
|
||||||
|
*/
|
||||||
|
enum batadv_subtype {
|
||||||
|
BATADV_P_DATA = 0x01,
|
||||||
|
BATADV_P_DAT_DHT_GET = 0x02,
|
||||||
|
BATADV_P_DAT_DHT_PUT = 0x03,
|
||||||
|
BATADV_P_DAT_CACHE_REPLY = 0x04,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* this file is included by batctl which needs these defines */
|
/* this file is included by batctl which needs these defines */
|
||||||
|
@ -106,13 +121,16 @@ struct batadv_bla_claim_dst {
|
||||||
uint8_t magic[3]; /* FF:43:05 */
|
uint8_t magic[3]; /* FF:43:05 */
|
||||||
uint8_t type; /* bla_claimframe */
|
uint8_t type; /* bla_claimframe */
|
||||||
__be16 group; /* group id */
|
__be16 group; /* group id */
|
||||||
} __packed;
|
};
|
||||||
|
|
||||||
struct batadv_header {
|
struct batadv_header {
|
||||||
uint8_t packet_type;
|
uint8_t packet_type;
|
||||||
uint8_t version; /* batman version field */
|
uint8_t version; /* batman version field */
|
||||||
uint8_t ttl;
|
uint8_t ttl;
|
||||||
} __packed;
|
/* the parent struct has to add a byte after the header to make
|
||||||
|
* everything 4 bytes aligned again
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
struct batadv_ogm_packet {
|
struct batadv_ogm_packet {
|
||||||
struct batadv_header header;
|
struct batadv_header header;
|
||||||
|
@ -137,7 +155,7 @@ struct batadv_icmp_packet {
|
||||||
__be16 seqno;
|
__be16 seqno;
|
||||||
uint8_t uid;
|
uint8_t uid;
|
||||||
uint8_t reserved;
|
uint8_t reserved;
|
||||||
} __packed;
|
};
|
||||||
|
|
||||||
#define BATADV_RR_LEN 16
|
#define BATADV_RR_LEN 16
|
||||||
|
|
||||||
|
@ -153,13 +171,32 @@ struct batadv_icmp_packet_rr {
|
||||||
uint8_t uid;
|
uint8_t uid;
|
||||||
uint8_t rr_cur;
|
uint8_t rr_cur;
|
||||||
uint8_t rr[BATADV_RR_LEN][ETH_ALEN];
|
uint8_t rr[BATADV_RR_LEN][ETH_ALEN];
|
||||||
} __packed;
|
};
|
||||||
|
|
||||||
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 */
|
||||||
uint8_t dest[ETH_ALEN];
|
uint8_t dest[ETH_ALEN];
|
||||||
} __packed;
|
/* "4 bytes boundary + 2 bytes" long to make the payload after the
|
||||||
|
* following ethernet header again 4 bytes boundary aligned
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct batadv_unicast_4addr_packet - extended unicast packet
|
||||||
|
* @u: common unicast packet header
|
||||||
|
* @src: address of the source
|
||||||
|
* @subtype: packet subtype
|
||||||
|
*/
|
||||||
|
struct batadv_unicast_4addr_packet {
|
||||||
|
struct batadv_unicast_packet u;
|
||||||
|
uint8_t src[ETH_ALEN];
|
||||||
|
uint8_t subtype;
|
||||||
|
uint8_t reserved;
|
||||||
|
/* "4 bytes boundary + 2 bytes" long to make the payload after the
|
||||||
|
* following ethernet header again 4 bytes boundary aligned
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
struct batadv_unicast_frag_packet {
|
struct batadv_unicast_frag_packet {
|
||||||
struct batadv_header header;
|
struct batadv_header header;
|
||||||
|
@ -176,6 +213,9 @@ struct batadv_bcast_packet {
|
||||||
uint8_t reserved;
|
uint8_t reserved;
|
||||||
__be32 seqno;
|
__be32 seqno;
|
||||||
uint8_t orig[ETH_ALEN];
|
uint8_t orig[ETH_ALEN];
|
||||||
|
/* "4 bytes boundary + 2 bytes" long to make the payload after the
|
||||||
|
* following ethernet header again 4 bytes boundary aligned
|
||||||
|
*/
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct batadv_vis_packet {
|
struct batadv_vis_packet {
|
||||||
|
@ -187,7 +227,7 @@ struct batadv_vis_packet {
|
||||||
uint8_t vis_orig[ETH_ALEN]; /* originator reporting its neighbors */
|
uint8_t vis_orig[ETH_ALEN]; /* originator reporting its neighbors */
|
||||||
uint8_t target_orig[ETH_ALEN]; /* who should receive this packet */
|
uint8_t target_orig[ETH_ALEN]; /* who should receive this packet */
|
||||||
uint8_t sender_orig[ETH_ALEN]; /* who sent or forwarded this packet */
|
uint8_t sender_orig[ETH_ALEN]; /* who sent or forwarded this packet */
|
||||||
} __packed;
|
};
|
||||||
|
|
||||||
struct batadv_tt_query_packet {
|
struct batadv_tt_query_packet {
|
||||||
struct batadv_header header;
|
struct batadv_header header;
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "vis.h"
|
#include "vis.h"
|
||||||
#include "unicast.h"
|
#include "unicast.h"
|
||||||
#include "bridge_loop_avoidance.h"
|
#include "bridge_loop_avoidance.h"
|
||||||
|
#include "distributed-arp-table.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);
|
||||||
|
@ -984,7 +985,19 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
|
||||||
{
|
{
|
||||||
struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
|
struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
|
||||||
struct batadv_unicast_packet *unicast_packet;
|
struct batadv_unicast_packet *unicast_packet;
|
||||||
|
struct batadv_unicast_4addr_packet *unicast_4addr_packet;
|
||||||
|
uint8_t *orig_addr;
|
||||||
|
struct batadv_orig_node *orig_node = NULL;
|
||||||
int hdr_size = sizeof(*unicast_packet);
|
int hdr_size = sizeof(*unicast_packet);
|
||||||
|
bool is4addr;
|
||||||
|
|
||||||
|
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
||||||
|
unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
|
||||||
|
|
||||||
|
is4addr = unicast_packet->header.packet_type == BATADV_UNICAST_4ADDR;
|
||||||
|
/* the caller function should have already pulled 2 bytes */
|
||||||
|
if (is4addr)
|
||||||
|
hdr_size = sizeof(*unicast_4addr_packet);
|
||||||
|
|
||||||
if (batadv_check_unicast_packet(skb, hdr_size) < 0)
|
if (batadv_check_unicast_packet(skb, hdr_size) < 0)
|
||||||
return NET_RX_DROP;
|
return NET_RX_DROP;
|
||||||
|
@ -992,12 +1005,28 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
|
||||||
if (!batadv_check_unicast_ttvn(bat_priv, skb))
|
if (!batadv_check_unicast_ttvn(bat_priv, skb))
|
||||||
return NET_RX_DROP;
|
return NET_RX_DROP;
|
||||||
|
|
||||||
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
|
||||||
|
|
||||||
/* packet for me */
|
/* packet for me */
|
||||||
if (batadv_is_my_mac(unicast_packet->dest)) {
|
if (batadv_is_my_mac(unicast_packet->dest)) {
|
||||||
|
if (is4addr) {
|
||||||
|
batadv_dat_inc_counter(bat_priv,
|
||||||
|
unicast_4addr_packet->subtype);
|
||||||
|
orig_addr = unicast_4addr_packet->src;
|
||||||
|
orig_node = batadv_orig_hash_find(bat_priv, orig_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb,
|
||||||
|
hdr_size))
|
||||||
|
goto rx_success;
|
||||||
|
if (batadv_dat_snoop_incoming_arp_reply(bat_priv, skb,
|
||||||
|
hdr_size))
|
||||||
|
goto rx_success;
|
||||||
|
|
||||||
batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size,
|
batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size,
|
||||||
NULL);
|
orig_node);
|
||||||
|
|
||||||
|
rx_success:
|
||||||
|
if (orig_node)
|
||||||
|
batadv_orig_node_free_ref(orig_node);
|
||||||
|
|
||||||
return NET_RX_SUCCESS;
|
return NET_RX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1034,8 +1063,17 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
|
||||||
if (!new_skb)
|
if (!new_skb)
|
||||||
return NET_RX_SUCCESS;
|
return NET_RX_SUCCESS;
|
||||||
|
|
||||||
|
if (batadv_dat_snoop_incoming_arp_request(bat_priv, new_skb,
|
||||||
|
hdr_size))
|
||||||
|
goto rx_success;
|
||||||
|
if (batadv_dat_snoop_incoming_arp_reply(bat_priv, new_skb,
|
||||||
|
hdr_size))
|
||||||
|
goto rx_success;
|
||||||
|
|
||||||
batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if,
|
batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if,
|
||||||
sizeof(struct batadv_unicast_packet), NULL);
|
sizeof(struct batadv_unicast_packet), NULL);
|
||||||
|
|
||||||
|
rx_success:
|
||||||
return NET_RX_SUCCESS;
|
return NET_RX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1127,9 +1165,16 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
|
||||||
if (batadv_bla_is_backbone_gw(skb, orig_node, hdr_size))
|
if (batadv_bla_is_backbone_gw(skb, orig_node, hdr_size))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb, hdr_size))
|
||||||
|
goto rx_success;
|
||||||
|
if (batadv_dat_snoop_incoming_arp_reply(bat_priv, skb, hdr_size))
|
||||||
|
goto rx_success;
|
||||||
|
|
||||||
/* broadcast for me */
|
/* broadcast for me */
|
||||||
batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size,
|
batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size,
|
||||||
orig_node);
|
orig_node);
|
||||||
|
|
||||||
|
rx_success:
|
||||||
ret = NET_RX_SUCCESS;
|
ret = NET_RX_SUCCESS;
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "distributed-arp-table.h"
|
||||||
#include "send.h"
|
#include "send.h"
|
||||||
#include "routing.h"
|
#include "routing.h"
|
||||||
#include "translation-table.h"
|
#include "translation-table.h"
|
||||||
|
@ -209,6 +210,9 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
|
||||||
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
|
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (batadv_dat_drop_broadcast_packet(bat_priv, forw_packet))
|
||||||
|
goto out;
|
||||||
|
|
||||||
/* rebroadcast packet */
|
/* rebroadcast packet */
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
|
list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "soft-interface.h"
|
#include "soft-interface.h"
|
||||||
#include "hard-interface.h"
|
#include "hard-interface.h"
|
||||||
|
#include "distributed-arp-table.h"
|
||||||
#include "routing.h"
|
#include "routing.h"
|
||||||
#include "send.h"
|
#include "send.h"
|
||||||
#include "debugfs.h"
|
#include "debugfs.h"
|
||||||
|
@ -155,6 +156,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
|
||||||
short vid __maybe_unused = -1;
|
short vid __maybe_unused = -1;
|
||||||
bool do_bcast = false;
|
bool do_bcast = false;
|
||||||
uint32_t seqno;
|
uint32_t seqno;
|
||||||
|
unsigned long brd_delay = 1;
|
||||||
|
|
||||||
if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
|
if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
|
||||||
goto dropped;
|
goto dropped;
|
||||||
|
@ -224,6 +226,13 @@ static int batadv_interface_tx(struct sk_buff *skb,
|
||||||
if (!primary_if)
|
if (!primary_if)
|
||||||
goto dropped;
|
goto dropped;
|
||||||
|
|
||||||
|
/* in case of ARP request, we do not immediately broadcasti the
|
||||||
|
* packet, instead we first wait for DAT to try to retrieve the
|
||||||
|
* correct ARP entry
|
||||||
|
*/
|
||||||
|
if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb))
|
||||||
|
brd_delay = msecs_to_jiffies(ARP_REQ_DELAY);
|
||||||
|
|
||||||
if (batadv_skb_head_push(skb, sizeof(*bcast_packet)) < 0)
|
if (batadv_skb_head_push(skb, sizeof(*bcast_packet)) < 0)
|
||||||
goto dropped;
|
goto dropped;
|
||||||
|
|
||||||
|
@ -245,7 +254,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
|
||||||
seqno = atomic_inc_return(&bat_priv->bcast_seqno);
|
seqno = atomic_inc_return(&bat_priv->bcast_seqno);
|
||||||
bcast_packet->seqno = htonl(seqno);
|
bcast_packet->seqno = htonl(seqno);
|
||||||
|
|
||||||
batadv_add_bcast_packet_to_list(bat_priv, skb, 1);
|
batadv_add_bcast_packet_to_list(bat_priv, skb, brd_delay);
|
||||||
|
|
||||||
/* a copy is stored in the bcast list, therefore removing
|
/* a copy is stored in the bcast list, therefore removing
|
||||||
* the original skb.
|
* the original skb.
|
||||||
|
@ -260,7 +269,12 @@ static int batadv_interface_tx(struct sk_buff *skb,
|
||||||
goto dropped;
|
goto dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = batadv_unicast_send_skb(skb, bat_priv);
|
if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb))
|
||||||
|
goto dropped;
|
||||||
|
|
||||||
|
batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb);
|
||||||
|
|
||||||
|
ret = batadv_unicast_send_skb(bat_priv, skb);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto dropped_freed;
|
goto dropped_freed;
|
||||||
}
|
}
|
||||||
|
@ -466,6 +480,9 @@ struct net_device *batadv_softif_create(const char *name)
|
||||||
atomic_set(&bat_priv->aggregated_ogms, 1);
|
atomic_set(&bat_priv->aggregated_ogms, 1);
|
||||||
atomic_set(&bat_priv->bonding, 0);
|
atomic_set(&bat_priv->bonding, 0);
|
||||||
atomic_set(&bat_priv->bridge_loop_avoidance, 0);
|
atomic_set(&bat_priv->bridge_loop_avoidance, 0);
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||||
|
atomic_set(&bat_priv->distributed_arp_table, 1);
|
||||||
|
#endif
|
||||||
atomic_set(&bat_priv->ap_isolation, 0);
|
atomic_set(&bat_priv->ap_isolation, 0);
|
||||||
atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE);
|
atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE);
|
||||||
atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
|
atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
|
||||||
|
@ -608,6 +625,13 @@ static const struct {
|
||||||
{ "tt_response_rx" },
|
{ "tt_response_rx" },
|
||||||
{ "tt_roam_adv_tx" },
|
{ "tt_roam_adv_tx" },
|
||||||
{ "tt_roam_adv_rx" },
|
{ "tt_roam_adv_rx" },
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||||
|
{ "dat_get_tx" },
|
||||||
|
{ "dat_get_rx" },
|
||||||
|
{ "dat_put_tx" },
|
||||||
|
{ "dat_put_rx" },
|
||||||
|
{ "dat_cached_reply_tx" },
|
||||||
|
#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,
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "sysfs.h"
|
#include "sysfs.h"
|
||||||
#include "translation-table.h"
|
#include "translation-table.h"
|
||||||
|
#include "distributed-arp-table.h"
|
||||||
#include "originator.h"
|
#include "originator.h"
|
||||||
#include "hard-interface.h"
|
#include "hard-interface.h"
|
||||||
#include "gateway_common.h"
|
#include "gateway_common.h"
|
||||||
|
@ -420,6 +421,9 @@ BATADV_ATTR_SIF_BOOL(bonding, S_IRUGO | S_IWUSR, NULL);
|
||||||
#ifdef CONFIG_BATMAN_ADV_BLA
|
#ifdef CONFIG_BATMAN_ADV_BLA
|
||||||
BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL);
|
BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||||
|
BATADV_ATTR_SIF_BOOL(distributed_arp_table, S_IRUGO | S_IWUSR, NULL);
|
||||||
|
#endif
|
||||||
BATADV_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu);
|
BATADV_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu);
|
||||||
BATADV_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
|
BATADV_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
|
||||||
static BATADV_ATTR(vis_mode, S_IRUGO | S_IWUSR, batadv_show_vis_mode,
|
static BATADV_ATTR(vis_mode, S_IRUGO | S_IWUSR, batadv_show_vis_mode,
|
||||||
|
@ -444,6 +448,9 @@ static struct batadv_attribute *batadv_mesh_attrs[] = {
|
||||||
&batadv_attr_bonding,
|
&batadv_attr_bonding,
|
||||||
#ifdef CONFIG_BATMAN_ADV_BLA
|
#ifdef CONFIG_BATMAN_ADV_BLA
|
||||||
&batadv_attr_bridge_loop_avoidance,
|
&batadv_attr_bridge_loop_avoidance,
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||||
|
&batadv_attr_distributed_arp_table,
|
||||||
#endif
|
#endif
|
||||||
&batadv_attr_fragmentation,
|
&batadv_attr_fragmentation,
|
||||||
&batadv_attr_ap_isolation,
|
&batadv_attr_ap_isolation,
|
||||||
|
|
|
@ -1472,11 +1472,11 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
|
||||||
tt_tot = tt_len / sizeof(struct batadv_tt_change);
|
tt_tot = tt_len / sizeof(struct batadv_tt_change);
|
||||||
|
|
||||||
len = tt_query_size + tt_len;
|
len = tt_query_size + tt_len;
|
||||||
skb = dev_alloc_skb(len + ETH_HLEN);
|
skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
skb_reserve(skb, ETH_HLEN);
|
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
|
||||||
tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len);
|
tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len);
|
||||||
tt_response->ttvn = ttvn;
|
tt_response->ttvn = ttvn;
|
||||||
|
|
||||||
|
@ -1538,11 +1538,11 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
|
||||||
if (!tt_req_node)
|
if (!tt_req_node)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
skb = dev_alloc_skb(sizeof(*tt_request) + ETH_HLEN);
|
skb = dev_alloc_skb(sizeof(*tt_request) + ETH_HLEN + NET_IP_ALIGN);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
skb_reserve(skb, ETH_HLEN);
|
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
|
||||||
|
|
||||||
tt_req_len = sizeof(*tt_request);
|
tt_req_len = sizeof(*tt_request);
|
||||||
tt_request = (struct batadv_tt_query_packet *)skb_put(skb, tt_req_len);
|
tt_request = (struct batadv_tt_query_packet *)skb_put(skb, tt_req_len);
|
||||||
|
@ -1653,11 +1653,11 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
|
||||||
tt_tot = tt_len / sizeof(struct batadv_tt_change);
|
tt_tot = tt_len / sizeof(struct batadv_tt_change);
|
||||||
|
|
||||||
len = sizeof(*tt_response) + tt_len;
|
len = sizeof(*tt_response) + tt_len;
|
||||||
skb = dev_alloc_skb(len + ETH_HLEN);
|
skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
skb_reserve(skb, ETH_HLEN);
|
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
|
||||||
packet_pos = skb_put(skb, len);
|
packet_pos = skb_put(skb, len);
|
||||||
tt_response = (struct batadv_tt_query_packet *)packet_pos;
|
tt_response = (struct batadv_tt_query_packet *)packet_pos;
|
||||||
tt_response->ttvn = req_ttvn;
|
tt_response->ttvn = req_ttvn;
|
||||||
|
@ -1780,11 +1780,11 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
|
||||||
tt_tot = tt_len / sizeof(struct batadv_tt_change);
|
tt_tot = tt_len / sizeof(struct batadv_tt_change);
|
||||||
|
|
||||||
len = sizeof(*tt_response) + tt_len;
|
len = sizeof(*tt_response) + tt_len;
|
||||||
skb = dev_alloc_skb(len + ETH_HLEN);
|
skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
skb_reserve(skb, ETH_HLEN);
|
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
|
||||||
packet_pos = skb_put(skb, len);
|
packet_pos = skb_put(skb, len);
|
||||||
tt_response = (struct batadv_tt_query_packet *)packet_pos;
|
tt_response = (struct batadv_tt_query_packet *)packet_pos;
|
||||||
tt_response->ttvn = req_ttvn;
|
tt_response->ttvn = req_ttvn;
|
||||||
|
@ -2118,11 +2118,11 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
|
||||||
if (!batadv_tt_check_roam_count(bat_priv, client))
|
if (!batadv_tt_check_roam_count(bat_priv, client))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
skb = dev_alloc_skb(sizeof(*roam_adv_packet) + ETH_HLEN);
|
skb = dev_alloc_skb(sizeof(*roam_adv_packet) + ETH_HLEN + NET_IP_ALIGN);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
skb_reserve(skb, ETH_HLEN);
|
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
|
||||||
|
|
||||||
roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len);
|
roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len);
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,17 @@
|
||||||
(ETH_HLEN + max(sizeof(struct batadv_unicast_packet), \
|
(ETH_HLEN + max(sizeof(struct batadv_unicast_packet), \
|
||||||
sizeof(struct batadv_bcast_packet)))
|
sizeof(struct batadv_bcast_packet)))
|
||||||
|
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||||
|
|
||||||
|
/* batadv_dat_addr_t is the type used for all DHT addresses. If it is changed,
|
||||||
|
* BATADV_DAT_ADDR_MAX is changed as well.
|
||||||
|
*
|
||||||
|
* *Please be careful: batadv_dat_addr_t must be UNSIGNED*
|
||||||
|
*/
|
||||||
|
#define batadv_dat_addr_t uint16_t
|
||||||
|
|
||||||
|
#endif /* CONFIG_BATMAN_ADV_DAT */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct batadv_hard_iface_bat_iv - per hard interface B.A.T.M.A.N. IV data
|
* struct batadv_hard_iface_bat_iv - per hard interface B.A.T.M.A.N. IV data
|
||||||
* @ogm_buff: buffer holding the OGM packet
|
* @ogm_buff: buffer holding the OGM packet
|
||||||
|
@ -73,6 +84,9 @@ struct batadv_orig_node {
|
||||||
uint8_t orig[ETH_ALEN];
|
uint8_t orig[ETH_ALEN];
|
||||||
uint8_t primary_addr[ETH_ALEN];
|
uint8_t primary_addr[ETH_ALEN];
|
||||||
struct batadv_neigh_node __rcu *router; /* rcu protected pointer */
|
struct batadv_neigh_node __rcu *router; /* rcu protected pointer */
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||||
|
batadv_dat_addr_t dat_addr;
|
||||||
|
#endif
|
||||||
unsigned long *bcast_own;
|
unsigned long *bcast_own;
|
||||||
uint8_t *bcast_own_sum;
|
uint8_t *bcast_own_sum;
|
||||||
unsigned long last_seen;
|
unsigned long last_seen;
|
||||||
|
@ -172,6 +186,13 @@ enum batadv_counters {
|
||||||
BATADV_CNT_TT_RESPONSE_RX,
|
BATADV_CNT_TT_RESPONSE_RX,
|
||||||
BATADV_CNT_TT_ROAM_ADV_TX,
|
BATADV_CNT_TT_ROAM_ADV_TX,
|
||||||
BATADV_CNT_TT_ROAM_ADV_RX,
|
BATADV_CNT_TT_ROAM_ADV_RX,
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||||
|
BATADV_CNT_DAT_GET_TX,
|
||||||
|
BATADV_CNT_DAT_GET_RX,
|
||||||
|
BATADV_CNT_DAT_PUT_TX,
|
||||||
|
BATADV_CNT_DAT_PUT_RX,
|
||||||
|
BATADV_CNT_DAT_CACHED_REPLY_TX,
|
||||||
|
#endif
|
||||||
BATADV_CNT_NUM,
|
BATADV_CNT_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -238,6 +259,20 @@ struct batadv_priv_vis {
|
||||||
struct batadv_vis_info *my_info;
|
struct batadv_vis_info *my_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct batadv_priv_dat - per mesh interface DAT private data
|
||||||
|
* @addr: node DAT address
|
||||||
|
* @hash: hashtable representing the local ARP cache
|
||||||
|
* @work: work queue callback item for cache purging
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||||
|
struct batadv_priv_dat {
|
||||||
|
batadv_dat_addr_t addr;
|
||||||
|
struct batadv_hashtable *hash;
|
||||||
|
struct delayed_work work;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
struct batadv_priv {
|
struct batadv_priv {
|
||||||
atomic_t mesh_state;
|
atomic_t mesh_state;
|
||||||
struct net_device_stats stats;
|
struct net_device_stats stats;
|
||||||
|
@ -247,6 +282,9 @@ struct batadv_priv {
|
||||||
atomic_t fragmentation; /* boolean */
|
atomic_t fragmentation; /* boolean */
|
||||||
atomic_t ap_isolation; /* boolean */
|
atomic_t ap_isolation; /* boolean */
|
||||||
atomic_t bridge_loop_avoidance; /* boolean */
|
atomic_t bridge_loop_avoidance; /* boolean */
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||||
|
atomic_t distributed_arp_table; /* boolean */
|
||||||
|
#endif
|
||||||
atomic_t vis_mode; /* VIS_TYPE_* */
|
atomic_t vis_mode; /* VIS_TYPE_* */
|
||||||
atomic_t gw_mode; /* GW_MODE_* */
|
atomic_t gw_mode; /* GW_MODE_* */
|
||||||
atomic_t gw_sel_class; /* uint */
|
atomic_t gw_sel_class; /* uint */
|
||||||
|
@ -275,6 +313,9 @@ struct batadv_priv {
|
||||||
struct batadv_priv_gw gw;
|
struct batadv_priv_gw gw;
|
||||||
struct batadv_priv_tt tt;
|
struct batadv_priv_tt tt;
|
||||||
struct batadv_priv_vis vis;
|
struct batadv_priv_vis vis;
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||||
|
struct batadv_priv_dat dat;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct batadv_socket_client {
|
struct batadv_socket_client {
|
||||||
|
@ -447,4 +488,36 @@ struct batadv_algo_ops {
|
||||||
void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet);
|
void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct batadv_dat_entry - it is a single entry of batman-adv ARP backend. It
|
||||||
|
* is used to stored ARP entries needed for the global DAT cache
|
||||||
|
* @ip: the IPv4 corresponding to this DAT/ARP entry
|
||||||
|
* @mac_addr: the MAC address associated to the stored IPv4
|
||||||
|
* @last_update: time in jiffies when this entry was refreshed last time
|
||||||
|
* @hash_entry: hlist node for batadv_priv_dat::hash
|
||||||
|
* @refcount: number of contexts the object is used
|
||||||
|
* @rcu: struct used for freeing in an RCU-safe manner
|
||||||
|
*/
|
||||||
|
struct batadv_dat_entry {
|
||||||
|
__be32 ip;
|
||||||
|
uint8_t mac_addr[ETH_ALEN];
|
||||||
|
unsigned long last_update;
|
||||||
|
struct hlist_node hash_entry;
|
||||||
|
atomic_t refcount;
|
||||||
|
struct rcu_head rcu;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct batadv_dat_candidate - candidate destination for DAT operations
|
||||||
|
* @type: the type of the selected candidate. It can one of the following:
|
||||||
|
* - BATADV_DAT_CANDIDATE_NOT_FOUND
|
||||||
|
* - BATADV_DAT_CANDIDATE_ORIG
|
||||||
|
* @orig_node: if type is BATADV_DAT_CANDIDATE_ORIG this field points to the
|
||||||
|
* corresponding originator node structure
|
||||||
|
*/
|
||||||
|
struct batadv_dat_candidate {
|
||||||
|
int type;
|
||||||
|
struct batadv_orig_node *orig_node;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_TYPES_H_ */
|
#endif /* _NET_BATMAN_ADV_TYPES_H_ */
|
||||||
|
|
|
@ -291,7 +291,111 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int batadv_unicast_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv)
|
/**
|
||||||
|
* batadv_unicast_push_and_fill_skb - extends the buffer and initializes the
|
||||||
|
* common fields for unicast packets
|
||||||
|
* @skb: packet
|
||||||
|
* @hdr_size: amount of bytes to push at the beginning of the skb
|
||||||
|
* @orig_node: the destination node
|
||||||
|
*
|
||||||
|
* Returns false if the buffer extension was not possible or true otherwise
|
||||||
|
*/
|
||||||
|
static bool batadv_unicast_push_and_fill_skb(struct sk_buff *skb, int hdr_size,
|
||||||
|
struct batadv_orig_node *orig_node)
|
||||||
|
{
|
||||||
|
struct batadv_unicast_packet *unicast_packet;
|
||||||
|
uint8_t ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
|
||||||
|
|
||||||
|
if (batadv_skb_head_push(skb, hdr_size) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
||||||
|
unicast_packet->header.version = BATADV_COMPAT_VERSION;
|
||||||
|
/* batman packet type: unicast */
|
||||||
|
unicast_packet->header.packet_type = BATADV_UNICAST;
|
||||||
|
/* set unicast ttl */
|
||||||
|
unicast_packet->header.ttl = BATADV_TTL;
|
||||||
|
/* copy the destination for faster routing */
|
||||||
|
memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
|
||||||
|
/* set the destination tt version number */
|
||||||
|
unicast_packet->ttvn = ttvn;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_unicast_prepare_skb - encapsulate an skb with a unicast header
|
||||||
|
* @skb: the skb containing the payload to encapsulate
|
||||||
|
* @orig_node: the destination node
|
||||||
|
*
|
||||||
|
* Returns false if the payload could not be encapsulated or true otherwise
|
||||||
|
*/
|
||||||
|
static bool batadv_unicast_prepare_skb(struct sk_buff *skb,
|
||||||
|
struct batadv_orig_node *orig_node)
|
||||||
|
{
|
||||||
|
size_t uni_size = sizeof(struct batadv_unicast_packet);
|
||||||
|
return batadv_unicast_push_and_fill_skb(skb, uni_size, orig_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_unicast_4addr_prepare_skb - encapsulate an skb with a unicast4addr
|
||||||
|
* header
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
* @skb: the skb containing the payload to encapsulate
|
||||||
|
* @orig_node: the destination node
|
||||||
|
* @packet_subtype: the batman 4addr packet subtype to use
|
||||||
|
*
|
||||||
|
* Returns false if the payload could not be encapsulated or true otherwise
|
||||||
|
*/
|
||||||
|
bool batadv_unicast_4addr_prepare_skb(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
struct batadv_orig_node *orig,
|
||||||
|
int packet_subtype)
|
||||||
|
{
|
||||||
|
struct batadv_hard_iface *primary_if;
|
||||||
|
struct batadv_unicast_4addr_packet *unicast_4addr_packet;
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
primary_if = batadv_primary_if_get_selected(bat_priv);
|
||||||
|
if (!primary_if)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* pull the header space and fill the unicast_packet substructure.
|
||||||
|
* We can do that because the first member of the unicast_4addr_packet
|
||||||
|
* is of type struct unicast_packet
|
||||||
|
*/
|
||||||
|
if (!batadv_unicast_push_and_fill_skb(skb,
|
||||||
|
sizeof(*unicast_4addr_packet),
|
||||||
|
orig))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
|
||||||
|
unicast_4addr_packet->u.header.packet_type = BATADV_UNICAST_4ADDR;
|
||||||
|
memcpy(unicast_4addr_packet->src, primary_if->net_dev->dev_addr,
|
||||||
|
ETH_ALEN);
|
||||||
|
unicast_4addr_packet->subtype = packet_subtype;
|
||||||
|
unicast_4addr_packet->reserved = 0;
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
out:
|
||||||
|
if (primary_if)
|
||||||
|
batadv_hardif_free_ref(primary_if);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_unicast_generic_send_skb - send an skb as unicast
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
* @skb: payload to send
|
||||||
|
* @packet_type: the batman unicast packet type to use
|
||||||
|
* @packet_subtype: the batman packet subtype. It is ignored if packet_type is
|
||||||
|
* not BATADV_UNICAT_4ADDR
|
||||||
|
*
|
||||||
|
* Returns 1 in case of error or 0 otherwise
|
||||||
|
*/
|
||||||
|
int batadv_unicast_generic_send_skb(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb, int packet_type,
|
||||||
|
int packet_subtype)
|
||||||
{
|
{
|
||||||
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
|
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
|
||||||
struct batadv_unicast_packet *unicast_packet;
|
struct batadv_unicast_packet *unicast_packet;
|
||||||
|
@ -324,21 +428,23 @@ find_router:
|
||||||
if (!neigh_node)
|
if (!neigh_node)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (batadv_skb_head_push(skb, sizeof(*unicast_packet)) < 0)
|
switch (packet_type) {
|
||||||
|
case BATADV_UNICAST:
|
||||||
|
batadv_unicast_prepare_skb(skb, orig_node);
|
||||||
|
break;
|
||||||
|
case BATADV_UNICAST_4ADDR:
|
||||||
|
batadv_unicast_4addr_prepare_skb(bat_priv, skb, orig_node,
|
||||||
|
packet_subtype);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* this function supports UNICAST and UNICAST_4ADDR only. It
|
||||||
|
* should never be invoked with any other packet type
|
||||||
|
*/
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
||||||
|
|
||||||
unicast_packet->header.version = BATADV_COMPAT_VERSION;
|
|
||||||
/* batman packet type: unicast */
|
|
||||||
unicast_packet->header.packet_type = BATADV_UNICAST;
|
|
||||||
/* set unicast ttl */
|
|
||||||
unicast_packet->header.ttl = BATADV_TTL;
|
|
||||||
/* copy the destination for faster routing */
|
|
||||||
memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
|
|
||||||
/* set the destination tt version number */
|
|
||||||
unicast_packet->ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
|
|
||||||
|
|
||||||
/* inform the destination node that we are still missing a correct route
|
/* inform the destination node that we are still missing a correct route
|
||||||
* for this client. The destination will receive this packet and will
|
* for this client. The destination will receive this packet and will
|
||||||
* try to reroute it because the ttvn contained in the header is less
|
* try to reroute it because the ttvn contained in the header is less
|
||||||
|
@ -348,7 +454,9 @@ find_router:
|
||||||
unicast_packet->ttvn = unicast_packet->ttvn - 1;
|
unicast_packet->ttvn = unicast_packet->ttvn - 1;
|
||||||
|
|
||||||
dev_mtu = neigh_node->if_incoming->net_dev->mtu;
|
dev_mtu = neigh_node->if_incoming->net_dev->mtu;
|
||||||
if (atomic_read(&bat_priv->fragmentation) &&
|
/* fragmentation mechanism only works for UNICAST (now) */
|
||||||
|
if (packet_type == BATADV_UNICAST &&
|
||||||
|
atomic_read(&bat_priv->fragmentation) &&
|
||||||
data_len + sizeof(*unicast_packet) > dev_mtu) {
|
data_len + sizeof(*unicast_packet) > dev_mtu) {
|
||||||
/* send frag skb decreases ttl */
|
/* send frag skb decreases ttl */
|
||||||
unicast_packet->header.ttl++;
|
unicast_packet->header.ttl++;
|
||||||
|
@ -360,7 +468,6 @@ find_router:
|
||||||
|
|
||||||
batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
|
batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto out;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (neigh_node)
|
if (neigh_node)
|
||||||
|
|
|
@ -29,10 +29,44 @@ int batadv_frag_reassemble_skb(struct sk_buff *skb,
|
||||||
struct batadv_priv *bat_priv,
|
struct batadv_priv *bat_priv,
|
||||||
struct sk_buff **new_skb);
|
struct sk_buff **new_skb);
|
||||||
void batadv_frag_list_free(struct list_head *head);
|
void batadv_frag_list_free(struct list_head *head);
|
||||||
int batadv_unicast_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv);
|
|
||||||
int batadv_frag_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv,
|
int batadv_frag_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv,
|
||||||
struct batadv_hard_iface *hard_iface,
|
struct batadv_hard_iface *hard_iface,
|
||||||
const uint8_t dstaddr[]);
|
const uint8_t dstaddr[]);
|
||||||
|
bool batadv_unicast_4addr_prepare_skb(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
struct batadv_orig_node *orig_node,
|
||||||
|
int packet_subtype);
|
||||||
|
int batadv_unicast_generic_send_skb(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb, int packet_type,
|
||||||
|
int packet_subtype);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_unicast_send_skb - send the skb encapsulated in a unicast packet
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
* @skb: the payload to send
|
||||||
|
*/
|
||||||
|
static inline int batadv_unicast_send_skb(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return batadv_unicast_generic_send_skb(bat_priv, skb, BATADV_UNICAST,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_unicast_send_skb - send the skb encapsulated in a unicast4addr packet
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
* @skb: the payload to send
|
||||||
|
* @packet_subtype: the batman 4addr packet subtype to use
|
||||||
|
*/
|
||||||
|
static inline int batadv_unicast_4addr_send_skb(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
int packet_subtype)
|
||||||
|
{
|
||||||
|
return batadv_unicast_generic_send_skb(bat_priv, skb,
|
||||||
|
BATADV_UNICAST_4ADDR,
|
||||||
|
packet_subtype);
|
||||||
|
}
|
||||||
|
|
||||||
static inline int batadv_frag_can_reassemble(const struct sk_buff *skb, int mtu)
|
static inline int batadv_frag_can_reassemble(const struct sk_buff *skb, int mtu)
|
||||||
{
|
{
|
||||||
|
|
|
@ -396,12 +396,12 @@ batadv_add_packet(struct batadv_priv *bat_priv,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
len = sizeof(*packet) + vis_info_len;
|
len = sizeof(*packet) + vis_info_len;
|
||||||
info->skb_packet = dev_alloc_skb(len + ETH_HLEN);
|
info->skb_packet = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
|
||||||
if (!info->skb_packet) {
|
if (!info->skb_packet) {
|
||||||
kfree(info);
|
kfree(info);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
skb_reserve(info->skb_packet, ETH_HLEN);
|
skb_reserve(info->skb_packet, ETH_HLEN + NET_IP_ALIGN);
|
||||||
packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len);
|
packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len);
|
||||||
|
|
||||||
kref_init(&info->refcount);
|
kref_init(&info->refcount);
|
||||||
|
@ -873,12 +873,13 @@ int batadv_vis_init(struct batadv_priv *bat_priv)
|
||||||
if (!bat_priv->vis.my_info)
|
if (!bat_priv->vis.my_info)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE + ETH_HLEN;
|
len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE;
|
||||||
|
len += ETH_HLEN + NET_IP_ALIGN;
|
||||||
bat_priv->vis.my_info->skb_packet = dev_alloc_skb(len);
|
bat_priv->vis.my_info->skb_packet = dev_alloc_skb(len);
|
||||||
if (!bat_priv->vis.my_info->skb_packet)
|
if (!bat_priv->vis.my_info->skb_packet)
|
||||||
goto free_info;
|
goto free_info;
|
||||||
|
|
||||||
skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN);
|
skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN + NET_IP_ALIGN);
|
||||||
tmp_skb = bat_priv->vis.my_info->skb_packet;
|
tmp_skb = bat_priv->vis.my_info->skb_packet;
|
||||||
packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));
|
packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue