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:
Коммит
f1e0b5b4f1
|
@ -203,7 +203,8 @@ abled during run time. Following log_levels are defined:
|
|||
2 - Enable messages related to route added / changed / deleted
|
||||
4 - Enable messages related to translation table operations
|
||||
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
|
||||
/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
|
||||
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
|
||||
bool "B.A.T.M.A.N. debugging"
|
||||
depends on BATMAN_ADV
|
||||
|
|
|
@ -23,6 +23,7 @@ batman-adv-y += bat_iv_ogm.o
|
|||
batman-adv-y += bitarray.o
|
||||
batman-adv-$(CONFIG_BATMAN_ADV_BLA) += bridge_loop_avoidance.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_common.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)) &&
|
||||
(packet_len < BATADV_MAX_AGGREGATION_BYTES))
|
||||
skb_size = BATADV_MAX_AGGREGATION_BYTES + ETH_HLEN;
|
||||
skb_size = BATADV_MAX_AGGREGATION_BYTES;
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "vis.h"
|
||||
#include "icmp_socket.h"
|
||||
#include "bridge_loop_avoidance.h"
|
||||
#include "distributed-arp-table.h"
|
||||
|
||||
static struct dentry *batadv_debugfs;
|
||||
|
||||
|
@ -280,6 +281,19 @@ static int batadv_bla_backbone_table_open(struct inode *inode,
|
|||
|
||||
#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)
|
||||
{
|
||||
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,
|
||||
batadv_bla_backbone_table_open);
|
||||
#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,
|
||||
batadv_transtable_local_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
|
||||
&batadv_debuginfo_bla_claim_table,
|
||||
&batadv_debuginfo_bla_backbone_table,
|
||||
#endif
|
||||
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||
&batadv_debuginfo_dat_cache,
|
||||
#endif
|
||||
&batadv_debuginfo_transtable_local,
|
||||
&batadv_debuginfo_vis_data,
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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 "distributed-arp-table.h"
|
||||
#include "hard-interface.h"
|
||||
#include "soft-interface.h"
|
||||
#include "send.h"
|
||||
|
@ -109,6 +110,8 @@ static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv,
|
|||
if (!primary_if)
|
||||
goto out;
|
||||
|
||||
batadv_dat_init_own_addr(bat_priv, primary_if);
|
||||
|
||||
skb = bat_priv->vis.my_info->skb_packet;
|
||||
vis_packet = (struct batadv_vis_packet *)skb->data;
|
||||
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))
|
||||
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) {
|
||||
len = -ENOMEM;
|
||||
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);
|
||||
|
||||
if (copy_from_user(icmp_packet, buff, packet_len)) {
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "hard-interface.h"
|
||||
#include "gateway_client.h"
|
||||
#include "bridge_loop_avoidance.h"
|
||||
#include "distributed-arp-table.h"
|
||||
#include "vis.h"
|
||||
#include "hash.h"
|
||||
#include "bat_algo.h"
|
||||
|
@ -128,6 +129,10 @@ int batadv_mesh_init(struct net_device *soft_iface)
|
|||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = batadv_dat_init(bat_priv);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
atomic_set(&bat_priv->gw.reselect, 0);
|
||||
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_dat_free(bat_priv);
|
||||
|
||||
free_percpu(bat_priv->bat_counters);
|
||||
|
||||
atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
|
||||
|
@ -300,6 +307,8 @@ static void batadv_recv_handler_init(void)
|
|||
|
||||
/* batman 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 */
|
||||
batadv_rx_handler[BATADV_UNICAST] = batadv_recv_unicast_packet;
|
||||
/* fragmented unicast packet */
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in milliseconds */
|
||||
#define BATADV_TT_CLIENT_ROAM_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
|
||||
* (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 */
|
||||
|
||||
/* 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 */
|
||||
|
||||
/* 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_DAT_CANDIDATE_NOT_FOUND 0
|
||||
#define BATADV_DAT_CANDIDATE_ORIG 1
|
||||
|
||||
/* Debug Messages */
|
||||
#ifdef 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_TT: translation table 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
|
||||
*/
|
||||
enum batadv_dbg_level {
|
||||
|
@ -178,7 +188,8 @@ enum batadv_dbg_level {
|
|||
BATADV_DBG_ROUTES = BIT(1),
|
||||
BATADV_DBG_TT = BIT(2),
|
||||
BATADV_DBG_BLA = BIT(3),
|
||||
BATADV_DBG_ALL = 15,
|
||||
BATADV_DBG_DAT = BIT(4),
|
||||
BATADV_DBG_ALL = 31,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "distributed-arp-table.h"
|
||||
#include "originator.h"
|
||||
#include "hash.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->bat_priv = bat_priv;
|
||||
memcpy(orig_node->orig, addr, ETH_ALEN);
|
||||
batadv_dat_init_orig_node_addr(orig_node);
|
||||
orig_node->router = NULL;
|
||||
orig_node->tt_crc = 0;
|
||||
atomic_set(&orig_node->last_ttvn, 0);
|
||||
|
|
|
@ -23,14 +23,29 @@
|
|||
#define BATADV_ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */
|
||||
|
||||
enum batadv_packettype {
|
||||
BATADV_IV_OGM = 0x01,
|
||||
BATADV_ICMP = 0x02,
|
||||
BATADV_UNICAST = 0x03,
|
||||
BATADV_BCAST = 0x04,
|
||||
BATADV_VIS = 0x05,
|
||||
BATADV_UNICAST_FRAG = 0x06,
|
||||
BATADV_TT_QUERY = 0x07,
|
||||
BATADV_ROAM_ADV = 0x08,
|
||||
BATADV_IV_OGM = 0x01,
|
||||
BATADV_ICMP = 0x02,
|
||||
BATADV_UNICAST = 0x03,
|
||||
BATADV_BCAST = 0x04,
|
||||
BATADV_VIS = 0x05,
|
||||
BATADV_UNICAST_FRAG = 0x06,
|
||||
BATADV_TT_QUERY = 0x07,
|
||||
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 */
|
||||
|
@ -106,13 +121,16 @@ struct batadv_bla_claim_dst {
|
|||
uint8_t magic[3]; /* FF:43:05 */
|
||||
uint8_t type; /* bla_claimframe */
|
||||
__be16 group; /* group id */
|
||||
} __packed;
|
||||
};
|
||||
|
||||
struct batadv_header {
|
||||
uint8_t packet_type;
|
||||
uint8_t version; /* batman version field */
|
||||
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_header header;
|
||||
|
@ -137,7 +155,7 @@ struct batadv_icmp_packet {
|
|||
__be16 seqno;
|
||||
uint8_t uid;
|
||||
uint8_t reserved;
|
||||
} __packed;
|
||||
};
|
||||
|
||||
#define BATADV_RR_LEN 16
|
||||
|
||||
|
@ -153,13 +171,32 @@ struct batadv_icmp_packet_rr {
|
|||
uint8_t uid;
|
||||
uint8_t rr_cur;
|
||||
uint8_t rr[BATADV_RR_LEN][ETH_ALEN];
|
||||
} __packed;
|
||||
};
|
||||
|
||||
struct batadv_unicast_packet {
|
||||
struct batadv_header header;
|
||||
uint8_t ttvn; /* destination translation table version number */
|
||||
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_header header;
|
||||
|
@ -176,6 +213,9 @@ struct batadv_bcast_packet {
|
|||
uint8_t reserved;
|
||||
__be32 seqno;
|
||||
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;
|
||||
|
||||
struct batadv_vis_packet {
|
||||
|
@ -187,7 +227,7 @@ struct batadv_vis_packet {
|
|||
uint8_t vis_orig[ETH_ALEN]; /* originator reporting its neighbors */
|
||||
uint8_t target_orig[ETH_ALEN]; /* who should receive this packet */
|
||||
uint8_t sender_orig[ETH_ALEN]; /* who sent or forwarded this packet */
|
||||
} __packed;
|
||||
};
|
||||
|
||||
struct batadv_tt_query_packet {
|
||||
struct batadv_header header;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "vis.h"
|
||||
#include "unicast.h"
|
||||
#include "bridge_loop_avoidance.h"
|
||||
#include "distributed-arp-table.h"
|
||||
|
||||
static int batadv_route_unicast_packet(struct sk_buff *skb,
|
||||
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_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);
|
||||
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)
|
||||
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))
|
||||
return NET_RX_DROP;
|
||||
|
||||
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
||||
|
||||
/* packet for me */
|
||||
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,
|
||||
NULL);
|
||||
orig_node);
|
||||
|
||||
rx_success:
|
||||
if (orig_node)
|
||||
batadv_orig_node_free_ref(orig_node);
|
||||
|
||||
return NET_RX_SUCCESS;
|
||||
}
|
||||
|
@ -1034,8 +1063,17 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
|
|||
if (!new_skb)
|
||||
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,
|
||||
sizeof(struct batadv_unicast_packet), NULL);
|
||||
|
||||
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))
|
||||
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 */
|
||||
batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size,
|
||||
orig_node);
|
||||
|
||||
rx_success:
|
||||
ret = NET_RX_SUCCESS;
|
||||
goto out;
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "distributed-arp-table.h"
|
||||
#include "send.h"
|
||||
#include "routing.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)
|
||||
goto out;
|
||||
|
||||
if (batadv_dat_drop_broadcast_packet(bat_priv, forw_packet))
|
||||
goto out;
|
||||
|
||||
/* rebroadcast packet */
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "main.h"
|
||||
#include "soft-interface.h"
|
||||
#include "hard-interface.h"
|
||||
#include "distributed-arp-table.h"
|
||||
#include "routing.h"
|
||||
#include "send.h"
|
||||
#include "debugfs.h"
|
||||
|
@ -155,6 +156,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
|
|||
short vid __maybe_unused = -1;
|
||||
bool do_bcast = false;
|
||||
uint32_t seqno;
|
||||
unsigned long brd_delay = 1;
|
||||
|
||||
if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
|
||||
goto dropped;
|
||||
|
@ -224,6 +226,13 @@ static int batadv_interface_tx(struct sk_buff *skb,
|
|||
if (!primary_if)
|
||||
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)
|
||||
goto dropped;
|
||||
|
||||
|
@ -245,7 +254,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
|
|||
seqno = atomic_inc_return(&bat_priv->bcast_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
|
||||
* the original skb.
|
||||
|
@ -260,7 +269,12 @@ static int batadv_interface_tx(struct sk_buff *skb,
|
|||
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)
|
||||
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->bonding, 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->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE);
|
||||
atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
|
||||
|
@ -608,6 +625,13 @@ static const struct {
|
|||
{ "tt_response_rx" },
|
||||
{ "tt_roam_adv_tx" },
|
||||
{ "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,
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "main.h"
|
||||
#include "sysfs.h"
|
||||
#include "translation-table.h"
|
||||
#include "distributed-arp-table.h"
|
||||
#include "originator.h"
|
||||
#include "hard-interface.h"
|
||||
#include "gateway_common.h"
|
||||
|
@ -420,6 +421,9 @@ BATADV_ATTR_SIF_BOOL(bonding, S_IRUGO | S_IWUSR, NULL);
|
|||
#ifdef CONFIG_BATMAN_ADV_BLA
|
||||
BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL);
|
||||
#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(ap_isolation, S_IRUGO | S_IWUSR, NULL);
|
||||
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,
|
||||
#ifdef CONFIG_BATMAN_ADV_BLA
|
||||
&batadv_attr_bridge_loop_avoidance,
|
||||
#endif
|
||||
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||
&batadv_attr_distributed_arp_table,
|
||||
#endif
|
||||
&batadv_attr_fragmentation,
|
||||
&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);
|
||||
|
||||
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)
|
||||
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->ttvn = ttvn;
|
||||
|
||||
|
@ -1538,11 +1538,11 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
|
|||
if (!tt_req_node)
|
||||
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)
|
||||
goto out;
|
||||
|
||||
skb_reserve(skb, ETH_HLEN);
|
||||
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
|
||||
|
||||
tt_req_len = sizeof(*tt_request);
|
||||
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);
|
||||
|
||||
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)
|
||||
goto unlock;
|
||||
|
||||
skb_reserve(skb, ETH_HLEN);
|
||||
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
|
||||
packet_pos = skb_put(skb, len);
|
||||
tt_response = (struct batadv_tt_query_packet *)packet_pos;
|
||||
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);
|
||||
|
||||
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)
|
||||
goto unlock;
|
||||
|
||||
skb_reserve(skb, ETH_HLEN);
|
||||
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
|
||||
packet_pos = skb_put(skb, len);
|
||||
tt_response = (struct batadv_tt_query_packet *)packet_pos;
|
||||
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))
|
||||
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)
|
||||
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);
|
||||
|
||||
|
|
|
@ -28,6 +28,17 @@
|
|||
(ETH_HLEN + max(sizeof(struct batadv_unicast_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
|
||||
* @ogm_buff: buffer holding the OGM packet
|
||||
|
@ -73,6 +84,9 @@ struct batadv_orig_node {
|
|||
uint8_t orig[ETH_ALEN];
|
||||
uint8_t primary_addr[ETH_ALEN];
|
||||
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;
|
||||
uint8_t *bcast_own_sum;
|
||||
unsigned long last_seen;
|
||||
|
@ -172,6 +186,13 @@ enum batadv_counters {
|
|||
BATADV_CNT_TT_RESPONSE_RX,
|
||||
BATADV_CNT_TT_ROAM_ADV_TX,
|
||||
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,
|
||||
};
|
||||
|
||||
|
@ -238,6 +259,20 @@ struct batadv_priv_vis {
|
|||
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 {
|
||||
atomic_t mesh_state;
|
||||
struct net_device_stats stats;
|
||||
|
@ -247,6 +282,9 @@ struct batadv_priv {
|
|||
atomic_t fragmentation; /* boolean */
|
||||
atomic_t ap_isolation; /* 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 gw_mode; /* GW_MODE_* */
|
||||
atomic_t gw_sel_class; /* uint */
|
||||
|
@ -275,6 +313,9 @@ struct batadv_priv {
|
|||
struct batadv_priv_gw gw;
|
||||
struct batadv_priv_tt tt;
|
||||
struct batadv_priv_vis vis;
|
||||
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||
struct batadv_priv_dat dat;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct batadv_socket_client {
|
||||
|
@ -447,4 +488,36 @@ struct batadv_algo_ops {
|
|||
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_ */
|
||||
|
|
|
@ -291,7 +291,111 @@ out:
|
|||
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 batadv_unicast_packet *unicast_packet;
|
||||
|
@ -324,21 +428,23 @@ find_router:
|
|||
if (!neigh_node)
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
* for this client. The destination will receive this packet and will
|
||||
* 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;
|
||||
|
||||
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) {
|
||||
/* send frag skb decreases ttl */
|
||||
unicast_packet->header.ttl++;
|
||||
|
@ -360,7 +468,6 @@ find_router:
|
|||
|
||||
batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
|
||||
ret = 0;
|
||||
goto out;
|
||||
|
||||
out:
|
||||
if (neigh_node)
|
||||
|
|
|
@ -29,10 +29,44 @@ int batadv_frag_reassemble_skb(struct sk_buff *skb,
|
|||
struct batadv_priv *bat_priv,
|
||||
struct sk_buff **new_skb);
|
||||
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,
|
||||
struct batadv_hard_iface *hard_iface,
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -396,12 +396,12 @@ batadv_add_packet(struct batadv_priv *bat_priv,
|
|||
return NULL;
|
||||
|
||||
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) {
|
||||
kfree(info);
|
||||
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);
|
||||
|
||||
kref_init(&info->refcount);
|
||||
|
@ -873,12 +873,13 @@ int batadv_vis_init(struct batadv_priv *bat_priv)
|
|||
if (!bat_priv->vis.my_info)
|
||||
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);
|
||||
if (!bat_priv->vis.my_info->skb_packet)
|
||||
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;
|
||||
packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче